BSD nc(netcat)不会在 EOF 上终止

BSD nc(netcat)不会在 EOF 上终止

主持人A:

tar cf -  stuff | dd | nc  -N -l 12987

主持人B:

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并关闭了该死的套接字,而主机 Bnc应该已经看到 TCP 连接终止并且应该已经关闭stdoutstdin/ )。ddtar

我如何告诉在主机 B 上nc关闭stdout/终止并在主机 A 上终止

nc漏洞?

-D(调试)什么也不做。nc甚至无法说出它的版本号......

两位主持人都是FreeBSD 10.3-RELEASE-p4,仅限 IPv4。

答案1

我也对 netcat 的行为感到困惑,所以我深入研究了代码。以下是整个故事:

nc 服务器 ( nc -l) 和客户端仅在相互连接关闭后退出。也就是说,如果每一方都发送了一个数据包给对方。

服务器总是FIN在收到FIN客户端发来的数据包后才发送数据包。(除非服务器已经发送了数据FIN包。)

客户端可以以下列方式发送 FIN 数据包:

  • 在 stdin之后EOF,带参数运行时-N
  • 在标准输入之后EOF,当服务器已经发送 FIN 数据包时

使用选项-d stdin 将被忽略,并且nc行为就像EOF在 stdin 上遇到一样。

选项-N总是暗示在标准输入上FIN遇到后发送EOF

交换数据后退出nc进程的方法:

  1. 乔治的回答

     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

    连接关闭,客户端和服务器均退出。

答案2

nc建立一个双向连接。即,它stdin从主机 B 向主机 A 发送消息,同时从 A 向 B 发送所需的消息。

在主机 B 上使用-d以忽略stdin。在主机 A 上仍然需要在 EOF 上-N关闭连接。TCP


总之

主持人A:

tar cf -  stuff | dd | nc  -N -l 12987

主持人B:

nc -d a.example.com 12987 | dd | tar tf - 

相关内容