如何设置 SSH 密钥登录禁用密码验证提升安全?

文章导读
设置 SSH 密钥登录并禁用密码验证的核心操作是生成密钥对、将公钥部署到服务器、测试密钥登录成功后,修改 `/etc/ssh/sshd_config` 将 `PasswordAuthentication` 设为 `no`。此操作适用于 Linux 服务器安全加固,风险边界在于一旦密钥失效且密码禁用,若无控制台访问权限将无法登录服务器。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

设置 SSH 密钥登录并禁用密码验证的核心操作是生成密钥对、将公钥部署到服务器、测试密钥登录成功后,修改 `/etc/ssh/sshd_config` 将 `PasswordAuthentication` 设为 `no`。此操作适用于 Linux 服务器安全加固,风险边界在于一旦密钥失效且密码禁用,若无控制台访问权限将无法登录服务器。

先说结论:启用密钥认证并关闭密码认证是服务器安全基线配置,但必须在确认密钥登录无误后执行关闭密码操作。

  • 先判断:确认拥有服务器控制台(VNC/物理)访问权限,以防密钥配置失误导致锁死。
  • 优先做:生成 Ed25519 或 RSA 密钥对,并将公钥写入服务器 `~/.ssh/authorized_keys`。
  • 再验证:保持当前 SSH 会话开启,新开终端测试密钥登录成功后,再修改配置禁用密码。

命令速用版

以下命令适用于大多数 Linux 发行版,需在本地终端生成密钥,然后在服务器端修改配置。

# 1. 本地生成密钥(推荐 Ed25519)
ssh-keygen -t ed25519 -C "your_email@example.com"

# 2. 复制公钥到服务器
ssh-copy-id user@server_ip

# 3. 服务器端编辑配置
sudo vim /etc/ssh/sshd_config

# 4. 修改以下项
PasswordAuthentication no
PubkeyAuthentication yes

# 5. 重载服务
sudo systemctl restart sshd

为什么会这样

密码验证容易受到暴力破解和字典攻击,而密钥认证基于非对称加密,私钥不通过网络传输。

SSH 协议支持多种认证方式,密码认证依赖用户记忆的秘密字符串,容易被自动化脚本猜测。密钥认证依赖本地持有的私钥文件,攻击者无法通过截获网络流量还原私钥。禁用密码验证能直接阻断基于密码的暴力破解尝试,减少日志噪音和潜在入侵风险。

分步处理

按顺序执行以下步骤,每一步都有检查点,确保不会因配置错误导致无法登录。

步骤 1:生成密钥对
在本地电脑终端运行 `ssh-keygen`。建议选择不设置 passphrase 以便自动化脚本使用,或设置 passphrase 提高安全性。默认路径通常为 `~/.ssh/id_ed25519`。

步骤 2:部署公钥
使用 `ssh-copy-id user@server_ip` 自动将公钥追加到服务器 `~/.ssh/authorized_keys`。若手动复制,需确保文件权限为 600,目录 `.ssh` 权限为 700。

步骤 3:测试密钥登录
打开一个新的终端窗口,尝试 `ssh user@server_ip`。确认不需要输入密码即可登录。此时不要关闭旧的 SSH 会话,作为应急回滚通道。

步骤 4:修改服务端配置
登录服务器后,编辑 `/etc/ssh/sshd_config`。找到 `PasswordAuthentication` 行,改为 `no`。确保 `PubkeyAuthentication` 为 `yes`。若禁止 root 远程登录,同时设置 `PermitRootLogin prohibit-password` 或 `no`。

步骤 5:重启 SSH 服务
执行 `sudo systemctl restart sshd` 或 `sudo service ssh restart`。若配置语法错误,服务可能启动失败,此时可立即通过旧会话修复。

怎么验证是否生效

通过配置检查和登录行为测试确认密码验证已关闭。

检查配置生效:
在服务器运行 `sudo sshd -T | grep passwordauthentication`,输出应为 `passwordauthentication no`。

测试密码被拒:
在本地新建终端,使用 `-o PreferredAuthentications=password -o PubkeyAuthentication=no` 参数强制使用密码登录,连接应被拒绝或提示 Permission denied。

如何设置 SSH 密钥登录禁用密码验证提升安全?

查看日志:
检查 `/var/log/auth.log` 或 `/var/log/secure`,确认登录记录显示 `Publickey` 而非 `Password`。

常见坑

操作过程中容易因权限或配置细节导致登录失败,需注意以下边界。

1. 文件权限错误
服务器端 `~/.ssh` 目录权限必须是 700,`authorized_keys` 必须是 600。权限过宽会导致 SSH 服务端忽略密钥文件。

2. SELinux 限制
在 CentOS/RHEL 等开启 SELinux 的系统,若家目录上下文错误,密钥认证可能失败。需确保文件上下文正确,或使用 `restorecon` 修复。

3. 根用户登录限制
若配置了 `PermitRootLogin no`,即使密钥正确也无法登录 root 账户。建议创建普通用户并通过 sudo 提权,而非直接登录 root。

4. 防火墙拦截
修改 SSH 端口后,若未放行新端口防火墙规则,会导致连接超时。修改配置前请先确认防火墙规则。

常见问题

丢失私钥怎么办?

必须通过服务器提供商的控制台(VNC/终端)登录服务器恢复访问。

在控制台登录后,重新生成密钥或临时开启密码验证,将新公钥写入 `authorized_keys`。若无控制台权限,可能需要重装系统。

应该选 RSA 还是 Ed25519?

优先选择 Ed25519,除非需要兼容旧版 SSH 客户端。

Ed25519 密钥更短、安全性更高且生成速度更快。RSA 需至少 3072 位才被认为安全,但部分旧系统可能不支持 Ed25519。

禁用密码后如何切换用户?

使用 `su - username` 切换用户仍需目标用户的密码,与 SSH 登录无关。

若需免密切换,可配置 sudo 规则。SSH 禁用密码仅影响远程登录环节,不影响系统内部用户切换机制。

参考来源

  • OpenSSH 官方文档,sshd_config 手册页,https://www.openssh.com/manual.html
  • Ubuntu 官方文档,SSH/OpenSSH 配置指南,https://ubuntu.com/server/docs/openssh-server
  • CentOS 官方文档,OpenSSH 配置,https://docs.centos.org/en-US/centos-stream/docs/