编辑

编辑

我正在尝试调试端口转发的一个问题,即“为什么我不能限制要连接的端口?”但这不是这里的问题。这里的问题是“为什么 nc 不会通过转发端口发送任何数据?”

在本地机器上简单开始:

  1. 我已经在 Windows 8.1 下安装了 OpenSSH。很简单。
  2. 将这些行添加到 sshd_config 文件的开头:

    许可证TTY 号
    最大会话数 1
    
  3. 我使用命令启动 sshd net start sshd

  4. 我启动了一个 cygwin bash shell(也尝试使用 git-bash)并输入命令:ssh -N -L 1234:localhost:5678 adrian@localhost,然后输入密码。
  5. 我启动另一个 cygwin bash shell 并输入命令nc -l 5678
  6. 我启动另一个 cygwin bash shell 并输入命令nc -v localhost 1234

此时,我希望看到连接成功,现在可以在第二个 cygwin bash shell 中输入内容,并让其显示在第一个 cygwin bash shell 中。但是,我收到的是连接成功的消息,然后它又回到了 bash 提示符。为什么?

例子

  1. 然后它将我引导到命令行的成功消息是:

    $ nc -v  localhost 1234
    Connection to localhost 1234 port [tcp/*] succeeded!
    
    $
    

    如果我没有nc运行侦听器并尝试通过转发端口进行连接,也会发生这种情况。

  2. 我可以直接连接到端口并收到一条错误消息,然后收到一条成功消息,最后我可以在一个 shell 中输入,它会显示在另一个 shell 中:

    $ nc -v  localhost 5678
    nc: connect to localhost port 5678 (tcp) failed: Connection refused
    Connection to localhost 5678 port [tcp/*] succeeded!
    

    如果我要连接未转发的端口,并且无论 sshd 是否正在运行,这都是一致的。

  3. 如果没有端口转发,如果我没有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 5678sshsshnc

要修复它,请使用命令让监听器仅接受 IP6 数据包nc -6l 5678,然后一切就可以正常工作。

答案1

SSH“端口转发”与路由器执行的端口转发略有不同。路由器会单独且不加改变地转发每个 IP 数据包,而 SSH 会处理“连接已打开”等通用信号,并且根本不转发实际的 TCP 操作。

也就是说,SSH 充当两个完全独立的 TCP 连接(“nc→ssh”和“sshd→nc-l”)之间的管道,而不像路由器那样从一端到另一端承载相同的连接。

因此,使用 SSH 实际上是您的本地系统它接受来自的 TCP 握手nc,而 SSH 客户端只知道这一点它已经被接受了。然后 SSH 客户端向服务器发送“隧道打开”请求,服务器尝试建立到最终目的地的全新 TCP 连接。如果没有成功,它会向客户端发送“隧道打开失败”的回复。

此时,您的本地系统nc以通常的方式通知错误已经太晚了——请记住它已经接受了连接;它可以立即关闭它,但无法及时返回并完全拒绝它。

(您收到的“拒绝”消息localhostsee 与转换为 IPv4 127.0.0.1 和 IPv6 ::1相关– nc 尝试访问两者,但 ssh 客户端被告知只监听其中一个。)

因此,根据答案,失败的原因似乎是 nc -l 5678 将连接到传入的 IP4 数据包。nc localhost 5678 将首先尝试发送 IP6 数据包,如果失败,则再次尝试发送 IP4 数据包。sshd 通过从 ssh 收到的任何数据包类型与 nc -l 5678 进行通信。由于这是 IP4 数据包,因此它会失败,关闭隧道,然后关闭 ssh,然后关闭 nc 发送方,然后再重试发送 IP6 数据包。

不。有点像,但是——再说一遍——实际的 IP 数据包根本就不会穿过隧道。有两个独立的连接(如果算上实际的 SSH 会话,可能是三个)和本地nc客户端尝试的 IP 版本与远程侦听器收到的 IP 版本不同nc -l

更具体地说,这是两个客户端-服务器对:

  1. 本地系统:nc localhost 5678作为客户端⇆ssh -L ...作为监听器;

  2. 远程系统:sshd作为客户端⇆nc -l 5678作为监听器。

第一次出现连接拒绝是因为ssh-L 密码不期望 IP 版本nc 本地主机正在尝试。此尝试未到达远程系统(既未sshd也不数控知道这一点)。

相关内容