改了TCP keepalive_time仍断连,是因为SFTP基于SSH且默认不启用TCP层保活;OpenSSH使用独立的ClientAliveInterval(服务端)和ServerAliveInterval(客户端)控制保活,二者互不依赖,必须至少配置其一才能防止空闲断连。

为什么改了 TCP keepalive_time 还是断连?
Linux 内核的 TCP keepalive_time 控制的是底层 TCP 连接空闲多久后开始发保活探测包,但 SFTP(基于 SSH)默认根本不会启用 TCP 层的 keepalive。即使你调小了 /proc/sys/net/ipv4/tcp_keepalive_time,OpenSSH 服务端和客户端仍可能在应用层直接关闭连接——因为它们各自有独立的保活机制,且默认关闭。
常见现象是:SFTP 传输大文件中途卡住、Connection closed by remote host、或上传到一半报 Broken pipe。这不是网络中断,而是 SSH 会话被静默终止。
-
TCP keepalive_time影响的是内核 TCP 栈行为,对 OpenSSH 默认无效 - OpenSSH 的保活由
ClientAliveInterval(服务端)和ServerAliveInterval(客户端)控制,优先级更高 - 两者不联动:改了内核参数,没配 SSH 参数,照样超时
ClientAliveInterval 和 ServerAliveInterval 到底谁管谁?
服务端的 ClientAliveInterval 是 SSH daemon 主动向客户端发心跳的间隔;客户端的 ServerAliveInterval 是 ssh 命令主动向服务端发心跳的间隔。二者互不依赖,但必须至少启用其一,否则连接空闲超过服务端默认的 ClientAliveCountMax * ClientAliveInterval(通常 3 × 0 = 0 → 不检测)就会被 kill。
- 服务端配置(
/etc/ssh/sshd_config):ClientAliveInterval 60 ClientAliveCountMax 3
表示每 60 秒发一次心跳,连续 3 次无响应就断开(即总容忍空闲 180 秒) - 客户端配置(
~/.ssh/config或命令行):Host example.com ServerAliveInterval 45 ServerAliveCountMax 2表示每 45 秒发一次,2 次失败即断开(容忍 90 秒) - 若服务端未启用
ClientAliveInterval,仅客户端配ServerAliveInterval就足够维持连接
SFTP 命令行与文件管理器的行为差异
命令行 sftp 工具默认不开启保活,而很多图形化 SFTP 客户端(如 FileZilla、Cyberduck)内置心跳逻辑,所以后者更“耐挂”。如果你用 sftp user@host 手动操作,又长时间没敲命令,大概率被服务端踢掉。
- 临时解决:启动时加参数
sftp -o ServerAliveInterval=30 -o ServerAliveCountMax=3 user@host - 永久解决:在
~/.ssh/config中为对应 Host 设置ServerAliveInterval - 注意:某些旧版 OpenSSH(ServerAliveInterval 在 config 文件中生效,需升级或改用命令行参数
- FileZilla 等工具的“Keep alive”选项本质就是模拟
ServerAliveInterval,但不可见底层细节
别漏掉防火墙和中间设备的干扰
有些企业网络中的 NAT 设备、负载均衡器或防火墙会主动清理“空闲连接”,它们的超时阈值往往比 SSH 更短(比如 60–120 秒),且不识别 SSH 心跳包。这时即使 ServerAliveInterval 设为 30 秒,也可能因中间设备丢包导致心跳失效。
- 验证方法:在客户端执行
tcpdump -i any port 22,观察是否真有心跳包发出并收到响应 - 若心跳包发出但无回包,问题大概率出在中间链路,而非 SSH 配置本身
- 此时可尝试把
ServerAliveInterval改得更激进(如 20 秒),或联系网络管理员调整设备 idle timeout - 避免同时开启
TCP keepalive和 SSH 应用层保活——多一层探测未必更稳,反而增加误判风险
实际部署时最容易忽略的是:服务端 sshd_config 修改后忘记 sudo systemctl reload sshd,或者客户端配置写错 Host 别名导致匹配失败。保活不是越频繁越好,20–45 秒区间已足够覆盖绝大多数中间设备限制,再短反而可能触发限流或被当作扫描行为拦截。











