SFTP连接卡住的根本原因是中间网络设备静默丢弃空闲TCP连接,而OpenSSH默认不发保活包;应配置ServerAliveInterval 30与ServerAliveCountMax 3实现可靠探测和自动断连。

为什么 SFTP 连接卡在 password prompt 或建立连接后无响应
根本原因常是中间网络设备(如防火墙、NAT 网关)静默丢弃了空闲 TCP 连接,而 OpenSSH 默认不发送任何保活探测包。客户端看似“卡住”,实则是等待服务端响应,但连接早已被中间设备切断,服务端根本没收到请求。
关键区别:TCP keepalive 是内核级机制,作用于底层 socket;ServerAliveInterval 是 OpenSSH 客户端主动发 SSH 层 keepalive 消息(SSH_MSG_GLOBAL_REQUEST),更可靠、可穿透 NAT、且能触发重连逻辑。
-
TCP keepalive默认通常关闭或超时过长(Linux 默认 7200 秒),对 SFTP 交互场景完全无效 -
ServerAliveInterval必须配合ServerAliveCountMax使用,否则单次丢包就导致假死 - 服务端的
ClientAliveInterval不影响客户端发起的保活,仅控制服务端主动探测,不能解决客户端连接挂起问题
如何在 ssh_config 中正确配置 ServerAliveInterval
直接修改用户级配置 ~/.ssh/config 最安全,避免影响系统其他连接。目标是让客户端每 30 秒发一次探针,连续 3 次无响应即断开并报错,而非无限等待。
Host example.com
HostName example.com
User myuser
ServerAliveInterval 30
ServerAliveCountMax 3
ConnectTimeout 10
-
ServerAliveInterval 30:单位秒,建议 15–45,太短增加无效流量,太长无法及时发现断连 -
ServerAliveCountMax 3:必须设为小整数(2 或 3),默认值 0 表示“永远重试”,会掩盖真实故障 -
ConnectTimeout 10单独设置,防止首次握手因网络抖动卡死,与保活无关但常被忽略 - 不要在命令行用
-o ServerAliveInterval=30临时覆盖,容易遗漏ServerAliveCountMax导致行为不一致
什么时候需要同时调整 TCP keepalive(极少数情况)
仅当你的 SFTP 客户端不是 OpenSSH(比如某些嵌入式工具、旧版 FileZilla、或自研基于 libssh 的程序),且无法配置应用层保活时,才需回退到内核级 TCP keepalive。OpenSSH 用户几乎不需要碰这个。
若真要调,只能在客户端机器全局或进程级设置(如 Linux 上通过 /proc/sys/net/ipv4/tcp_keepalive_time),但注意:
- 它对已建立的连接无效,只影响新创建的 socket
- Windows 和 macOS 的默认 keepalive 时间更长(2 小时以上),且不可通过 ssh_config 控制
- 即使开启,中间设备仍可能无视 TCP keepalive 包(尤其非标准端口或深度检测防火墙)
- 与
ServerAliveInterval混用无意义,后者更精准、协议感知、可被日志记录
验证保活是否生效的简单方法
别依赖主观“感觉快了”,用实际网络干扰测试最可靠。例如在连接建立后,手动切断客户端网络(拔网线 / 关 Wi-Fi),观察断开时间是否接近 ServerAliveInterval × ServerAliveCountMax。
- 启用详细日志:
ssh -vvv -F ~/.ssh/config user@host,搜索debug1: Sending SSH2_MSG_GLOBAL_REQUEST for "keepalive@openssh.com" - 用
tcpdump -i any port 22 -w sftp-keepalive.pcap抓包,确认每 30 秒出现一次 SSH keepalive 请求 - 如果仍慢,检查是否用了代理(
ProxyCommand)、跳板机(ProxyJump),保活配置需加在对应 Host 块中,而非最终目标主机 - 某些企业环境强制使用 SSL 中间人代理(如 Zscaler),会干扰 SSH keepalive,此时需联系网络管理员确认策略
真正影响 SFTP 响应速度的,往往不是保活本身,而是保活没配对导致的“假死—重试—再卡住”循环。把 ServerAliveInterval 和 ServerAliveCountMax 当作连接健康检查的最小单元来对待,而不是可选优化。











