SSH密钥登录后如何验证香港服务器已降低密码暴力破解风险?
SSH密钥登录成功,并不等于香港服务器已经降低了密码暴力破解风险。真正有效的判断标准是:目标 SSH 服务的实际生效配置已经关闭密码类认证,使用密钥可以正常登录,强制指定密码认证时不能进入密码输入流程,同时日志中不再出现重载之后的 Accepted password 或持续的 Failed password。如果只是把公钥写入 authorized_keys,但仍保留密码登录,攻击者依旧可以对同一个 SSH 入口反复猜测账户密码。

因此,“免密登录”需要先明确含义:它通常是指服务器不再要求输入账户密码,而不是私钥一定没有口令保护。私钥保留本地口令、服务器端关闭 SSH 密码认证,通常比保存一把无口令私钥更稳妥。验证完成后,可以较有把握地判断“SSH 密码暴力破解入口已关闭”;但不能据此认定私钥泄露、其他服务认证或已经建立的登录会话也不存在风险。
先定义要验证的风险边界
添加密钥与关闭密码认证不是一回事
SSH 服务常见的认证方式包括:
| 配置状态 | 密钥登录 | 密码登录 | 对密码暴力破解风险的影响 |
|---|---|---|---|
| 只添加公钥,其他配置不变 | 可以 | 可以 | 风险基本仍在 |
| 首选密钥,但允许回退到密码 | 可以 | 可以 | 只改变登录便利性,没有关闭密码入口 |
关闭 PasswordAuthentication | 可以 | 通常不可以 | 关闭主要密码认证路径 |
| 同时关闭密码与键盘交互认证 | 可以 | 不可以 | 进一步避免通过交互式认证绕回密码 |
| 再限制 root、账户和来源 | 可以 | 不可以 | 暴露面和可尝试账户进一步减少 |
很多人看到客户端提示 Authenticated to ... using "publickey",就认为密码暴力破解已经被阻止。这个提示只能证明本次连接使用了密钥,不能证明服务器不会接受下一次密码登录。
更可靠的判断需要同时满足以下条件:
- 运行中的 SSH 服务实际采用
PasswordAuthentication no。 - 运行中的 SSH 服务实际采用
KbdInteractiveAuthentication no,避免通过键盘交互或 PAM 继续询问密码。 - 目标账户使用指定私钥可以登录。
- 禁止密钥认证后,强制密码认证的测试连接不能完成认证,也不应正常出现密码提示。
- 配置变更后的日志中没有新的
Accepted password。 - 目标端口、目标地址和实际运行的 SSH 服务与测试对象一致。
这里的“实际采用”很重要。/etc/ssh/sshd_config 中看到一行配置,不一定等于最终生效结果,因为 Include 文件、Match 条件、不同监听实例或服务启动参数都可能改变判断。
“彻底杜绝”只能限定在 SSH 密码认证入口
当 SSH 服务明确只接受公钥认证时,攻击者即使知道用户名,也不能再通过猜测账户密码完成该 SSH 登录。此时可以说,该 SSH 服务的密码暴力破解路径被关闭。
但以下风险仍然不属于这个结论的覆盖范围:
- 私钥文件被窃取,且私钥没有口令保护;
- 私钥口令过于简单,或私钥长期暴露在不安全设备上;
- 攻击者已经通过密钥登录并保持了现有会话;
- 服务器面板、应用后台、数据库或其他服务仍允许密码登录;
- SSH 允许不必要的高权限账户登录;
- 使用了多个 SSH 实例,只修改了其中一个实例的配置;
- SSH 服务本身存在漏洞,或者系统账户权限配置过宽。
所以,验证结果应当写成“SSH 密码认证入口已关闭”或“密码猜测无法通过该 SSH 服务完成”,而不是把所有未授权访问风险都归因于密码暴力破解。
密钥登录降低风险的工作机制
密码认证与公钥认证的区别
密码认证通常是服务器向客户端发起密码验证,攻击者可以不断尝试不同的密码组合。即使每次尝试都有延迟,暴露在公网的 SSH 端口仍可能收到大量自动化扫描。
公钥认证的流程不同:
- 客户端持有私钥,服务器只保存对应的公钥。
- 服务器向客户端发送一次性认证数据。
- 客户端使用私钥对数据进行签名。
- 服务器使用
authorized_keys中的公钥验证签名。 - 私钥本身不会传到服务器。
因此,攻击者不能通过猜测普通账户密码来通过公钥认证。攻击者若想伪造登录,通常需要获得对应私钥,或利用账户、SSH 服务、系统权限等其他薄弱环节。
需要注意,密钥认证并不意味着客户端绝对不会提示输入内容。如果私钥设置了口令,SSH 客户端可能会在本地要求输入私钥口令。这是保护私钥的措施,不是服务器账户密码认证。只要输入过程发生在本地,且服务器没有启用密码认证,就不会重新打开 SSH 密码暴力破解入口。
需要重点检查的配置项
常见的全局配置可以参考下面的逻辑。不要直接重复追加同名配置,先检查现有配置、Include 文件和 Match 区块,再修改对应项目。
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
这些配置的含义如下:
PubkeyAuthentication yes:允许公钥认证。PasswordAuthentication no:关闭传统密码认证。KbdInteractiveAuthentication no:关闭键盘交互认证,减少通过 PAM 等交互方式绕回密码验证的可能。PermitRootLogin no:完全禁止 root 直接通过 SSH 登录。若业务确实需要 root 密钥登录,prohibit-password只代表禁止 root 使用密码,仍然允许 root 使用密钥,不能与no混为一谈。
某些较旧的 OpenSSH 配置中还可能出现:
ChallengeResponseAuthentication no
该配置在不同版本中可能处于兼容或弃用状态。不要只根据文件中的配置名判断结果,应以 sshd -T 输出的实际生效值为准。如果手动加入配置后检查失败,应先修正语法,而不是直接重启服务。
在确认所有需要 SSH 登录的账户都已完成密钥配置后,也可以考虑使用:
AuthenticationMethods publickey
它要求该认证链包含公钥认证。这个选项不适合在密钥尚未验证、仍依赖密码登录的阶段直接启用,否则可能把管理员锁在服务器外。配置修改前应保留当前登录会话,并准备第二个测试会话或服务器控制台作为回退入口。
配置完成后的验证流程
1. 先确认账户、端口和配置文件
验证前,先确认当前操作账户和正在使用的目标地址。不要在无法确认目标服务器的情况下修改 SSH 配置。
whoami
hostname
echo "$SSH_CONNECTION"
sudo ss -lntp | grep -E 'ssh|:22'
SSH_CONNECTION 通常可以看到当前连接的来源地址、来源端口、目标地址和目标端口。实际测试时,要使用与生产登录相同的账户、域名或 IP、端口和地址族。
如果服务器同时监听 IPv4 和 IPv6,或域名同时解析到两种地址,建议分别验证。某一个地址能够使用密钥登录,不代表另一个监听入口也采用了相同配置。
先备份 SSH 配置。备份本身不会改变服务状态,但配置备份文件应限制访问权限:
sudo cp -a /etc/ssh/sshd_config \
"/etc/ssh/sshd_config.bak.$(date +%Y%m%d-%H%M%S)"
sudo chmod 600 /etc/ssh/sshd_config.bak.*
如果系统实际使用的是其他配置文件或多个 sshd 实例,应先通过服务定义确认配置路径:
systemctl cat ssh 2>/dev/null
systemctl cat sshd 2>/dev/null
上面的两个命令可能只有一个存在。重点是确认正在监听目标端口的服务,不要只修改一个没有被使用的配置文件。
2. 检查密钥文件和账户权限
在客户端生成密钥时,可以使用当前 OpenSSH 通常支持的 Ed25519 密钥:
ssh-keygen -t ed25519 -a 100 \
-f ~/.ssh/id_ed25519_hk \
-C "admin@hongkong-server"
-f 指定私钥保存路径,.pub 文件是对应的公钥。私钥应保留在客户端,不要上传到服务器。建议为私钥设置口令;这不会影响服务器端使用公钥认证,只会在本地保护私钥。
将公钥放入目标账户的 authorized_keys 后,检查文件权限。下面的命令应在目标账户环境中执行,或者明确替换为实际账户路径:
stat -c '%U:%G %a %n' ~/.ssh ~/.ssh/authorized_keys
常见的权限参考值是:
~/.ssh 700
~/.ssh/authorized_keys 600
如果权限或所有者确实不正确,再进行修正。修改前应确认路径属于目标账户,避免误改其他账户文件:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
查看公钥指纹时,可以在客户端执行:
ssh-keygen -lf ~/.ssh/id_ed25519_hk.pub
也可以在服务器上查看 authorized_keys 中对应公钥的指纹,确认安装的不是另一把密钥。若密钥登录失败,权限、所有者、家目录路径和公钥内容通常比网络线路更值得优先检查。
3. 查看 SSH 服务的实际生效配置
不要只使用 grep /etc/ssh/sshd_config 判断。先让 SSH 守护进程输出解析后的有效配置:
sudo sshd -T | grep -Ei \
'^(pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|challengeresponseauthentication|permitrootlogin|authenticationmethods) '
如果系统找不到 sshd 命令,可以先确认路径:
command -v sshd
典型的有效结果可能类似:
pubkeyauthentication yes
passwordauthentication no
kbdinteractiveauthentication no
permitrootlogin no
如果启用了 AuthenticationMethods,还可能看到:
authenticationmethods publickey
这里的结果只是全局配置视角。若配置中包含按用户、来源地址或主机匹配的 Match 区块,还要带上实际连接条件检查。例如,目标账户是 admin,当前客户端公网地址为 203.0.113.25,可以使用类似命令:
sudo sshd -T -C \
user=admin,addr=203.0.113.25,host=server.example \
| grep -Ei \
'^(pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|challengeresponseauthentication|permitrootlogin|authenticationmethods) '
命令中的账户、来源地址和主机名必须替换为真实值。-C 的作用是让 sshd 根据连接条件计算 Match 规则。如果带条件和不带条件的结果不同,应以与实际登录条件相符的结果为准。
重点关注以下结果:
passwordauthentication no:传统密码认证关闭。kbdinteractiveauthentication no:键盘交互认证关闭。pubkeyauthentication yes:公钥认证仍可用。permitrootlogin no:root 不允许直接登录。permitrootlogin prohibit-password:root 仍可使用密钥登录,只是不能使用密码。
如果输出仍为 passwordauthentication yes,不要继续用日志数量推测风险已经降低,应先找出配置覆盖来源。
4. 修改配置并先做语法检查
确认公钥登录已经在第二个会话中测试成功后,再调整服务端配置。编辑配置时,重点是修改现有有效项,不要在文件末尾盲目堆叠同名设置:
sudoedit /etc/ssh/sshd_config
配置修改完成后,先检查语法:
sudo sshd -t -f /etc/ssh/sshd_config
没有任何输出通常表示语法检查通过。如果出现错误,先不要重载服务,按报错行号修正。常见原因包括拼写错误、配置项不受当前版本支持、Match 区块位置不正确,或者 Include 文件中的配置有问题。
语法检查通过后,再根据系统实际服务名重载配置。Debian、Ubuntu 等系统常见服务名为 ssh,部分其他发行版常见服务名为 sshd:
sudo systemctl reload ssh
如果系统没有 ssh.service,应使用:
sudo systemctl reload sshd
重载通常不会主动断开已经建立的 SSH 会话,但新连接会采用新配置。不要在唯一的 SSH 会话中直接执行未经检查的 restart,否则配置错误可能导致新连接无法建立。若配置修改不符合预期,可以使用备份回滚:
sudo cp -a /etc/ssh/sshd_config.bak.YYYYMMDD-HHMMSS \
/etc/ssh/sshd_config
sudo sshd -t -f /etc/ssh/sshd_config
sudo systemctl reload ssh
回滚文件名需要替换成实际备份文件,且回滚前仍应保留当前会话和可用的控制台入口。
5. 用客户端分别验证“密钥能进”和“密码不能进”
先从另一个终端测试密钥登录:
ssh -p 22 \
-o IdentitiesOnly=yes \
-i ~/.ssh/id_ed25519_hk \
admin@server.example
如果 SSH 使用了其他端口,应替换 -p 22。IdentitiesOnly=yes 可以避免客户端自动尝试其他密钥,便于确认这次登录确实使用了指定私钥。
成功时,可以使用调试模式观察认证过程:
ssh -vv \
-p 22 \
-o IdentitiesOnly=yes \
-i ~/.ssh/id_ed25519_hk \
admin@server.example
重点看是否出现类似信息:
Offering public key: ...
Server accepts key: ...
Authenticated to ... using "publickey"
不同 OpenSSH 版本的文字可能略有差异。调试输出只建议在本地查看,不要把其中的用户名、地址、主机指纹或路径直接公开。
然后强制客户端不使用公钥,只尝试密码认证:
ssh -p 22 \
-o PubkeyAuthentication=no \
-o KbdInteractiveAuthentication=no \
-o PreferredAuthentications=password \
-o NumberOfPasswordPrompts=1 \
admin@server.example
在密码认证已经关闭的情况下,预期结果是连接无法完成认证,通常会直接显示只剩公钥等认证方式,或出现类似:
Permission denied (publickey).
不同系统可能显示不同的认证方式列表。关键判断点有两个:
- 不应正常进入密码输入流程;
- 不应使用账户密码建立 SSH 会话。
如果仍然出现密码提示,不要继续输入真实密码。应立即回到 sshd -T -C 检查实际生效配置,重点排查 Match 区块、Include 文件、多个 SSH 实例和实际测试端口是否一致。
6. 检查重载之后的日志
日志可以帮助确认实际发生了什么,但不能单独替代配置检查。应从配置重载之后的时间开始观察,不要把旧日志中的密码失败记录当成当前状态。
使用 systemd 日志的系统,可以查看对应服务:
sudo journalctl -u ssh --since "10 minutes ago" --no-pager
如果服务名是 sshd:
sudo journalctl -u sshd --since "10 minutes ago" --no-pager
部分系统使用文本日志,常见位置包括:
sudo grep -E \
'Accepted password|Accepted publickey|Failed password|Failed publickey|Invalid user' \
/var/log/auth.log | tail -n 50
如果不存在 /var/log/auth.log,也可能需要查看 /var/log/secure。日志项目可以按下面方式理解:
| 日志内容 | 通常代表的含义 | 对本次验证的判断 |
|---|---|---|
Accepted publickey | 某账户通过公钥认证成功 | 证明密钥路径可用 |
Accepted password | 某账户通过密码认证成功 | 说明密码入口仍未关闭 |
Failed password | 有连接尝试密码认证但失败 | 重载后持续出现,需检查配置 |
Failed publickey | 有连接尝试公钥认证但失败 | 不是密码暴力破解,可能是扫描或错误密钥 |
Invalid user | 尝试了不存在的用户名 | 属于账户探测,不能证明密码认证开启 |
如果重载后仍出现大量 Failed password,而且客户端强制密码测试能够进入密码提示,通常说明密码认证仍然有效,或测试连接实际到达了另一台服务器、另一个端口或另一个 SSH 实例。
如何根据验证结果作出判断
可以将结果分成三种状态。
达到较强判断条件
以下条件同时成立时,可以判断 SSH 密码暴力破解入口已经关闭:
sshd -T对实际账户和来源条件显示passwordauthentication no;kbdinteractiveauthentication no;- 密钥登录成功,且调试信息确认使用的是
publickey; - 禁用公钥后,密码强制测试不能进入认证;
- 重载之后没有新的
Accepted password; - 测试的地址、端口和实际对外服务一致。
这意味着攻击者无法通过不断猜测账户密码来完成该 SSH 服务的登录。公网扫描仍可能继续发生,日志中也可能出现 Invalid user 或 Failed publickey,但它们不表示密码认证仍然开放。
只能判断为部分降低
如果只满足以下情况之一,就不要下“密码风险已关闭”的结论:
- 密钥登录成功,但没有测试密码登录;
- 配置文件写了
PasswordAuthentication no,但sshd -T仍显示yes; - 关闭了
PasswordAuthentication,却保留了键盘交互认证并能弹出密码提示; - 仅禁止了 root 密码登录,普通账户仍允许密码登录;
- 只验证了 IPv4,域名的 IPv6 入口没有验证;
- 只修改了默认配置文件,但目标端口由另一个 SSH 实例监听;
- 日志没有新记录,但服务器没有启用对应认证日志。
“日志里暂时没有失败记录”不等于风险已经消失。攻击者可能尚未发起连接、日志可能被过滤,或者测试根本没有到达目标服务。
出现明确失败信号
以下任何情况都说明需要重新检查:
- 强制密码测试能够输入密码并完成登录;
- 重载后出现
Accepted password; sshd -T显示passwordauthentication yes;- 密钥登录失败,但没有保留可用的第二会话;
sshd -t检查不通过;- 目标账户命中了特殊的
Match User或Match Address配置; - root 仍能使用密钥登录,而原本的安全要求是禁止 root 直接 SSH 登录。
遇到配置语法错误时,不要反复重启 SSH 服务。优先保持现有会话,恢复备份、执行语法检查,再进行重载。
常见配置问题与处理方式
密钥能登录,但密码仍然可用
这通常是因为“增加密钥”被误认为“关闭密码”。先运行:
sudo sshd -T | grep -Ei \
'^(passwordauthentication|kbdinteractiveauthentication|authenticationmethods) '
如果结果不符合预期,检查:
/etc/ssh/sshd_config中是否存在重复配置;Include目录下是否有额外配置;- 目标账户是否命中
Match User; - 来源地址是否命中
Match Address; - 重载的服务是否与监听端口对应;
- 测试连接是否确实连接到目标香港服务器。
不要只修改一行后立即判断结果,必须再次通过 sshd -T 和强制认证测试确认。
密钥登录失败,密码关闭后无法进入
先不要删除现有公钥。检查客户端是否使用了正确私钥:
ssh -vv \
-o IdentitiesOnly=yes \
-i ~/.ssh/id_ed25519_hk \
admin@server.example
服务器端检查:
stat -c '%U:%G %a %n' \
/home/admin/.ssh \
/home/admin/.ssh/authorized_keys
再确认公钥内容没有被截断、换行或复制错误。authorized_keys 通常要求一条公钥占一行,文件所有者应为目标账户,目录和文件权限不能过宽。
如果服务器启用了强制访问控制,权限看似正确仍可能被策略拦截。这时应查看对应系统日志,不能在不了解影响范围的情况下随意关闭安全策略。
以为禁止 root 密码就等于禁止 root 登录
以下两项含义不同:
PermitRootLogin prohibit-password
表示 root 不能用密码登录,但仍可能使用密钥登录。
PermitRootLogin no
表示 root 不能直接通过 SSH 登录。更常见的管理方式是使用普通管理员账户登录,再通过 sudo 执行管理操作。需要注意,关闭 SSH 密码认证不会自动关闭 sudo 对账户密码的要求;这是两个不同的认证场景。
日志里还有大量失败记录
先区分日志类型和时间:
Failed password:说明有密码认证尝试,重载后持续出现需要重点检查;Failed publickey:说明有公钥认证失败,不等同于密码暴力破解;Invalid user:说明有人探测用户名;- 旧时间段的日志:不能代表当前配置。
如果 sshd -T 已显示密码关闭、强制密码测试也不能进入密码认证,但日志仍有旧的 Failed password,那只是历史记录,不应与重载后的时间段混在一起判断。
适用限制与最终判断边界
关闭 SSH 密码认证后,仍应保护私钥。私钥一旦被复制到其他设备,攻击者可能直接使用它登录,尤其是私钥没有本地口令时。建议为私钥设置口令,不要将私钥上传到服务器,也不要把私钥提交到代码仓库或公开共享目录。
还要注意,撤销登录权限不能只靠修改 SSH 配置。已经建立的连接通常不会因为 systemctl reload 自动退出。如果怀疑某把密钥已经泄露,应在保留其他可用管理入口的前提下,从目标账户的 authorized_keys 中移除对应公钥,并检查现有登录会话和相关进程。删除公钥前应先备份文件,避免误删仍在使用的管理员密钥。
对于需要进一步收缩权限的账户,可以在确认业务依赖后,为特定公钥增加来源地址、强制命令、禁止端口转发或禁止代理转发等限制。但这些设置会影响远程运维、部署和转发行为,不应在未确认用途时直接套用。
最终可以用下面的判断链核验结果:
密钥能登录
↓
sshd -T 对实际连接条件显示密码认证关闭
↓
强制密码测试不能进入密码认证
↓
重载后的日志没有 Accepted password
↓
实际端口、地址、账户和 SSH 实例均已确认
只有走完整条链路,才能说明香港服务器的 SSH 密码暴力破解入口已经被有效压缩。密钥登录本身是起点,关闭密码类认证、核对实际生效配置、验证失败路径和检查重载后的日志,才构成可复核的安全判断。



