必须同时配置tmout和clientaliveinterval+clientalivecountmax才能可靠断连;tmout只响应键盘输入,无法感知网络中断或客户端假死,而clientaliveinterval与clientalivecountmax在sshd层通过加密心跳探测连接真实性。

TMOUT 能让 SSH 会话自动注销,但它只管“人有没有敲键盘”,不管“网络还通不通”。单独设 TMOUT,笔记本合盖再打开、客户端假死、tail -f 等场景下根本不会触发退出——这不是配置错了,是机制本就不覆盖这些情况。真正可靠的闲置断连,必须搭配 SSH 服务端的保活参数一起用。
TMOUT 怎么设才在 SSH 里起作用
它不是写进文件就生效,关键在三点:导出、加载、作用域。
- 必须写成
export TMOUT=600(不能只写TMOUT=600),否则子 shell 和新登录会话不继承 - 对所有用户生效,加到
/etc/profile末尾;只对当前用户,加到~/.bash_profile(注意:~/.bashrc在 SSH 登录时默认不读) - 改完要运行
source /etc/profile或新开 SSH 连接,否则当前终端看不到效果 - 执行
echo $TMOUT输出数字(如 600),才算真正加载成功
为什么 TMOUT 单独用容易失效
它的计时逻辑非常明确:只在 shell 等待命令输入时倒数。一旦控制权被交出去,计时就暂停。
- 运行
vim、htop、less等全屏程序时,TMOUT 完全不计时 - SSH 到另一台机器后,本地 TMOUT 停止作用,远端的才开始计
- 图形终端(GNOME Terminal、Konsole)压根不理会 TMOUT,这是设计如此,不是 bug
-
sudo -i或su -切换用户后,会重新读目标用户的配置,若其配置里有unset TMOUT,就失效了
必须配合的 SSH 服务端参数
TCP 层的心跳探测才是防断连的核心。ClientAliveInterval 和 ClientAliveCountMax 必须同时配,缺一不可。
- 编辑
/etc/ssh/sshd_config,确保这两行取消注释且格式正确:ClientAliveInterval 300ClientAliveCountMax 2
(注意:不能写等号,不能带 #,也不能缩进) - 总空闲容忍时间 = 300 × 2 = 600 秒(10 分钟),超时后直接关闭 socket,提示 “Connection closed by remote host”
- 改完必须执行
sudo systemctl restart sshd,reload 不保证生效 - 避免设
ClientAliveCountMax 0,这会导致第一次心跳失败就断连,极易误杀正常连接
验证是不是真生效了
别只看 echo $TMOUT,那只是语法对了;要分两层验证:
-
Shell 层验证:新 SSH 登录后,执行
unset TMOUT(关掉 shell 超时),然后静默等待 10 分钟——如果仍被踢出,说明 ClientAlive 生效 -
网络层验证:另一台机器连上来,执行
sudo ss -tnp | grep :22确认连接存在;然后断网或关客户端,等超过 10 分钟,再查连接是否消失 - 注意 systemd-logind 的干扰:若系统启用了
IdleAction=lock或terminate,它可能比 sshd 更早干掉会话











