-m 选项在 ping 命令中不起作用

7 ping

我正在学习 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
Run Code Online (Sandbox Code Playgroud)

那么,为什么它无法标记?如何使用该-m选项标记数据包?

小智 17

简短的回答:你不能用普通用户做。

长答案:为了能够标记数据包,您需要是root用户,或者至少是具有SO_MARK能力的用户(需要设置为root):

套接字 (7)处的 SO_MARK :

   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.
Run Code Online (Sandbox Code Playgroud)

来自 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
Run Code Online (Sandbox Code Playgroud)

要了解有关功能的更多信息: man capabilities(7)和 capabilities(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.
Run Code Online (Sandbox Code Playgroud)

正如在超级用户问题中所解释的那样,在探测多链路/多路由网络环境时,此功能可能很有用,您需要强制 ICMP 数据包通过一个特定的“流”。

实际例子。主机 1:

$ ping -m 10 <host>
Run Code Online (Sandbox Code Playgroud)

主机 2. 更改默认策略INPUTtoDROP并仅接受来自主机 1 上标记为 10 的特定路由的源 ip 的数据包:

# iptables -P INPUT DROP
# iptables -A INPUT -s <IP_SOURCE_MARK_10> -p icmp -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

这已经在这里解释。同样,它将更好地用于路由决策调试(如果您在 2 台主机之间有多个路径),因为 atcpdump -nevvv -i <interface> src host <source_host>足以探测“icmp 数据包到达”。