我正在学习 Linuxping
命令及其选项,并阅读了-m
用于标记传出数据包的选项。接收时,我们可以先过滤标记的数据包结果。
我正在尝试为数据包设置标记,但收到一条警告消息:
$ ping -m 10 server
PING server (192.168.2.2) 56(84) bytes of data.
Warning: Failed to set mark 10
64 bytes from server (192.168.2.2): icmp_req=1 ttl=64 time=0.182 ms
64 bytes from server (192.168.2.2): icmp_req=2 ttl=64 time=0.201 ms
那么,为什么标记失败呢?如何使用该-m
选项标记数据包?
答案1
简短回答:你不能与普通用户一起做。
长答案:为了能够标记数据包,您需要是 root 用户,或者至少是具有以下SO_MARK
功能的用户(需要设置为 root):
SO_MARK 在插座(7):
SO_MARK (since Linux 2.6.25) Set the mark for each packet sent through this socket (similar to the netfilter MARK target but socket-based). Changing the mark can be used for mark-based routing without netfilter or for packet filtering. Setting this option requires the CAP_NET_ADMIN capability.
这一段代码来自 iputils 的 ping_common.c 证实了这一理论:
#ifdef SO_MARK
if (options & F_MARK) {
int ret;
enable_capability_admin();
ret = setsockopt(sock->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
disable_capability_admin();
if (ret == -1) {
/* we probably dont wanna exit since old kernels
* dont support mark ..
*/
fprintf(stderr, "Warning: Failed to set mark %d\n", mark);
}
}
#endif
要了解有关功能的更多信息:man能力(7)和能力(7)概述。
如果您想进一步了解系统所有其他二进制文件的功能,这是探索它们的好方法。由于涉及内核编译,不太适合生产环境。
ICMP 标记的用途:
正如它所描述的手册页:
-m mark
use mark to tag the packets going out. This is useful for variety of reasons
within the kernel such as using policy routing to select specific outbound processing.
正如上所解释的超级用户问题是,在探测多链路/多路由网络环境时,您需要强制 ICMP 数据包通过一个特定的“流”,此功能可能很有用。
实际例子。主机1:
$ ping -m 10 <host>
主机 2. 更改默认策略INPUT
toDROP
并仅接受来自主机 1 上标记为 10 的特定路由的源 ip 的数据包:
# iptables -P INPUT DROP
# iptables -A INPUT -s <IP_SOURCE_MARK_10> -p icmp -j ACCEPT
这已经解释过了这里。同样,它更适合用于路由决策调试(如果两台主机之间有不止一条路径),因为 atcpdump -nevvv -i <interface> src host <source_host>
足以探测“icmp 数据包到达”。