必须同时配置TMOUT=1800和sshd_config中ClientAliveInterval 600与ClientAliveCountMax 3,前者控制终端输入空闲超时,后者通过心跳检测网络连接真实性,二者分别应对“人未操作”和“连接假活跃”场景,缺一不可。

只配 TMOUT 或只改 ClientAliveInterval,SSH 空闲断连基本失效。必须两者都设,且各自生效逻辑完全不同——一个管“人有没有动键盘”,一个管“连接还通不通”。
为什么单独设置 TMOUT 无法真正踢掉假死 SSH 连接
TMOUT 是 shell 层变量,依赖 stdin 输入触发计时。一旦发生以下情况,它就完全失能:
- 客户端休眠、合盖、网络中断,
sshd进程仍维持 ESTABLISHED 状态,TMOUT根本不启动 - 运行
tail -f、top、vim等全屏程序时,stdin 被接管,空闲计时不继续 - GNOME Terminal、Konsole 等图形终端默认忽略
TMOUT,设了也白设 - root 用户可能不读
/etc/profile,而是直接加载~/.bashrc,导致全局TMOUT不生效
如何正确配置 ClientAliveInterval 和 ClientAliveCountMax
这两个参数在 /etc/ssh/sshd_config 中协同工作,由 sshd 主动发加密心跳包探测连接真实性:
- 必须同时取消注释:
ClientAliveInterval 300(每 5 分钟发一次心跳)和ClientAliveCountMax 3(最多容忍 3 次无响应),总超时 = 300 × 3 = 900 秒(15 分钟) - 禁止写成
ClientAliveInterval=300—— 等号是语法错误,sshd 启动会失败 - 避免设
ClientAliveCountMax 0:这会让 sshd 在第一次心跳无响应时立即断连,极易误杀正常连接(比如短暂丢包) - 改完必须执行
sudo systemctl restart sshd;reload有时不生效,尤其在 systemd-logind 干预时
怎么验证 SSH 自动退出真的起作用了
别只信 echo $TMOUT 或 sshd -t —— 那只说明配置“写对了”,不是“跑对了”:
- Shell 层验证:新 SSH 登录后,先执行
unset TMOUT,然后静默等待 15 分钟,观察是否被踢出。若没退出,说明ClientAlive没生效 - 网络层验证:另一台机器登录后,用
sudo ss -tnp | grep :22确认连接存在;拔网线或关客户端,等超过 900 秒后再查连接是否消失 - 注意干扰项:systemd-logind 的
IdleAction(如 lock/terminate)可能抢在 sshd 前干掉会话,需检查loginctl show-user $USER中的IdleHint和IdleSinceUSec
最常被忽略的点:TMOUT 对非 bash shell(如 zsh、dash)无效;ClientAlive 对本地 console 登录完全不作用——要覆盖所有入口,得搭配 PAM 的 pam_idle.so 或系统级 /etc/profile.d/ 只读脚本。


















