本页目录
任何对互联网开放 SSH 的服务器都会全天候遭受自动化的密码猜测攻击。使用基于密钥的认证后,这些尝试都将徒劳无功:服务器只接受持有您私钥的人登录。本指南先配置密钥,再禁用密码登录,同时确保出现问题时您仍有办法重新登录。
生成密钥对
请使用 Ed25519:这种密钥短小、速度快,且所有当前版本的 OpenSSH 都支持。请在您自己的电脑上创建密钥对,切勿在服务器上创建。
Linux 和 macOS
ssh-keygen -t ed25519 -C "you@laptop"接受默认位置 ~/.ssh/id_ed25519,并设置密码短语。密码短语用于加密存储在磁盘上的私钥;借助 SSH 代理(agent),每个会话只需输入一次,而不必每次连接都输入。在 macOS 上,ssh-add --apple-use-keychain ~/.ssh/id_ed25519 会将其存入钥匙串。
Windows 10 和 11
系统已内置 OpenSSH 客户端。在 PowerShell 中运行:
ssh-keygen -t ed25519 -C "you@laptop"私钥保存为 %USERPROFILE%\.ssh\id_ed25519,公钥则保存在同一目录下的 id_ed25519.pub。如需使用代理(agent),请在以管理员身份运行的 PowerShell 中执行一次 Get-Service ssh-agent | Set-Service -StartupType Automatic,然后运行 Start-Service ssh-agent 和 ssh-add。
提示:如果您有 FIDO2 安全密钥,ssh-keygen -t ed25519-sk 可以创建一个每次登录时还需触碰该设备的密钥。
只有 .pub 文件才可以离开您的电脑。如果私钥被复制到不该存放的地方,请将其视为已泄露并予以更换。
在服务器上安装公钥
示例使用账户 deploy(在入门步骤中创建)和地址 203.0.113.10。如果使用 root,请改用 root@。
使用 ssh-copy-id(Linux 和 macOS)
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@203.0.113.10它会使用账户密码登录一次,并将密钥追加到服务器上的 ~/.ssh/authorized_keys 中;如果目录和文件尚不存在,它会以安全的权限创建它们。
在 Windows 上或手动安装
Windows 没有 ssh-copy-id。以下 PowerShell 命令可以完成同样的操作:
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh deploy@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"您也可以将 .pub 文件的内容作为单独一行,粘贴到服务器上 ~/.ssh/authorized_keys 的末尾。
检查权限
如果密钥所在的文件可被其他用户写入,sshd 会忽略这些密钥。在服务器上,以将要登录的用户身份运行:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
ls -ld ~ ~/.ssh ~/.ssh/authorized_keys主目录同样不能对同组用户或所有用户可写。在 AlmaLinux 和 Rocky Linux 上,如果您手动创建或移动过这些文件,请运行 restorecon -Rv ~/.ssh,以便 SELinux 允许 sshd 读取它们。
现在使用 ssh deploy@203.0.113.10 登录。如果系统要求输入密钥的密码短语,或者什么都不要求,说明密钥有效。如果要求输入账户密码,说明密钥无效:请先解决该问题再继续。ssh -v 会显示客户端提供了哪些密钥,以及服务器如何响应。
禁用密码认证
本部分请以 root 身份运行(sudo -i)。当前版本的 Ubuntu、Debian、AlmaLinux 和 Rocky Linux 都会在 sshd_config 的开头引入 /etc/ssh/sshd_config.d/ 中的所有 *.conf 文件。对于大多数设置,sshd 会采用其读取到的第一个值,因此文件名排序最靠前的 drop-in 配置文件优先生效。使用编辑器创建 /etc/ssh/sshd_config.d/00-keys-only.conf:
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-passwordprohibit-password 仍允许 root 使用密钥登录。当您只以 sudo 用户身份登录后,请改用 PermitRootLogin no。检查是否存在可能冲突的旧设置,然后验证配置:
grep -ri -E 'passwordauthentication|permitrootlogin' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/
sshd -t配置有效时,sshd -t 不会输出任何内容。某些镜像自带 50-cloud-init.conf 之类的文件,其中设置了 PasswordAuthentication yes;00- 前缀可确保您的文件优先生效,但删除旧的那一行可以避免日后混淆。应用更改;已打开的会话不会中断:
systemctl reload ssh在 AlmaLinux 和 Rocky Linux 上,服务名为 sshd:systemctl reload sshd。然后检查 sshd 实际使用的值:
sshd -T | grep -E '^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin)'您应该看到 passwordauthentication no。prohibit-password 可能会以其旧名称 without-password 显示。
退出登录前在第二个会话中测试
警告:在下面的测试成功之前,请保持当前 SSH 会话处于打开状态。它是您的安全保障:通过它,您仍然可以撤销更改。
打开一个新终端,使用密钥登录。
ssh deploy@203.0.113.10必须能够成功登录。确认密码登录会被拒绝。强制使用密码认证:
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password deploy@203.0.113.10预期的响应为
Permission denied (publickey).确认无误后,再关闭原来的会话。
如果第一步失败,请在仍处于打开状态的会话中删除 00-keys-only.conf,重新加载 sshd,然后再次检查密钥和权限。
使用 SSH 配置别名减少输入
在您的电脑上,向 ~/.ssh/config(Windows 上为 %USERPROFILE%\.ssh\config)添加一个条目:
Host web1
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes现在只需输入 ssh web1 即可连接,而且通过 SSH 运行的工具(例如 scp、rsync 和 git)也接受同一别名。IdentitiesOnly yes 可以阻止客户端逐一提供代理中的所有密钥,从而避免出现“Too many authentication failures”错误。
无法登录?使用 IPMI 控制台恢复
sshd 的设置只对网络登录生效。本地控制台仍然接受 root 密码,因此 IPMI/KVM 控制台就是您重新进入系统的途径:
打开控制台。在控制面板中打开该服务器,然后选择“控制台(IPMI)”。
以 root 身份登录,使用 root 密码。
撤销更改并重新加载 sshd(在 AlmaLinux 和 Rocky Linux 上为
sshd):mv /etc/ssh/sshd_config.d/00-keys-only.conf /root/ systemctl reload ssh修复问题根源(通常是缺少密钥或权限错误),然后将该文件放回原处。
控制台登录需要密码,因此没有设置密码的 root 账户无法在控制台登录。如果服务器安装时只配置了 SSH 密钥,就可能出现这种情况。请立即使用 passwd 设置一个强 root 密码,并将其保存在密码管理器中:SSH 仍会拒绝密码登录,但控制台会接受该密码。如果没有密码,请使用救援模式设置密码或修复文件。
后续步骤
接下来请继续阅读服务器加固。如果您还要将 SSH 改到其他端口,请先在防火墙中放行新端口。在 Ubuntu 上,请检查 systemctl status ssh.socket:如果 socket 单元处于活动状态,更改端口后还需要执行 systemctl daemon-reload 和 systemctl restart ssh.socket。
仍未解决?请在技术支持页面提交工单,并附上 ssh -v 的输出。