openssh客户端防断连需配置serveraliveinterval和serveralivecountmax,前者设心跳间隔(如30秒),后者设最大失败次数(如3次),二者合起来实现主动保活;服务端则用clientaliveinterval和clientalivecountmax控制空闲超时,与客户端机制不同。

OpenSSH 客户端怎么设置心跳防止断连
客户端主动发心跳,靠的是 ServerAliveInterval 和 ServerAliveCountMax 这两个配置。不设它们,SSH 默认完全不发任何保活包,网络中间设备(比如 NAT 网关、防火墙)静默丢包后,连接就卡住或悄无声息断开。
常见错误现象:终端突然卡死、ssh 命令无响应、执行命令后光标不动但实际已断连;再敲字符会报 Write failed: Broken pipe。
-
ServerAliveInterval 30表示每 30 秒向服务端发一次空包(TCP 层的 ACK + SSH keepalive 消息) -
ServerAliveCountMax 3表示连续 3 次没收到响应才断开连接(即最多容忍 90 秒无响应) - 这两个参数只在客户端生效,写在
~/.ssh/config里最稳妥,例如:Host example.com HostName example.com User alice ServerAliveInterval 30 ServerAliveCountMax 3 - 别用
ClientAliveInterval—— 那是服务端配置项,对单个客户端无效,且需要 root 权限改/etc/ssh/sshd_config
OpenSSH 服务端如何限制空闲会话时长
服务端控制空闲断连,核心是 ClientAliveInterval 和 ClientAliveCountMax,但它们的行为和客户端的 ServerAlive* 完全不同:服务端是「等客户端不说话太久才动手」,不是「帮客户端保活」。
典型使用场景:运维统一管理服务器,防止用户忘记登出、长期挂着 shell 占资源,或规避审计漏洞。
-
ClientAliveInterval 60表示服务端每 60 秒检查一次该连接是否有新数据(包括 stdin 输入、命令输出等) -
ClientAliveCountMax 5表示连续 5 次检查都无活动(即空闲满 300 秒),就强制关闭连接 - 必须重启
sshd或重载配置(sudo systemctl reload sshd)才生效 - 注意:这个机制对正在运行长任务(如
tail -f、ping)的会话无效——只要 TCP 连接有数据流(哪怕只是服务端在持续吐日志),就不算“空闲”
为什么开了心跳还是被断?常见兼容性坑
心跳不是万能的。有些网络环境或旧版 OpenSSH 会绕过或忽略 keepalive 包,导致配置看似生效实则无效。
- OpenSSH 5.4 以前版本不支持
ServerAliveInterval,客户端会静默忽略——检查版本用ssh -V - 某些企业级防火墙(如 Palo Alto、深信服)默认过滤 SSH keepalive 报文,需在策略中放行
SSH_MSG_GLOBAL_REQUEST类型消息 - 如果服务端设置了极短的
TCPKeepAlive(非 SSH 层,是系统级 TCP 参数),而客户端心跳间隔比它还长,可能被内核先掐断——查用sysctl net.ipv4.tcp_keepalive_time - 使用
mosh或跳板机(ProxyJump)时,心跳只作用于最后一跳;中间跳板若没配,照样断
tmux/screen 能替代心跳吗
不能。tmux 和 screen 是会话保持工具,解决的是「SSH 断开后进程不退出」的问题,和「防止 SSH 连接被中间设备切断」完全无关。
真实情况:你开着 tmux,SSH 连接被路由器超时踢掉,本地终端显示断开,tmux 会话还在远端活着;但你无法再连回去——除非服务端同时配了 ClientAlive* 给你留足重连窗口,或者你本就用了 mosh 这类协议。
- tmux 的
set -g set-remain-on-exit off之类配置,只影响 pane 行为,不影响底层 TCP 连接生命周期 - 想真正抗断线,必须双管齐下:客户端开
ServerAliveInterval主动保活,服务端设合理ClientAlive*防僵死 - 如果连不上、ping 得通但 ssh 握手卡住,优先怀疑是中间链路 kill 了 keepalive,而不是 tmux 没启好
真正麻烦的是混合环境:客户端在 Windows(OpenSSH for Windows 旧版)、跳板机跑 CentOS 6、目标服务器是 Alpine 上的 dropbear —— 这时候 keepalive 可能根本没协商成功,连日志都看不到提示,得抓包确认。










