简短的介绍
多年来我一直在 SSH 连接上看到奇怪的行为,但直到今天才想到提出问题。我尝试对此进行了很多搜索,但找不到任何原因。
环境
- 基本上,我在不同区域(如爱尔兰、孟买等)运行着各种 AWS EC2 实例。
- 我有一台Mac。
- 我位于印度(以防有人出于某种原因感到震惊)。
问题陈述1
当我的 Mac 通过 4G 网络连接到个人热点(从三星设备或 iPhone)时,如果我不进行 SSH 会话(基本上, SSH 连接非常理想)。所以我必须一直按箭头键才能让它保持活力。
问题陈述2(这不是问题)
但当我的Mac连接到Wifi宽带连接时,这个问题就不会出现。即使我将 Mac 从睡眠状态中唤醒(打开盖子),我的 SSH 连接仍会保持连接数小时。
今天再次根据我的谷歌搜索,我发现了各种文章,这些文章提供了使用诸如TCPKeepAlive
或 之类的选项的解决方案ServerAliveInterval
:
- sshd_config 中的 `ServerAliveInterval` 和 `ClientAliveInterval` 选项到底有什么作用?
- tcp-keepalive 在 ssh 中如何工作?
- https://raspberrypi.stackexchange.com/questions/8311/ssh-connection-timeout-when-connecting
- https://patrickmn.com/aside/how-to-keep-alive-ssh-sessions/
但我找不到任何说明这个问题的帖子。你们中有人对这种行为有任何想法吗?我很乐意向您提供有关我的 4G 热点连接的任何可能的详细信息。
答案1
我猜测是系统跟踪(并忘记)连接状态导致了这种情况。当使用 NAT 时(不使用 IPv6 时经常出现这种情况),执行 NAT 的系统通常需要一个内存来记住向何处发回回复。对于您的 Wifi 宽带,执行 NAT 的系统可能有更长的内存来记住活动连接(例如,Linux网络过滤器的连线默认情况下,它会记住 TCP 连接 5 天,而它会记住 UDP 流 2 或 3 分钟)。在 4G 路径上执行 NAT 的等效系统的内存可能较短,略小于 300 万。
要解决此问题,正如您在问题中找到并链接的那样,您可以设置特定的 ssh 参数ServerAliveInterval
当没有活动时,会定期发送空数据(如 SSH 协议),类似于TCP 保活。这将使执行 NAT 的系统始终将连接视为活动连接,并且不会忘记它。所以在你的~/.ssh/config
文件中你可以添加:
ServerAliveInterval 115
115 的值选择略小于 2mn 以保持保守:该值低于路径中不可见 NAT 设备上活动连接的估计跟踪持续时间,但也不会太低(见下文)。因此,更糟糕的是,当跟踪状态距离即将被删除还有 5 秒时,它会回到假设的 120 秒寿命。
缺点是(无论如何在您的 Wifi 宽带接入上)如果您失去连接一段时间然后恢复它,这可能会让客户端认为远程服务器已关闭并且它会关闭连接。您还可以调整ServerAliveCountMax
为此,但无论如何,如果默认值为 3,则需要 3*115=345 秒的连接丢失,超过 500 万,才有机会出现此问题。
服务器端有一个等效的ClientAliveInterval
sshd_config
您可以出于相同的目的在其文件中进行设置。这样做的另一个好处是,当客户端无论如何都失去连接时,不会在一段时间内保留 Ghost ssh 客户端连接,这些连接被视为仍然连接。