SSH 隧道空闲断开怎么配置 ServerAliveInterval 心跳检测?

文章导读
直接在客户端配置发送心跳包,能解决大多数因网络空闲导致的连接中断问题。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

直接在客户端配置发送心跳包,能解决大多数因网络空闲导致的连接中断问题。

先说结论:通过修改 SSH 客户端配置或启动参数,让客户端定期向服务器发送空数据包,可以防止中间网络设备因超时而切断连接。

  • 适合需要长时间保持空闲的远程会话场景
  • 先准备客户端配置文件或确认命令行参数权限
  • 验收需在网络空闲状态下观察连接是否保持

命令速用版

如果只是临时使用,可以在命令中直接添加参数:

ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 user@host

如果希望永久生效,编辑本地配置文件 ~/.ssh/config

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

为什么会这样

SSH 连接断开通常不是因为服务器主动关闭,而是中间的网络设备(如 NAT 网关、防火墙)认为连接已空闲,从而清除了映射表项。SSH 协议本身支持心跳机制,客户端通过 ServerAliveInterval 设置发送心跳的时间间隔,服务器收到后无需回复具体内容,但这一来一回的数据包能刷新网络设备的状态计时器。

另外,服务器端也可能配置了 ClientAliveInterval,如果服务器太久没收到客户端数据,也可能主动断开。客户端发送心跳能同时缓解这两种情况。

分步处理

1. 确认配置文件位置

Linux 和 macOS 用户通常使用 ~/.ssh/config,Windows 用户如果使用 OpenSSH 客户端,路径类似 C:\Users\用户名\.ssh\config。如果文件不存在,可以新建一个。

2. 写入配置项

使用文本编辑器打开文件,添加以下内容。注意缩进不是必须的,但保持清晰更好:

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

这里 Host * 表示对所有连接生效。如果只想针对特定服务器,可以把 * 换成主机名或 IP。

3. 设置权限(重要)

SSH 客户端对配置文件权限有严格要求,权限过开放会导致配置被忽略。在 Linux/macOS 终端执行:

SSH 隧道空闲断开怎么配置 ServerAliveInterval 心跳检测?
chmod 600 ~/.ssh/config

怎么验证是否生效

1. 查看 verbose 日志

连接时加上 -v 参数,观察输出中是否有发送 keepalive 的记录。虽然默认日志不一定显示每次心跳,但可以确认配置已加载:

ssh -v user@host

在输出开头寻找 Reading configuration data... 以及后续的连接维持信息。

2. 实际空闲测试

连接成功后,不要执行任何命令,离开电脑等待超过 2 分钟。回来后按回车,如果仍然能立即出现命令提示符,说明连接未断开。如果配置未生效,通常会看到 Connection reset by peer 或类似错误。

常见坑

1. 混淆客户端与服务端配置

ServerAliveInterval 是客户端配置,写在本地 ssh_config 中;ClientAliveInterval 是服务端配置,写在服务器的 sshd_config 中。普通用户通常只能修改客户端配置,不要试图去改云服务商的控制台安全组来替代心跳。

2. 间隔设置过短

公开资料中没有看到可靠的量化数据表明具体多少秒最优,但设置过短(如 5 秒)会增加不必要的流量和服务器负载,设置过长(如 300 秒)可能无法防止某些激进的 NAT 超时。60 秒是社区中较常见的经验值。

3. 忽略 ServerAliveCountMax

如果网络真的断了,客户端不会无限期尝试发送心跳。ServerAliveCountMax 定义了允许丢失多少个心跳包后断开连接。默认值通常是 3,如果网络质量较差,可以适当调大,但这只是延缓报错,不能修复网络故障。

参考来源

  • OpenSSH Manual, ssh_config(5) - OpenSSH SSH client configuration files, https://man.openbsd.org/ssh_config.5
  • Linux Man Pages, ssh_config(5) - SSH client configuration files, https://linux.die.net/man/5/ssh_config