根本原因是服务端主动关闭空闲连接,需同步配置服务端clientaliveinterval 60与clientalivecountmax 3,并重启sshd;客户端可配serveraliveinterval与serveralivecountmax实现保活,tmout无效。

SSH 连接空闲一段时间后自动断开,根本原因不是客户端“卡了”,而是服务端主动关闭了无响应的连接。解决它得从服务端配置和客户端保活两头入手,单改一边常无效。
修改 sshd_config 启用服务端心跳探测
这是最可靠、对所有客户端生效的方式。编辑 /etc/ssh/sshd_config,确保以下两项存在且未被注释:
-
ClientAliveInterval 60:服务器每 60 秒向客户端发一次探测包 -
ClientAliveCountMax 3:连续 3 次探测无响应(即 180 秒)后强制断开连接
注意:ClientAliveCountMax 设为 0 表示无限重试,不推荐;设为 1 则实际超时就是 ClientAliveInterval 值,太激进易误断。改完必须执行 systemctl restart sshd 生效,仅 reload 不够。
客户端配 ServerAliveInterval 主动维持连接
当无法修改服务端(如云厂商托管 SSH 服务),或想在本机单独控制行为时,用客户端配置更灵活。在 ~/.ssh/config 中为特定主机添加:
Host myserver
HostName 192.168.1.100
User admin
ServerAliveInterval 45
ServerAliveCountMax 2
含义是:每 45 秒发一次 keepalive 包,连续 2 次失败(即 90 秒无响应)才断开。这个配置只影响该 Host 条目,不影响其他连接。若全局生效,可在 Host * 下设置。
TMOUT 只管 shell 会话,不解决 SSH 断连
很多人误以为改 export TMOUT=0 或 export TMOUT=100000 能防 SSH 断开,其实它只控制当前 bash 会话的空闲退出(read 超时、交互等待等),对底层 TCP 连接毫无作用。SSH 连接已在内核层被服务端切断,shell 层面的 TMOUT 根本来不及触发。
常见错误现象:你明明设置了 TMOUT,但终端仍突然显示 Connection closed by remote host —— 这说明断连发生在 SSH 协议层,不是 shell 层。
权限与调试:为什么改了配置还不生效?
最容易被忽略的是配置加载顺序和权限问题:
- 服务端配置必须由 root 修改,且
sshd_config文件本身不能有语法错误(可用sshd -t验证) - 客户端
~/.ssh/config文件权限必须是600,否则 OpenSSH 直接忽略该文件 - 若使用非标准端口或 ProxyJump,保活参数需写在对应 Host 块内,不能只写在顶层
- 某些企业网络设备(如防火墙、NAT 网关)自身会切断长连接,此时需同步调整设备的 TCP 超时策略
验证是否生效:登录后执行 ssh -O check myserver(需支持 multiplexing)或观察 ss -tnp | grep :22 中连接的 timer 字段是否显示 keepalive。











