我有一个 SSH 连接流,client -> proxy server -> server
它是通过 ruby 中的 Net::SSH::Proxy 建立的(这看起来是 SSH 问题,而不是 ruby 问题)。连接建立后,后续命令将通过隧道发送,直到连接关闭。这在大约 99% 的情况下工作正常,但是,偶尔隧道会无限期地保持打开状态,并且似乎与存在活动连接时服务器的重新启动相关。如果我尝试手动重现该场景(在存在活动连接时重新启动服务器),我将无法执行此操作,而是 ssh 连接会按预期关闭。
当隧道陷入这种不确定的开放状态时,来自 的连接client -> proxy server
仍然建立,并且proxy server
认为到 的连接server
也仍然建立。但是,那server
才不是显示已建立的连接,proxy server
这是有意义的,因为它已经重新启动。
从每个主机收集的数据:
客户端(使用 OpenSSH):
ps -o cmd= -p 8029
ssh -o strictHostKeyChecking=no [email protected] -p 2022 -W [10.100.202.65]:22
TZ=UTC0 ps -o lstart= -p 8029
Mon Jul 8 21:17:09 2019
代理服务器(使用 OpenSSH):
sudo netstat -tnpa | grep 'ESTABLISHED.*sshd' | grep 10.100.202.65
tcp 0 0 10.100.201.246:47414 10.100.202.65:22 ESTABLISHED 29135/sshd: user1
服务器(使用 Dropbear)
netstat -tnpa | grep 'ESTABLISHED.*dropbear' | grep 10.100.202.65
<...no results...>
date; uptime
Tue Jul 9 18:56:49 UTC 2019
18:56:49 up 21:37, load average: 0.50, 0.56, 0.61
^ 请注意,服务器date - uptime
=而客户端命令自确认服务器在建立连接后重新启动以来Mon Jul 8 21:19 UTC
一直在运行。Mon Jul 8 21:17 UTC
我的第一个想法是代理服务器的 sshd 可能已TCPKeepAlive
禁用,因此它无法检测到服务器连接断开,但我在 sshd_config 中确认它已启用:
TCPKeepAlive yes
我还在代理服务器上进行了 tcpdump,但在目标服务器上看到的唯一流量是偶尔的 ARP:
sudo tcpdump -ni eth1 host 10.100.202.65
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
11:14:45.647479 ARP, Request who-has 10.100.0.2 (ff:ff:ff:ff:ff:ff) tell 10.100.202.65, length 46
11:14:45.660208 ARP, Request who-has 10.100.202.65 (ff:ff:ff:ff:ff:ff) tell 0.0.0.0, length 46
11:15:46.762554 ARP, Request who-has 10.100.0.2 (ff:ff:ff:ff:ff:ff) tell 10.100.202.65, length 46
11:15:46.782608 ARP, Request who-has 10.100.202.65 (ff:ff:ff:ff:ff:ff) tell 0.0.0.0, length 46
11:16:47.956901 ARP, Request who-has 10.100.0.2 (ff:ff:ff:ff:ff:ff) tell 10.100.202.65, length 46
11:16:47.974012 ARP, Request who-has 10.100.202.65 (ff:ff:ff:ff:ff:ff) tell 0.0.0.0, length 46
问题:是什么让 ssh 连接保持建立?是否有任何其他 ssh 选项(在 sshd 配置或命令行参数中)可用于防止这种情况?
编辑:我相信我发现了这个问题。客户端ssh_config
包含以下 ServerAlive* 选项:
ServerAliveCountMax 3
ServerAliveInterval 60
这将在 3 分钟后终止空闲会话。此路径中的proxy server
也充当客户端,连接到server
。没有proxy server
设置这些选项。我现在已将它们添加到ssh_config
上proxy server
,我将进行另一次编辑以报告这是否成功。