SSH 连接频繁断开与卡顿排查:心跳、MTU 与 DNS 反解

    发布时间:2026-09-17 04:31 更新时间:2026-09-17 04:31 阅读量:0

    用 SSH 连服务器时遇到两种典型症状:一种是登录后放着不动,几分钟后窗口突然卡住,敲键盘没反应,只能重连;另一种是连接一直在,但每次输入命令都要等一两秒才回显,上传下载也拖沓。前者多半是链路空闲被中间设备切断,后者往往和 MTU、DNS 反解有关。这篇把三类原因的排查顺序和配置写清楚,跟着做基本能定位到根因。

    一、闲置掉线:先看心跳有没有开

    SSH 连接建立后,如果一段时间没有数据往来,中间的 NAT 网关、云厂商安全组、运营商设备都可能把这条空闲会话从会话表里清掉,客户端却还以为是通的,于是表现为“卡死”。解决办法是让两端定期发心跳包,保持会话活跃。

    在服务端 /etc/ssh/sshd_config 中加上心跳与超时控制:

    # 服务端每 60 秒向客户端发一次探测
    ClientAliveInterval 60
    

    连续 3 次无响应则认为客户端失联,断开连接

    ClientAliveCountMax 3

    关闭服务端对客户端的反向 DNS 查询(后文详述)

    UseDNS no

    改完执行 sshd -t 检查语法,再 systemctl reload sshd(Debian/Ubuntu 上服务名可能是 ssh,以实际环境为准)。注意 reload 不会踢掉现有连接,新登录的会话才生效。

    客户端一侧也可以主动发心跳,在 ~/.ssh/config 里写:

    Host *
        ServerAliveInterval 30
        ServerAliveCountMax 3
        TCPKeepAlive yes
    

    ServerAliveInterval 是客户端每隔多少秒向服务端发一次空包,比服务端的 ClientAliveInterval 更常用,因为它不需要改服务器权限。两边都配也不冲突,只是心跳更密一些。

    需要提醒的是,ClientAliveCountMax 设成 0 或过大都有副作用:设 0 会导致探测一次就断,设得太大则真正断线时要等很久才回收。一般 3 到 5 比较合适。

    二、输入延迟:MTU 与 DNS 反解是常见嫌疑

    如果连接不掉,但操作明显卡顿,先分清是“建立连接时慢”还是“交互过程中慢”。

    登录握手慢、要等好几秒才出密码提示,多数是服务端在做客户端 IP 的反向 DNS 解析,解析不到就等超时。确认方法:用 ssh -v 用户@主机 观察卡在哪一步,如果停在 Authenticating 之前,基本可以确认。此时在 sshd_config 中设置 UseDNS no 并 reload 即可。这也是很多云主机默认关闭 UseDNS 的原因。

    登录后输入延迟、大包传输卡顿,要怀疑 MTU。典型场景是服务器走隧道、VPN 或某些云内网,路径 MTU 比默认 1500 小,而 SSH 交互时小包能过、稍大的包被丢弃且没有回 ICMP,于是触发重传,表现为“敲一下卡一下”。

    排查用 ping 探测路径 MTU(Linux 下 -M do 表示不分片,Windows 用 -f):

    # 从 1472 开始递减,1472+28=1500
    ping -M do -s 1472 -c 3 目标IP
    

    若提示 Message too long,逐步减小到能通为止

    ping -M do -s 1400 -c 3 目标IP

    能通的最大值加上 28 字节 IP/ICMP 头,就是这条路径的实际 MTU。如果明显小于 1500,可以把本机网卡 MTU 调小测试:

    # 临时生效,重启网卡后失效
    ip link set dev eth0 mtu 1400
    

    查看确认

    ip link show eth0

    确认有效后再写进发行版的网络配置(如 /etc/network/interfaces、NetworkManager 或 netplan,具体以官方文档为准)。另外 TCP 层通常有 MSS 自动协商,MTU 问题更多出现在隧道和 UDP 场景,不要一上来就改网卡。

    还有一种卡顿来自服务端负载:CPU 跑满、磁盘 IO 阻塞、内存吃紧时,SSH 会话本身也会响应慢。可以先 top、vmstat 1 看一眼。如果是登录时加载 shell 配置慢,检查 ~/.bashrc 里有没有执行耗时命令或网络请求。

    三、定位手段与配置落地建议

    排查顺序建议从成本最低的开始:先确认心跳参数,再排除 UseDNS,最后才动 MTU 和网络设备。抓包能看到最直接的现象,比如反复重传:

    # 抓取本机 22 端口流量,观察是否有大量重传
    sudo tcpdump -i eth0 -nn 'tcp port 22' -w ssh.pcap
    

    也可先用 -c 限制包数,避免文件过大

    sudo tcpdump -i eth0 -nn -c 200 'tcp port 22'

    抓到的包用 Wireshark 打开,重点看 TCP Retransmission 和 Duplicate ACK 是否密集。如果重传集中在较大的数据包上,MTU 的嫌疑就比较大;如果只是长时间没有包,则是空闲被切断。

    配置落地时记住三条:服务端心跳和 UseDNS no 属于通用优化,可以放心加;客户端 ServerAliveInterval 只影响自己,改坏也不影响别人;MTU 属于网络层参数,改动前记录原值,改完验证,出问题能立刻回滚。三者的作用点不同,不要把“掉线”和“卡顿”混成一个问题处理。

    最后给一个排查清单:掉线优先查心跳与中间设备会话超时;握手慢查 UseDNS;交互卡查 MTU 与服务器负载;都不确定就抓包看重传。按这个顺序走,多数 SSH 连接问题能在十几分钟内定位。涉及云厂商安全组、专线或 VPN 的具体行为,以对应平台文档和实际环境为准。

    继续阅读

    📑 📅
    Linux内存被缓存吃满:buff/cache该不该手动释放 2026-09-17
    服务器时间不同步导致证书与定时任务异常:NTP/chrony 校时配置与排查 2026-09-16
    PostgreSQL 连接数与内存调优:max_connections 与 shared_buffers 怎么配 2026-09-16
    Linux文件句柄耗尽排查:Too many open files 从ulimit到systemd 2026-09-16
    Nginx 后端真实 IP 获取:X-Forwarded-For 与 real_ip 配置 2026-09-16
    MySQL表空间与ibdata1膨胀处理:独立表空间、碎片整理与磁盘回收 2026-09-17
    系统盘满了却找不到大文件:被删除但仍被进程占用的句柄排查与恢复空间 2026-09-17
    服务器 swap 使用率飙升:正常换页还是内存真不够用 2026-09-17
    Docker容器时区不对?TZ变量与localtime挂载的正确用法 2026-09-17
    journald 日志占满 /var/log:持久化与容量限制配置 2026-09-18