远程连接超时问题,实际上是一个典型的多层故障——并非通过单一配置项就能解决。它分为两个阶段:连接建立时无法连通,以及连接建立后中途断开。你遇到的是TCP握手失败,还是连接几分钟后自动掉线?解决路径完全不同,混淆了只会白费功夫。

先说结论:这三层彼此独立、互不覆盖。TCP层超时、SSH协议层保活、Shell会话超时,你需要先定位问题发生在哪一层,再调整对应的配置参数。
ssh 连不上:检查 TCP 层连接超时
典型报错信息是 ssh: connect to host x.x.x.x port 22: Connection timed out。本质很简单:客户端发出的SYN包石沉大海,未收到服务器响应。此时别急着翻SSH配置,九成是网络或防火墙的问题。
- 先确认目标IP和端口是否可达:
telnet x.x.x.x 22或nc -zv x.x.x.x 22。如果失败,说明连接根本没到达sshd进程。 - 检查服务器防火墙是否放行了22端口:
sudo ufw status(Ubuntu)或sudo firewall-cmd --list-ports(CentOS/RHEL)。 - 内核连接重试次数由
/proc/sys/net/ipv4/tcp_syn_retries控制,默认值为6(约130秒超时)。一般无需修改,但如果想缩短等待时间,可以临时设为3:echo 3 | sudo tee /proc/sys/net/ipv4/tcp_syn_retries。 - 永久修改则写入
/etc/sysctl.conf:追加net.ipv4.tcp_syn_retries = 3,再执行sudo sysctl -p。
ssh 连上后自动断开:调整保活参数
这是最容易被误称为“超时”的情况——实际上只是空闲连接被主动关闭了。关键看谁在控制断连:服务端用 ClientAliveInterval,客户端用 ServerAliveInterval。
- 服务端全局生效(推荐):编辑
/etc/ssh/sshd_config,确保包含以下两行(取消注释或新增):
ClientAliveInterval 60
ClientAliveCountMax 3
重启服务:sudo systemctl restart sshd - 客户端单用户生效:编辑
~/.ssh/config,添加:
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
注意权限设置:chmod 600 ~/.ssh/config - 临时调试用命令行:
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 user@host - 不要把
TCPKeepAlive和这个搞混。TCPKeepAlive 工作在TCP层,只能探测链路通不通,防不了NAT超时;而ServerAliveInterval是SSH协议层的心跳,能够穿透中间NAT设备。
终端登录后自动退出:Shell 级空闲超时
如果SSH连接没断,但Bash提示 timed out waiting for input: auto-logout,那是Shell的 TMOUT 在起作用,与SSH保活完全无关。
- 全局设置(影响所有Bash用户):在
/etc/profile末尾添加TMOUT=600和export TMOUT。 - 用户级设置:在
~/.bashrc里写入export TMOUT=1800(30分钟)。 - 强制只读(防止用户覆盖):新建
/etc/profile.d/autologout.sh,内容为:
TMOUT=300
readonly TMOUT
export TMOUT
再执行sudo chmod +x /etc/profile.d/autologout.sh。 - 当前会话临时禁用:
unset TMOUT。
最后再说一句容易被忽略的层级关系:TCP层超时 → SSH协议层保活 → Shell会话超时,三者独立生效、互不覆盖。先定位问题发生在哪一层,再调整对应配置,否则你改了 sshd_config 却发现是 TMOUT 在作怪,纯粹白忙一场。
