SSH 密钥化改造:先保住退路再关密码登录

举报
逍遥渝枫 发表于 2026/11/02 08:36:51 2026/11/02
【摘要】 把云主机从密码登录迁到仅密钥登录,最大的风险不是配错密钥,而是关掉密码登录那一刻把自己锁在门外。本文给出一套保退路的迁移顺序:先在新会话里验证密钥可登录,再确认 authorized_keys 权限、SELinux 或家目录权限没有拦路,最后才关闭 PasswordAuthentication。附 Ubuntu 22.04 上实测的 sshd 配置、常见报错对照表和失败时的回退办法,适合准备动手加

很多服务器入侵的起点都是同一个:SSH 密码登录开着,root 弱口令被爆破成功。把登录方式收敛到仅密钥,是性价比最高的一步加固。但真动手时最常见的翻车姿势是——改完 sshd_config、重启 sshd,密钥没配对,密码登录也关了,云控制台的 VNC 成了唯一的救命通道。

所以这套改造的核心原则只有一条:**每一步都留着退路,确认下一步真的能进,再收掉上一步的退路。**以下步骤在 Ubuntu 22.04 上验证过,其他发行版路径可能不同(比如 CentOS 的 sshd 配置位置和 SELinux 策略),需自行确认。

第一步:生成密钥并送达服务器

本地是 Windows 的话用 PowerShell 自带的 OpenSSH 即可:

ssh-keygen -t ed25519 -C "ops-laptop-2026"

把公钥送到服务器,不要手动复制粘贴(容易丢换行或结尾的注释):

ssh-copy-id -i ~/.ssh/id_ed25519.pub root@121.37.39.242

如果这台机器已经禁用了密码登录(比如接手别人加固过的机器),ssh-copy-id 会失败,此时用另一个渠道把公钥内容追加进 /root/.ssh/authorized_keys,注意一个公钥占一行。

第二步:验证密钥登录,而且要开新会话验证

这一步很多人偷懒:在当前已登录的会话里测一下就以为没问题。错。当前会话的登录态和你要验证的「全新连接」是两回事。正确做法是另开一个终端,强制走密钥试一次:

ssh -i ~/.ssh/id_ed25519 -o PasswordAuthentication=no root@121.37.39.242

-o PasswordAuthentication=no 强制客户端不回退到密码,能提前暴露「密钥根本没生效」的问题。能进去,第一步才算过关。

第三步:排查权限——密钥被拒的头号原因

如果上一步报 Permission denied (publickey),九成不是密钥内容错了,而是权限。sshd 对权限的检查非常严格,对照排查:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R root:root /root/.ssh
ls -ld /root /root/.ssh /root/.ssh/authorized_keys

注意最后一列的输出:家目录本身不能是 777,也不能归属别人。sshd 默认配置下(StrictModes yes),只要 authorized_keys、.ssh 目录或家目录任何一级权限过宽或属主不对,公钥认证直接静默拒绝,日志里才会留痕。看日志定位:

journalctl -u ssh -n 50 --no-pager | grep -i "authentication"

常见的两条:Authentication refused: bad ownership or modes 就是权限问题;userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms 说明还在用老的 RSA 密钥且服务端算法收紧了,换 ed25519 最省事。

第四步:修改 sshd 配置,用 include 意识避开覆盖

Ubuntu 22.04 的 /etc/ssh/sshd_config 末尾有一行 Include /etc/ssh/sshd_config.d/*.conf,而云厂商镜像常在这里预置了 50-cloud-init.conf 之类带 PasswordAuthentication yes 的文件。Include 的文件先于主文件生效,你改主文件里的 PasswordAuthentication 可能不生效。稳妥做法是新建一个数字更大的覆盖文件:

printf 'PasswordAuthentication no\nPermitRootLogin prohibit-password\nPubkeyAuthentication yes\n' > /etc/ssh/sshd_config.d/60-hardening.conf
sshd -t && systemctl restart ssh

sshd -t 先做语法检查再重启,避免配置写错导致 sshd 起不来。Ubuntu 22.04 上服务名是 ssh(个别系统是 sshd),用 systemctl status ssh 确认。

第五步:不退出,用新会话做最终验证

改完配置后不要退出当前会话。另开一个新终端再连一次,确认密钥登录正常、密码登录已被拒:

ssh -o PreferredAuthentications=password root@121.37.39.242
# 期望输出:Permission denied (publickey).  ← 注意括号里只剩 publickey,说明密码通道已关

看到 (publickey) 单独出现,说明密码认证已经彻底关闭;此时新会话的密钥登录成功,改造完成,旧会话可以放心退出。

报错对照表

现象 原因 处理
Permission denied (publickey),但密钥没配错 .ssh 或家目录权限/属主不对 700/600 + chown,查 StrictModes
bad ownership or modes 日志 同上,sshd 静默拒绝 同上
key type ssh-rsa not in PubkeyAcceptedAlgorithms 老 RSA 算法被收紧 换 ed25519 密钥
改了主配置密码登录还能用 sshd_config.d 里 Include 文件优先级更高 建 60-xxx.conf 覆盖
重启 sshd 后服务起不来 配置语法错误 重启前先 sshd -t
全都配对仍拒绝 fail2ban 把你 IP 封了 fail2ban-client status sshd 查

真被锁死了怎么办

最后留个底:如果以上全踩坑、密钥密码都进不去,用云厂商控制台的 VNC 救援登录(这也是为什么密码要留一份给 VNC 应急,而不是彻底丢弃)。进去后先看 /etc/ssh/sshd_config.d/ 里的覆盖文件,把 PasswordAuthentication no 临时改回 yes 并 systemctl restart ssh,恢复密码通道后再按上面的顺序重来。整个过程只要严格走「新会话验证再收退路」的节奏,走到锁死这一步的概率很低。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。