Ping

-m 選項在 ping 命令中不起作用

  • June 23, 2017

我正在學習 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選項標記數據包?

**簡短的回答:**你不能用普通使用者做。

**長答案:**為了能夠標記數據包,您需要是 root 使用者,或者至少是具有以下SO_MARK能力的使用者(需要設置為 root):

SO_MARK 在socket(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 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.

正如在超級使用者問題中所解釋的那樣,此功能在探測多鏈路/多路由網路環境時可能很有用,您需要強制 ICMP 數據包通過一個特定的“流”。

實際例子。主機1:

$ ping -m 10 <host>

INPUT主機 2. 更改to的預設策略DROP並僅接受來自主機 1 上標記為 10 的特定路由的源 ip 的數據包:

# iptables -P INPUT DROP
# iptables -A INPUT -s <IP_SOURCE_MARK_10> -p icmp -j ACCEPT

這已經在這裡解釋過了。同樣,它將更好地用於路由決策調試(如果您在 2 個主機之間有多個路徑),因為tcpdump -nevvv -i <interface> src host <source_host>僅探測“icmp 數據包到達”就綽綽有餘了。

引用自:https://unix.stackexchange.com/questions/281015