BSD nc (netcat) 不會在 EOF 上終止
主持人甲:
tar cf - stuff | dd | nc -N -l 12987
主持人乙:
nc a.example.com 12987 | dd | tar tf -
在主機 A 上完成
dd
後列印其摘要tar
。因此很明顯, tar 關閉了管道/文件 ->EOF
。165040+0 記錄 165040+0 記錄輸出 84500480 字節在 25.464802 秒內傳輸(3318325 字節/秒)
兩個主機上都
nc
愉快地坐在那里而不退出。nc(1)
:-N shutdown(2) the network socket after EOF on the input. Some servers require this to finish their work.
因此,在主機 A 上
nc
應該已經看到EOF
,關閉了該死的套接字,在主機 B 上nc
應該已經看到 TCP 連接終止並且應該已經關閉stdout
(stdin
的dd
/tar
)。如何告訴在主機 B 上
nc
關閉stdout
/終止並在主機 A 上終止。
nc
漏洞?
-D
(調試)什麼都不做。nc
連版本號都說不出來……唉兩台主機都是FreeBSD 10.3-RELEASE-p4,僅限 IPv4。
我也對 netcat 的行為感到困惑,所以我深入研究了程式碼。這是整個故事:
nc 伺服器 (
nc -l
) 和客戶端僅在相互連接關閉後退出。也就是說,如果雙方都向對方發送了一個FIN數據包。伺服器總是在收到來自客戶端
FIN
的數據包後發送一個數據FIN
包。(除非伺服器已經發送了一個FIN
數據包。)客戶端發送一個 FIN 數據包:
- 在標準輸入之後
EOF
,當使用參數執行時-N
- 在標準輸入之後
EOF
,當伺服器已經發送了一個 FIN 數據包時使用選項
-d
stdin 將被忽略,nc
其行為就像EOF
在 stdin 上遇到一樣。選項
-N
總是意味著FIN
在遇到標準輸入後發送EOF
。交換數據後退出nc程序的方法:
- 格奧爾格的回答
server$ echo hello | nc -l -N 2000 client$ nc -d localhost 2000
發送後
hello
,伺服器EOF
在 stdin 上遇到發送,FIN
因為-N
.客戶端接收到消息,並且由於在標準輸入上
-d
看到EOF
並發送FIN
,因為伺服器已經發送FIN
。連接關閉,客戶端和伺服器都退出。 2. 客戶端發起關閉
server$ echo hello | nc -l 2000 client$ nc -dN localhost 2000
伺服器在標準輸入後保持連接打開
EOF
。客戶端在 stdin 上看到
EOF
並發送FIN
,因為-N
.伺服器
FIN
收到客戶端的FIN
.連接關閉,客戶端和伺服器都退出。