我正在尝试调试端口转发的问题,即“为什么我不能限制要连接的端口?” 但这不是这里的问题。这里的问题是“为什么 nc 不会通过转发端口发送任何数据?”
在本地机器上简单开始:
- 我已经在 Windows 8.1 下安装了 OpenSSH。简单的。
将这些行添加到 sshd_config 文件的开头:
许可证TTY no 最大会话数 1
我使用命令启动 sshd
net start sshd
。- 我启动了一个 cygwin bash shell(也尝试过使用 git-bash)并输入命令:
ssh -N -L 1234:localhost:5678 adrian@localhost
,然后输入密码。 - 我启动另一个 cygwin bash shell 并输入命令
nc -l 5678
。 - 我启动另一个 cygwin bash shell 并输入命令
nc -v localhost 1234
。
在这一点上,我希望看到连接成功,现在能够在第二个 cygwin bash shell 中输入内容并让它出现在第一个。但是,我得到的是连接成功的消息,然后它让我回到 bash 提示符。为什么?
例子
然后将我引导到命令行的成功消息是:
$ nc -v localhost 1234 Connection to localhost 1234 port [tcp/*] succeeded! $
如果我没有
nc
运行侦听器并尝试通过转发端口进行连接,也会发生这种情况。我可以直接连接到端口,然后收到一条错误消息,然后是一条成功消息,最后我可以输入一个 shell,它会显示在另一个 shell 中:
$ nc -v localhost 5678 nc: connect to localhost port 5678 (tcp) failed: Connection refused Connection to localhost 5678 port [tcp/*] succeeded!
如果我要连接到未转发的端口并且无论 sshd 是否正在运行,这都是一致的。
如果没有端口转发,如果我没有
nc
运行侦听器并尝试通过先前转发的端口进行连接,则会失败:$ nc -v localhost 1234 nc: connect to localhost port 1234 (tcp) failed: Connection refused nc: connect to localhost port 1234 (tcp) failed: Connection refused
编辑
因此,根据答案,似乎故障在于nc -l 5678
将连接到传入的 IP4 数据包。 nc localhost 5678
将首先尝试发送 IP6 数据包,如果失败,则使用 IP4 数据包重试。 通过它接收到的任何数据包类型与之sshd
通信。由于那是 IP4 数据包,它会失败,关闭隧道,然后关闭隧道,然后关闭发送方,然后再尝试发送 IP6 数据包。nc -l 5678
ssh
ssh
nc
要解决此问题,请使用 command 让侦听器仅接受 IP6 数据包nc -6l 5678
,然后一切正常。
SSH“端口转发”与路由器执行的有点不同。在路由器单独转发每个 IP 数据包且未更改的情况下,SSH 处理诸如“连接打开”之类的通用信号,并且根本不转发实际的 TCP 操作。
也就是说,SSH 充当两个完全独立的 TCP 连接(“nc→ssh”和“sshd→nc-l”)之间的管道,不像路由器从端到端承载相同的连接。
因此,对于 SSH,它实际上是您的本地系统接受来自 的 TCP 握手,而 SSH 客户端只有在它被接受后
nc
才会意识到这一点。然后 SSH 客户端向服务器发送一个“隧道打开”请求,服务器尝试与最终目的地建立全新的 TCP 连接。如果不成功,它会向您的客户端发送“隧道打开失败”的回复。此时,您的本地系统以
nc
通常的方式通知错误为时已晚——记住它已经接受了连接;它可以立即关闭它,但它不能及时返回并完全拒绝它。(您看到的“拒绝”消息与
localhost
转换为 IPv4 127.0.0.1 和 IPv6 ::1 相关 - nc 尝试同时访问两者,但 ssh 客户端被告知只收听一个。)不。有点像那样,但是——重复一遍——实际的 IP 数据包根本不会通过隧道。有两个独立的连接(如果算上实际的 SSH 会话,可能是三个),本地
nc
客户端尝试的 IP 版本可能nc -l
与远程侦听器收到的 IP 版本不同。更具体地说,这是两个客户端-服务器对:
本地系统:
nc localhost 5678
作为客户端⇆ssh -L ...
作为监听器;远程系统:
sshd
作为客户端⇆nc -l 5678
作为监听器。出现第一个连接拒绝是因为ssh -L不期望nc localhost尝试的 IP 版本。此尝试不会到达远程系统(sshd和nc -l都不知道)。