Ubuntu系统做完安全加固之后,SSH登录变慢甚至卡顿几十秒,绝大多数情况是由两个核心原因导致的:一是SSH服务端配置了UseDNS yes,导致每次连接都要做反向DNS解析;二是GSSAPIAuthentication开启后,客户端和服务端之间进行Kerberos认证协商超时。此外,/etc/hosts.deny和/etc/hosts.allow的TCP Wrappers机制、PAM模块的延迟、以及SSH密钥交换算法被限制为高安全性但低性能的选项,都会拖慢登录速度。解决方法很直接——修改/etc/ssh/sshd_config,关闭DNS解析和GSSAPI认证,重启sshd服务即可立竿见影。
下面我把这个问题从根因到解决方案,一层一层给你拆清楚。
一、SSH登录缓慢的典型表现你在加固Ubuntu之后,执行ssh user@server,终端会先卡住10秒到30秒,甚至更久,然后才出现密码提示或者直接连接成功。如果你用ssh -v开启详细日志模式,你会看到类似这样的输出:
debug1: Connecting to xxx.xxx.xxx.xxx [xxx.xxx.xxx.xxx] port 22. debug1: Connection established. debug1: key_load_public: No such file or directory debug1: identity file /home/user/.ssh/id_rsa type -1 debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_8.9p1 debug1: Remote protocol version 2.0, remote software version OpenSSH_8.9p1 debug1: match: OpenSSH_8.9p1 pat OpenSSH* compat 0x04000000 debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: algorithm: curve25519-sha256 debug1: kex: host key algorithm: ssh-ed25519 debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none debug1: expecting SSH2_MSG_KEX_ECDH_REPLY debug1: SSH2_MSG_KEX_ECDH_REPLY received debug1: Server host key: ssh-ed25519 SHA256:xxxxx debug1: Host 'xxx.xxx.xxx.xxx' is known and matches the ED25519 host key. debug1: Found key in /home/user/.ssh/known_hosts:1 debug1: rekey out after 134217728 blocks debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: rekey in after 134217728 blocks debug1: Will attempt key: /home/user/.ssh/id_rsa debug1: Will attempt key: /home/user/.ssh/id_ecdsa debug1: Will attempt key: /home/user/.ssh/id_ed25519 debug1: Will attempt key: /home/user/.ssh/id_xmss debug1: SSH2_MSG_EXT_INFO received debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,sk-ssh-ed25519@openssh.com> debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey,password debug1: Next authentication method: publickey debug1: Offering public key: /home/user/.ssh/id_rsa RSA SHA256:xxxxx debug1: Authentications that can continue: publickey,password debug1: Next authentication method: password
如果你看到在"Connection established"之后有长时间停顿,或者在"Next authentication method"之前卡住,那基本就是DNS解析或者GSSAPI的问题。
二、根因一:UseDNS反向解析延迟这是最常见的原因。Ubuntu默认的sshd_config里,UseDNS被设置为yes。这意味着每次有客户端连接进来,sshd都会尝试把客户端的IP地址反向解析成主机名。如果你的DNS服务器响应慢、或者根本没有配置反向解析,这个过程就会超时等待,通常要等5到30秒。
解决方法非常简单,打开配置文件:
sudo vim /etc/ssh/sshd_config
找到这一行:
UseDNS yes
改成:
UseDNS no
保存退出,然后重启sshd服务:
sudo systemctl restart sshd
改完之后你再试一下ssh登录,速度会有质的飞跃。这个改动对安全性几乎没有影响,因为主机名解析不是认证环节,只是日志记录用的。
三、根因二:GSSAPIAuthentication认证协商超时GSSAPI是一种基于Kerberos的认证机制。Ubuntu默认开启了GSSAPIAuthentication yes。当客户端连接时,sshd会尝试和客户端做GSSAPI协商。如果你的环境没有部署Kerberos,这个协商就会失败并超时,通常要等10到20秒。
同样在/etc/ssh/sshd_config里,找到并修改:
GSSAPIAuthentication no
同时建议把相关的GSSAPI选项一并关闭:
GSSAPICleanupCredentials no
这两个选项关掉之后,sshd不再做无意义的Kerberos协商,登录速度直接提升。
四、根因三:TCP Wrappers的访问控制检查很多安全加固指南会建议你配置/etc/hosts.allow和/etc/hosts.deny来做IP白名单控制。这个机制是通过TCP Wrappers实现的,sshd如果编译时启用了libwrap支持,每次连接都会先查这两个文件。
如果你的/etc/hosts.deny里写了ALL: ALL或者配置比较复杂,而/etc/hosts.allow里又没有明确放行,sshd可能会在TCP Wrappers层面上做额外的检查和等待。
建议你检查这两个文件的内容:
cat /etc/hosts.allow cat /etc/hosts.deny
推荐的配置是:
# /etc/hosts.allow sshd: 192.168.1.0/24 sshd: 10.0.0.0/8 # /etc/hosts.deny ALL: ALL
确保你信任的IP段在allow里明确列出,deny里放ALL: ALL作为兜底。这样TCP Wrappers能快速匹配放行,不会产生延迟。
五、根因四:PAM模块延迟PAM(Pluggable Authentication Modules)是Linux的认证框架。sshd通过PAM来做密码验证、账户检查等。加固过程中,你可能安装了pam_pwquality、pam_faillock、pam_tally2等模块来增强密码策略和防暴力破解。
这些模块本身不会导致明显延迟,但如果你配置了pam_faillock或者pam_tally2,并且锁定阈值设置过低,系统在认证失败后会有锁定等待时间。另外,如果你在/etc/pam.d/sshd里加了pam_unix.so的delay参数,也会人为增加延迟。
检查/etc/pam.d/sshd:
sudo vim /etc/pam.d/sshd
看看有没有类似这样的行:
auth optional pam_faillock.so preauth silent deny=3 unlock_time=600
如果有,确认deny和unlock_time参数合理。一般deny设为5到10次,unlock_time设为300到900秒比较合适。不要设成deny=1,否则一次输错密码就锁600秒,体验极差。
六、根因五:SSH密钥交换算法被限制安全加固时,你可能在sshd_config里限制了允许的KexAlgorithms、Ciphers和MACs,只保留高强度的算法。比如只允许curve25519-sha256做密钥交换,只允许chacha20-poly1305@openssh.com做加密。
这些算法本身性能很好,但如果你的客户端版本比较老(比如OpenSSH 6.x或7.x),它可能不支持这些新算法,导致协商过程反复尝试、回退、超时。这种情况在老旧的嵌入式设备或者旧版Windows的SSH客户端上特别明显。
建议在sshd_config里保留一个兼容性较好的算法列表:
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com
这样既保证了安全性,又不会因为算法不兼容导致协商延迟。
七、根因六:系统资源和网络层面的问题有时候SSH登录慢不是sshd配置的问题,而是系统层面的。比如:
1. 系统负载过高:用top或htop看一下CPU和内存使用情况。如果swap大量使用,I/O等待高,SSH进程调度也会变慢。
2. entropy不足:SSH密钥交换需要随机数。如果系统熵池不够(特别是虚拟机环境),/dev/urandom会阻塞等待熵积累。可以安装haveged来解决:
sudo apt install haveged sudo systemctl enable haveged sudo systemctl start haveged
3. 防火墙规则过多:如果你用ufw或iptables做了大量规则,每条规则都要匹配,也会增加连接建立时间。用sudo ufw status verbose检查规则数量,精简不必要的规则。
八、完整的优化配置模板下面给你一个兼顾安全和性能的sshd_config关键段落参考,你可以根据自己的环境调整:
# 禁用DNS解析 UseDNS no # 禁用GSSAPI GSSAPIAuthentication no GSSAPICleanupCredentials no # 限制登录尝试 MaxAuthTries 3 MaxSessions 2 # 限制root登录 PermitRootLogin prohibit-password # 密钥认证优先 PubkeyAuthentication yes PasswordAuthentication yes # 空闲超时 ClientAliveInterval 300 ClientAliveCountMax 2 # 登录横幅 Banner /etc/issue.net # 允许的用户(按需设置) AllowUsers deploy admin # 密钥交换算法 KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com # 日志级别 LogLevel VERBOSE
改完之后记得:
sudo sshd -t # 先测试配置语法是否正确 sudo systemctl restart sshd九、验证和排查工具
如果你改完配置还是慢,用以下方法逐步排查:
1. 客户端加-v参数看详细握手过程:ssh -vvv user@server,重点看在哪一步卡住。
2. 服务端看sshd日志:sudo journalctl -u sshd -f,实时观察连接时的日志输出。
3. 用tcpdump抓包分析:sudo tcpdump -i eth0 port 22 -nn,看数据包的时间间隔。
4. 检查sshd进程状态:sudo systemctl status sshd,看有没有报错或警告。
5. 测试DNS解析速度:nslookup 你的服务器IP 或者 dig -x 你的服务器IP,看反向解析是否正常。
十、总结与建议Ubuntu安全加固后SSH登录慢,90%以上的情况就是UseDNS和GSSAPIAuthentication这两个配置项在作怪。关掉它们,重启sshd,问题基本解决。剩下的10%要从PAM模块、算法兼容性、系统熵池、防火墙规则这些方向去排查。
安全加固和使用体验之间确实存在平衡。不要为了追求极致安全把所有功能都关掉,而是要理解每个配置项的作用,有针对性地调整。建议你每次改完sshd_config都用sshd -t验证语法,改之前备份原文件,避免改错了连不上服务器。
如果你管理的是生产环境,建议在非高峰时段做配置变更,并且始终保留一个控制台或者带外管理通道,防止SSH配置错误导致完全无法远程访问。
