虽然不打算交叉发布,但在将这个问题发送到 SecurityFocus 上的 OpenSSH 列表后,我注意到该列表的流量相当低(上一篇文章大约是 5 个月前)。话虽如此,我还是决定在这里重新发布,因为这个问题可能会吸引更多的关注(如果得到回答,将更有可能对其他人有用):
问题:我有一个从内部计算机到 DMZ 中主机的反向 SSH 隧道,该隧道设置为在系统启动时启动,如果隧道失败则重新启动。但是,当隧道中断时(例如,由于网络中断),由于 DMZ 主机上的端口正在使用中,因此无法重新建立隧道。从我阅读的 OpenSSH 邮件列表存档和其他地方来看,这似乎是因为端口处于 TIME_WAIT 状态。这很好:我可以在设置隧道的脚本中放入 sleep 语句。但是,这导致两个问题:
1) 知道如何确定特定 Linux (或其他) 系统上定义的 TIME_WAIT 间隔吗?虽然我可以只睡 5 分钟就没事了,但最好尽可能节省时间。 2) 虽然 OpenSSH 似乎不支持“ClearAllForwardings”选项,但是否有类似的功能,即经过身份验证的连接可以自动拆除并重新创建它之前建立的现有连接? 长时间的睡眠可能“足够好”,但如果可能的话,我更愿意以更有效的方式处理 TIME_WAIT 条件。 我感谢任何指导或建议!答案1
我认为你可以尝试各种 SSH 设置,例如 TCPKeepAlive、ServerAliveInterval、ServerAliveCountMax 等,以设置如果连接断开,它将终止所有内容。我有一个类似的设置,并且我对两端的 SSHD 和 SSH 都进行了大量修改,以符合我的要求。然后我有一个每 5 分钟运行一次的 cron 作业,如果需要,它会重新启动隧道。
#!/bin/bash
if ps aux | grep "ssh -fnNTx" | grep -v "grep"
then
echo "Already Running"
else
echo "Starting now"
ssh -fnNTx -L 1514:127.0.0.1:514 [email protected]
fi
到目前为止,这个解决方案对我来说效果很好。您还可以设置某种类型的 Nagios 检查或其他脚本来查看隧道是否打开,如果没有打开,则终止该 pid 以便重新启动。
编辑:
上一篇文章讨论了很多有关 TIME_WAIT 问题。如何强制关闭处于TIME_WAIT状态的套接字?
答案2
SSHD 应设置 SO_REUSEADDR,允许新实例绑定,即使前一个实例仍有处于 TIME_WAIT 状态的连接。要么你的 SSHD 有问题,要么你的某些配置设置会阻止此行为(例如,如果你已禁用 X11UseLocalHost)。