使用 iproute2 的 ss 時處於 UNCONN 狀態的 UDP 套接字
在執行 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))
為什麼
ss
OpenVPN 的輸出處於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)
呼叫。其他應用程序(例如:socat
UDP-RECVFROM:7777,fork -
而不是socat UDP-LISTEN:7777 -
,顯然是 openvpn)只是從不connect(2)
訪問源,因此保持在 UNCONN 狀態。他們只會使用recvfrom(2)
並將使用sendto(2)
.send() 呼叫只能在套接字處於連接狀態時使用(以便知道預期的接收者)。send() 和 write(2) 之間的唯一區別是標誌的存在。使用零標誌參數,send() 等效於 write(2)。