SSH远程端口转发失败

Jus*_*kva 32 ssh port-forwarding ssh-tunnel

跟进:看起来与每个服务器运行几个月相吻合的一系列快速断开连接可能是巧合,只是用来揭示实际问题。它无法重新连接的原因几乎可以肯定是由于 AliveInterval 值(kasperd 的回答)。使用 ExitOnForwardFailure 选项应该允许在重新连接之前正确发生超时,这应该可以解决大多数情况下的问题。MadHatter 的建议(kill 脚本)可能是确保隧道可以重新连接的最佳方法,即使其他一切都失败了。

我在防火墙后面有一个服务器 (A),它在几个端口上启动一个反向隧道到一个小的 DigitalOcean VPS (B),所以我可以通过 B 的 IP 地址连接到 A。这条隧道已经持续工作了大约 3 个月,但在过去的 24 小时内突然发生了四次故障。不久前,另一家 VPS 提供商也发生了同样的事情——几个月的完美运营,然后突然出现多次快速故障。

我在机器 A 上有一个脚本,它自动执行隧道命令(ssh -R *:X:localhost:X address_of_B对于每个端口 X),但是当它执行时,它说Warning: remote port forwarding failed for listen port X.

进入/var/log/secure服务器上的 sshd显示以下错误:

bind: Address already in use
error: bind: Address already in use
error: channel_setup_fwd_listener: cannot listen to port: X
Run Code Online (Sandbox Code Playgroud)

解决需要重启VPS。在那之前,所有重新连接的尝试都会给出“远程端口转发失败”的消息,并且不会起作用。现在到了隧道只持续大约 4 小时才停止的地步。

VPS 上没有任何变化,它是一台一次性使用的单用户机器,仅用作反向隧道端点。它在 CentOS 6.5 上运行 OpenSSH_5.3p1。当连接丢失时,sshd 似乎没有关闭其末端的端口。我无法解释为什么,或者为什么在几个月近乎完美的操作之后会突然发生。

为了澄清,我首先需要弄清楚为什么 sshd 在隧道失败后拒绝侦听端口,这似乎是由 sshd 保持端口打开并且从不关闭它们造成的。这似乎是主要问题。我只是不确定是什么导致它按照我的预期运行数月后会出现这种行为(即立即关闭端口并允许脚本重新连接)。

kas*_*erd 34

我同意 MadHatter 的观点,它很可能是来自失效的 ssh 连接的端口转发。即使您当前的问题被证明是其他问题,您迟早会遇到此类失效的 ssh 连接。

这种失效的连接可以通过三种方式发生:

  • 两个端点之一重新启动,而连接的另一端完全空闲。
  • 两个端点之一关闭了连接,但在连接关闭的时候,连接出现了临时中断。连接关闭后中断持续了几分钟,因此另一端从未了解关闭的连接。
  • 该连接在 ssh 连接的两个端点上仍然完全正常工作,但有人在它们之间放置了一个有状态设备,由于空闲而导致连接超时。这个有状态设备可以是 NAT 或防火墙,您已经提到的防火墙是主要嫌疑人。

弄清楚以上三个中的哪个发生了并不是很重要,因为有一种方法可以解决所有三个问题。那就是使用keepalive消息。

您应该查看ClientAliveInterval关键字 forsshd_configServerAliveInterval间隔ssh_configor ~/.ssh/config

ssh在循环中运行命令可以正常工作。在循环中插入睡眠也是一个好主意,这样当由于某种原因连接失败时,您最终不会淹没服务器。

如果客户端在服务器上的连接终止之前重新连接,您可能会遇到新的 ssh 连接有效但没有端口转发的情况。为了避免这种情况,您需要ExitOnForwardFailure在客户端使用关键字。

  • 没问题,实际上是`-o ExitOnForwardFailure=yes`(注意等号)。因此,如果有人遇到此问题,请不要从我之前的评论中复制和粘贴,这是行不通的。:P (4认同)
  • 说到警告消息不会杀死 SSH,这让我开始思考……并查看了联机帮助页。事实证明 `-o ExitOnForwardFailure yes` 正是我所需要的。所以我需要弄清楚的事情就少了一件。想一想,我打算编写一个 Python 脚本来解析这些警告消息。这要简单得多。:D (2认同)

Ste*_*uan 5

对我来说,当ssh隧道断开连接时,连接需要一段时间才能重置,因此该ssh过程继续阻塞,使我没有活动隧道,我不知道为什么。一种变通的解决方案是在不等待旧连接重置的情况下将其ssh置于后台-f并生成新连接。该-o ExitOnForwardFailure=yes可用于LIMT新进程的数量。在-o ServerAliveInterval=60改善当前连接的可靠性。

您可以ssh频繁地重复该命令,例如,在cron脚本中的 a或循环中,例如,在以下内容中,我们ssh每 3 分钟运行一次该命令:

while (1)
do
    ssh -f user@hostname -Rport:host:hostport -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=60
    sleep 180
done
Run Code Online (Sandbox Code Playgroud)