SSH连接意外断开,相信不少运维和开发人员都曾遭遇过。屏幕突然黑掉,工作进度瞬间丢失,实在令人烦恼。但您可能并不了解,在绝大多数场景下,这并非网络质量不佳所致,而是防火墙或NAT网关在“背后捣乱”——它们会在连接空闲一段时间后,主动清理掉TCP状态表。值得庆幸的是,只要正确配置一对参数,超过90%的这类“断连”问题都能轻松化解。

ServerAliveInterval 是什么,为什么必须配 ServerAliveCountMax
简单而言,ServerAliveInterval 是 OpenSSH 客户端的一个参数,它控制着本地机器每隔多少秒,向远程服务器发送一个特定的 SSH_MSG_IGNORE 数据包。这个包本质上是“心跳”信号,不执行任何命令,目的就是告知中间的网络设备:“这条连接仍然活跃,请勿清除”。
但这里有一个关键陷阱:ServerAliveInterval 只负责“发送”,不负责“断开”。真正决定何时放弃连接并报错退出的,是它的搭档——ServerAliveCountMax。该参数定义了连续发送多少次心跳后仍未收到任何响应,客户端才会判定连接中断。
- 只设
ServerAliveInterval 60,而ServerAliveCountMax保持默认值0:客户端会无限期地发送心跳并等待,连接陷入停滞状态,看起来就像“假死”,行为难以预测。 - 设
ServerAliveInterval 30+ServerAliveCountMax 3:这意味着最多耐受 90 秒(30秒*3次)的链路中断。超过这个时间仍未收到响应,客户端就会果断断开连接并报错,行为清晰可控。 - 数值选择需要谨慎:值太小(比如
10)会徒增不必要的网络流量;值太大(比如120)则可能赶不上云厂商安全组的超时限制(例如阿里云SLB默认900秒,而AWS ELB可能只有60秒)。
怎么配才真正生效:用户级 ~/.ssh/config 是首选
配置方法有多种,但最可靠、最推荐的是写入个人配置文件。修改 /etc/ssh/ssh_config 会影响所有用户,还可能被系统更新覆盖;而每次在命令行临时添加 -o ServerAliveInterval=60 又太繁琐,且容易遗漏 ServerAliveCountMax。
最佳实践是编辑 ~/.ssh/config 文件:
Host *
ServerAliveInterval 45
ServerAliveCountMax 5
ConnectTimeout 10
Host *表示对所有SSH连接生效。您也可以写成Host prod-server来精确匹配特定主机。- 这里额外添加了
ConnectTimeout 10。它与连接保活无关,但能防止首次连接时因DNS解析或网络抖动而长时间卡住,是一个常被忽视却非常实用的设置。 - 修改保存后即时生效,无需重启任何服务,新发起的所有SSH连接都会自动应用这些配置。
配了还是断?优先检查这三处
要使心跳机制正常运作,需要满足一个完整链条:心跳包能成功发出、对方能顺利接收、响应能及时返回。如果配置正确却仍然断线,问题往往出在链条中的其他环节:
- 云厂商安全组/NAT网关策略:这是最常见的“隐形杀手”。例如,AWS的ELB(弹性负载均衡器)默认的空闲超时时间可能只有60秒。如果您的
ServerAliveInterval设成了60秒,心跳包永远会在连接被清理后才发出,自然无效。此时必须将间隔设置为小于超时时间的一半(例如≤30秒)才稳妥。 - 终端复用工具干扰:如果您在使用
tmux或screen,需注意它们自身也有会话超时参数。例如tmux默认的idle-timeout是10分钟,这可能会覆盖SSH的心跳效果,需要手动关闭。 - GSSAPI认证导致的卡顿:这虽然不是保活问题,但症状相似——连接建立后很快卡住或断开。在服务端的
/etc/ssh/sshd_config中设置GSSAPIAuthentication no并重启sshd服务,通常能解决。
ClientAliveInterval 和 TCPKeepAlive 基本不用碰
网上一些方案会提到这两个参数,但坦率地说,对于绝大多数客户端用户,它们要么收效甚微,要么多此一举。
- ClientAliveInterval:这是服务端的配置,写在
/etc/ssh/sshd_config里。它要求您有远程服务器的root权限并能重启sshd服务,这在生产环境中通常不现实。因此,从客户端角度,通常可以忽略它。 - TCPKeepAlive yes:这是操作系统内核TCP层的保活机制,Linux默认的探测间隔长达7200秒(2小时),对于以分钟甚至秒为单位的防火墙超时策略而言,效果微乎其微。而且,一些深度包检测防火墙会丢弃TCP层的KeepAlive包,但对加密的SSH应用层心跳包却往往放行。对于OpenSSH客户端而言,
ServerAliveInterval已经足够,完全不需要启用TCPKeepAlive。
最后提一个容易忽视的细节:ServerAliveInterval 的作用范围仅限于“您的本机”到“您直接连接的目标主机”这一段。如果您使用了跳板机(通过 ProxyCommand 配置),那么从跳板机到最终目标服务器的那段连接,仍然可能因空闲而断开。解决方法是在跳板机上也配置同样的 ServerAliveInterval 参数。
