我遇到了一系列问题,所有这些问题加在一起就形成了一个棘手的问题。
背景:我有一台位于防火墙后面的服务器,使用外部 VPS 进行反向隧道传输(我们将该服务器称为“服务器”,将其连接到的 VPS 称为“隧道机”)。SSH 隧道会随机中断。我在服务器上有一个脚本可以重新连接,但不幸的是,隧道机(运行 CentOS 6.5)上的 SSHD 守护程序通常不会关闭。它只是保持打开状态,这意味着反向隧道无法绑定到端口。
我在隧道机上将 ClientAliveInterval 设置为 15,将 ClientAliveCountMax 设置为 2,以便在超过 30 秒时强制服务器停止监听。有时它有效……有时则无效。在许多情况下,它会一直待在那里监听不再存在的端口,而且由于它不会放弃端口,因此 ssh 无法绑定到它们。
我还遇到了两个次要问题。当我不可避免地Write failed: Broken pipe
在服务器上输入 ssh 命令时,它不会尝试重新连接。SSH 只是坐在那里等待输入。同样,Connection to xxx.xxx.xxx.xxx timed out while waiting to write
有时也会出现该消息。在客户端上,我将 ServerAliveInterval 设置为 15,将 ServerAliveCountMax 设置为 4,因此它会等待 1 分钟才尝试重新连接。但这还不够,因为此消息可能会导致 SSH 无限期挂起。对于远程端口转发失败警告,我使用这种方法-o ExitOnForwardFailure=yes
确保 SSH 在收到其中一个警告时会死机,从而确保我的脚本知道失败并可以重试。但对于Write failed: Broken pipe
其他一些,我找不到任何这样的选项,每次出现其中一个错误时,SSH 都不会死机,也不会重新启动。
首先,为什么当连接丢失时 sshd 进程不会终止?其次,如何确保每次断开连接或警告都会导致 SSH 终止,以确保它可以尝试重新连接?
另外,是的,在任何人提到它之前:我已经尝试过 autossh,它也存在完全相同的缺点。