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配置错误导致完全无法远程访问。