SSH客户端无内置重试机制,connecttimeout控制建连超时,ServerAliveInterval和ServerAliveCountMax仅管理已建立连接的保活断开,自动重连需依赖autossh或shell脚本实现。

SSH 客户端本身不提供“连接重试次数”这个配置项,connecttimeout 控制建连超时,ServerAliveInterval 和 ServerAliveCountMax 控制保活探测失败后的断开逻辑——但都不是重试建连。真要实现自动重连,得靠外部工具或脚本。
为什么 ssh 命令没有 retry 参数
OpenSSH 的 ssh 命令设计为一次性连接:它要么成功建立会话,要么报错退出。不存在内置的“失败后自动重试 N 次再放弃”的机制。你看到的所谓“重试”,其实是上层封装行为。
-
connecttimeout只控制 TCP 握手阶段最多等几秒,超时即报Connection timed out并退出 -
ServerAliveInterval是连接建立后,客户端主动发心跳包的间隔(单位秒) -
ServerAliveCountMax是连续多少次心跳没收到响应,就断开当前连接(默认 3),不是重试建连 - 网络抖动导致连接闪断时,
ssh不会自己重拨,必须由调用方处理
用 autossh 实现可靠重连(推荐)
autossh 是专为解决这个问题写的工具,它监控 ssh 进程状态,崩溃或断开就自动拉起新连接。它比手写 while 循环更健壮,支持退出码判断、连接状态检测和静默重试。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 安装:
sudo apt install autossh(Debian/Ubuntu)或sudo yum install autossh(RHEL/CentOS) - 基本用法:
autossh -M 0 -o "ServerAliveInterval=30" -o "ServerAliveCountMax=3" user@host -
-M 0表示禁用 autossh 自带的监控端口(避免额外端口占用),改用 SSH 内置保活机制判断 - 它会在后台持续尝试,直到连上;Ctrl+C 终止后进程才退出
- 若需限制最大重试次数(比如只试 5 次),得配合 shell 脚本计数,
autossh本身不提供该参数
用 shell 脚本做有限次重试(简单场景)
适合临时调试、CI/CD 流水线中的一次性连接任务,不需要常驻进程。
#!/bin/bash
max_retries=5
retry_count=0
while [ $retry_count -lt $max_retries ]; do
if ssh -o ConnectTimeout=10 -o ServerAliveInterval=30 user@host "echo ok"; then
exit 0
fi
retry_count=$((retry_count + 1))
echo "Attempt $retry_count failed, retrying in 3s..."
sleep 3
done
echo "Failed after $max_retries attempts"
exit 1
- 注意
ConnectTimeout=10必须显式设置,否则默认可能卡住很久(尤其 DNS 解析失败时) -
ServerAliveInterval在这里作用不大——脚本每次都是新连接,保活只对已建立的长连接有效 - 不要把重试逻辑写进
~/.ssh/config,那个文件不支持条件判断和循环
服务端配置不能解决客户端重连问题
有人误以为改 /etc/ssh/sshd_config 里的 MaxAuthTries 或 ClientAlive* 能控制重试次数,其实完全无关:
-
MaxAuthTries限制单次连接内允许输错密码/密钥的次数(比如输错 3 次就断开本次连接),不是重连次数 -
ClientAliveInterval是服务器发心跳给客户端,用于清理挂起连接,不影响客户端是否重试 - 所有服务端参数都不改变客户端发起新连接的行为
真正容易被忽略的是:**重连逻辑必须落在发起连接的一方(客户端)**,而且得明确区分“建连失败”和“连接中途断开”两种情况——前者靠 ConnectTimeout + 脚本/autossh,后者靠 ServerAlive* + autossh。混用或漏配其中一环,都会导致看似“配置了却没效果”。

















