上一篇 下一篇 分享链接 返回 返回顶部

SSH密钥登录后如何验证香港服务器已降低密码暴力破解风险?

发布人:Minchunlin 发布时间:2026-10-05 13:05 阅读量:23

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

根据全文核心主题形成自然、专业、克制的技术文章主题场景

因此,“免密登录”需要先明确含义:它通常是指服务器不再要求输入账户密码,而不是私钥一定没有口令保护。私钥保留本地口令、服务器端关闭 SSH 密码认证,通常比保存一把无口令私钥更稳妥。验证完成后,可以较有把握地判断“SSH 密码暴力破解入口已关闭”;但不能据此认定私钥泄露、其他服务认证或已经建立的登录会话也不存在风险。

先定义要验证的风险边界

添加密钥与关闭密码认证不是一回事

SSH 服务常见的认证方式包括:

配置状态密钥登录密码登录对密码暴力破解风险的影响
只添加公钥,其他配置不变可以可以风险基本仍在
首选密钥,但允许回退到密码可以可以只改变登录便利性,没有关闭密码入口
关闭 PasswordAuthentication可以通常不可以关闭主要密码认证路径
同时关闭密码与键盘交互认证可以不可以进一步避免通过交互式认证绕回密码
再限制 root、账户和来源可以不可以暴露面和可尝试账户进一步减少

很多人看到客户端提示 Authenticated to ... using "publickey",就认为密码暴力破解已经被阻止。这个提示只能证明本次连接使用了密钥,不能证明服务器不会接受下一次密码登录。

更可靠的判断需要同时满足以下条件:

  1. 运行中的 SSH 服务实际采用 PasswordAuthentication no。
  2. 运行中的 SSH 服务实际采用 KbdInteractiveAuthentication no,避免通过键盘交互或 PAM 继续询问密码。
  3. 目标账户使用指定私钥可以登录。
  4. 禁止密钥认证后,强制密码认证的测试连接不能完成认证,也不应正常出现密码提示。
  5. 配置变更后的日志中没有新的 Accepted password。
  6. 目标端口、目标地址和实际运行的 SSH 服务与测试对象一致。

这里的“实际采用”很重要。/etc/ssh/sshd_config 中看到一行配置,不一定等于最终生效结果,因为 Include 文件、Match 条件、不同监听实例或服务启动参数都可能改变判断。

“彻底杜绝”只能限定在 SSH 密码认证入口

当 SSH 服务明确只接受公钥认证时,攻击者即使知道用户名,也不能再通过猜测账户密码完成该 SSH 登录。此时可以说,该 SSH 服务的密码暴力破解路径被关闭。

但以下风险仍然不属于这个结论的覆盖范围:

  • 私钥文件被窃取,且私钥没有口令保护;
  • 私钥口令过于简单,或私钥长期暴露在不安全设备上;
  • 攻击者已经通过密钥登录并保持了现有会话;
  • 服务器面板、应用后台、数据库或其他服务仍允许密码登录;
  • SSH 允许不必要的高权限账户登录;
  • 使用了多个 SSH 实例,只修改了其中一个实例的配置;
  • SSH 服务本身存在漏洞,或者系统账户权限配置过宽。

所以,验证结果应当写成“SSH 密码认证入口已关闭”或“密码猜测无法通过该 SSH 服务完成”,而不是把所有未授权访问风险都归因于密码暴力破解。

密钥登录降低风险的工作机制

密码认证与公钥认证的区别

密码认证通常是服务器向客户端发起密码验证,攻击者可以不断尝试不同的密码组合。即使每次尝试都有延迟,暴露在公网的 SSH 端口仍可能收到大量自动化扫描。

公钥认证的流程不同:

  1. 客户端持有私钥,服务器只保存对应的公钥。
  2. 服务器向客户端发送一次性认证数据。
  3. 客户端使用私钥对数据进行签名。
  4. 服务器使用 authorized_keys 中的公钥验证签名。
  5. 私钥本身不会传到服务器。

因此,攻击者不能通过猜测普通账户密码来通过公钥认证。攻击者若想伪造登录,通常需要获得对应私钥,或利用账户、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 密码暴力破解入口已经被有效压缩。密钥登录本身是起点,关闭密码类认证、核对实际生效配置、验证失败路径和检查重载后的日志,才构成可复核的安全判断。