Openvpn

使用 iproute2 的 ss 時處於 UNCONN 狀態的 UDP 套接字

  • April 24, 2018

在執行 OpenVPN 客戶端的機器上編輯一些防火牆規則時,我試圖確定它的遠端埠,就像我通常做的那樣,使用ss.

# ss -anup | grep openvpn
UNCONN6528   0    0.0.0.0:52012        0.0.0.0:*     users:(("openvpn",pid=333,fd=3))

它空無一物。

從配置中,我可以看到客戶端必須10.0.0.5:389通過 UDP 連接。我驗證了這一點/proc

# cat /proc/net/nf_conntrack | grep udp | grep 389
ipv4     2 udp      17 175 src=10.0.7.8 dst=10.0.0.5 sport=52012 dport=389 src=10.0.0.5 dst=10.0.7.8 sport=389 dport=52012 [ASSURED] mark=0 zone=0 use=2

curl ipinfo.io在進行出站連接並驗證它是否正常工作並返回預期結果後,這兩個命令都快速連續執行。

我嘗試了與 netcat 的正常 UDP 連接(nc -l -u 12345在伺服器和nc -u 10.0.0.5 12345客戶端上)以查看客戶端ss上的輸出:

# ss -anup | grep nc
ESTAB      0      0      10.0.7.8:52051              10.0.0.5:12345               users:(("nc",pid=2002,fd=3))

為什麼ssOpenVPN 的輸出處於UNCONN狀態而不是預期ESTAB狀態,就像在簡單的 netcat 情況下一樣?


環境:

# uname -a
Linux tank 4.16.3-1-ARCH #1 SMP PREEMPT Thu Apr 19 09:17:56 UTC 2018 x86_64 GNU/Linux

# pacman -Qo /usr/bin/ss
/usr/bin/ss is owned by iproute2 4.16.0-1

TL;DR:您可以在連接模式下使用 UDP 套接字或保持未連接,這是一種實現選擇,取決於其他因素,取決於簡單性或可擴展性。這不會改變線路上數據包的內容或 conntrack 所做的任何選擇。

netcat使用bind(2)所選埠,僅使用一次recvfrom(2)MSG_PEEK甚至不使用數據,檢索源,然後使用connect(2)此源將套接字的狀態更改為ESTAB,現在可以繼續簡單的read(2)write(2)呼叫。

其他應用程序(例如:socatUDP-RECVFROM:7777,fork -而不是socat UDP-LISTEN:7777 -,顯然是 openvpn)只是從不connect(2)訪問源,因此保持在 UNCONN 狀態。他們只會使用recvfrom(2)並將使用sendto(2).

recv(2)和部分解釋了這種使用差異send(2)

send() 呼叫只能在套接字處於連接狀態時使用(以便知道預期的接收者)。send() 和 write(2) 之間的唯一區別是標誌的存在。使用零標誌參數,send() 等效於 write(2)。

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