本页内容
SSH 密钥比密码更安全,用起来也更快捷。本文介绍如何在本地电脑上创建密钥、将其复制到 FlexDedi 服务器,再在不把自己锁在门外的前提下关闭密码登录。
开始之前,需要准备服务器的 IPv4 地址和 root 密码,两者都显示在控制面板的服务器信息中。示例使用 203.0.113.10,请替换为实际地址。
准备工作
Linux、macOS、Windows 10 和 11,以及 Windows Server 2019 及更高版本均已预装 OpenSSH。在 Windows 上,可以在 PowerShell 中运行 ssh -V 检查。如果提示找不到该命令,请在管理员权限的 PowerShell 中安装客户端:
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.01. 创建密钥对
在 Linux 或 macOS 终端和 Windows PowerShell 中,命令完全相同:
ssh-keygen -t ed25519 -C "alice@laptop"保存位置使用默认值即可,并为私钥设置密码(passphrase)。私钥(id_ed25519)始终保存在本地电脑上:Linux 和 macOS 位于 ~/.ssh,Windows 位于 C:\Users\alice\.ssh。只有公钥(id_ed25519.pub)需要放到服务器上。
2. 将公钥复制到服务器
在 Linux 和 macOS 上,ssh-copy-id 会最后一次询问 root 密码,并以正确的权限追加公钥:
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@203.0.113.10Windows 没有 ssh-copy-id,可以改为通过 SSH 管道传输公钥:
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | ssh root@203.0.113.10 "umask 077; mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"然后确认密钥可用。正常情况下,无需输入密码即可直接进入 shell:
ssh -i ~/.ssh/id_ed25519 root@203.0.113.103. 将密钥加入 ssh-agent
ssh-agent 会记住已解锁的私钥,每个会话只需输入一次私钥密码。在 Linux 上,运行 ssh-add ~/.ssh/id_ed25519。在 macOS 上,ssh-add --apple-use-keychain ~/.ssh/id_ed25519 还会将私钥密码存入钥匙串。
在 Windows 上,先在管理员权限的 PowerShell 中启用 ssh-agent 服务(只需操作一次),然后添加密钥:
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed255194. 在 ~/.ssh/config 中保存服务器
添加主机条目后,就能用一个简短的名称代替冗长的命令行。将以下内容添加到 ~/.ssh/config(Windows 上为 C:\Users\alice\.ssh\config,语法相同):
Host fd-db1
HostName 203.0.113.10
User root
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
ServerAliveInterval 30现在运行 ssh fd-db1 即可连接,该名称同样适用于 scp 和 rsync,例如 rsync -a ./site/ fd-db1:/srv/site/。IdentitiesOnly yes 可以阻止客户端逐一尝试 ssh-agent 中的所有密钥,否则可能出现「Too many authentication failures」错误。
5. 安全地禁用密码登录
开放密码登录容易招来暴力破解。确认密钥登录可用后,请按以下顺序关闭密码登录。
步骤 1:保持当前 SSH 会话不要断开,在第二个终端中确认密钥登录正常。
步骤 2:创建一个仅允许密钥登录的 drop-in 配置文件:
cat > /etc/ssh/sshd_config.d/00-keys-only.conf <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
EOF00- 前缀很关键。在 Ubuntu、Debian、AlmaLinux 和 Rocky Linux 上,引入该目录的 Include 行位于 /etc/ssh/sshd_config 的开头,而 sshd 对每项设置只采用最先读到的值。因此先读取的文件优先生效,即使 50-cloud-init.conf 启用了密码登录也不例外。
步骤 3:校验配置,并输出 sshd 实际使用的设置:
sshd -t && sshd -T | grep -Ei '^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin)'预期输出依次为 no、no 和 without-password,后者是 prohibit-password 的旧名称。
步骤 4:重启服务。已打开的会话不会断开:
# Ubuntu and Debian
systemctl restart ssh
# AlmaLinux and Rocky Linux
systemctl restart sshd步骤 5:在本地电脑上确认密码登录已被拒绝:
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password root@203.0.113.10预期会返回 Permission denied (publickey). 这一提示。即便如此,仍应保留一个高强度的 root 密码:KVM 控制台不经过 SSH,在那里密码依然有效,这是重新进入服务器的退路。
6. 通过 KVM 控制台恢复访问
丢失密钥、防火墙规则封锁了 22 端口、被 fail2ban 封禁,或 sshd 配置文件损坏,都可能导致无法登录。KVM 控制台不经过网络和 SSH,可以直接操作服务器的屏幕和键盘。
- 在控制面板中打开服务器,启动 KVM 控制台。
- 使用密码以
root身份登录。 - 排查原因:
sshd -t # syntax errors in the configuration
journalctl -u ssh -n 50 --no-pager # use -u sshd on AlmaLinux and Rocky Linux
chmod 700 /root/.ssh && chmod 600 /root/.ssh/authorized_keys
ufw status verbose # or: nft list ruleset
fail2ban-client set sshd unbanip 198.51.100.7 # your workstation's IP, if banned如需安装新密钥,最简单的方法是:在 drop-in 配置文件中设置 PasswordAuthentication yes,重启 SSH,从本地电脑运行 ssh-copy-id,然后再改回 no。
如果连 root 密码也忘了,可以启动救援系统,在其中添加密钥或重置密码,详见重装系统或进入救援模式。控制台本身的用法见使用 IPMI 和 HTML5 KVM 控制台。
重装后的主机密钥警告
重装系统会生成新的主机密钥,因此客户端会警告远程主机标识已更改。如果刚刚重装过系统,删除旧记录后重新连接即可:
ssh-keygen -R 203.0.113.10如果并未重装,请不要绕过该警告,而应先通过 KVM 控制台核对指纹,方法见快速入门。