这篇的顺序不能乱:先把密钥登录跑通并验证,再关密码登录,最后开防火墙。每一步都会留一条退路(旧会话不关、控制台在手),做错顺序最坏的结果是把自己锁在机器外面。
下文以 Ubuntu 22.04 / 24.04 为默认假设,sshd 配置项以 OpenBSD 官方手册为准;其他发行版的路径可能不同。
一、首次登录
商家会给一个 IP,以及 root 密码或初始密钥。第一次连会看到主机指纹提示:
ssh root@你的服务器IP
提示 The authenticity of host ... can't be established 时,输入 yes 前先核对指纹。把指纹和商家控制台里显示的做对比——这一步防的是“你以为连的是自己的机器,实际连到了中间人”。指纹对不上就不要输入任何密码。
登录后先做两件事:更新系统和确认有没有普通用户。
apt update && apt upgrade -y
id
如果你后续打算禁用 root 登录,得先有一个能 sudo 的普通用户在。
二、在本机生成密钥对
OpenSSH 现在的默认算法就是 ed25519,官方手册对 -t 的说明里明确写着默认值是 ed25519:
-t Specifies the type of key to create. The possible values are “ecdsa”, “ecdsa-sk”, “ed25519 (the default),” “ed25519-sk”, … or “rsa”.
所以直接生成即可(-C 只是备注,方便你日后分辨是哪台机器的密钥):
ssh-keygen -t ed25519 -C "vps-2026" -a 64
-a 是 KDF 轮数,手册原文说明它决定口令校验的慢速程度,并写明默认 32 轮:
-a rounds … Higher numbers result in slower passphrase verification and increased resistance to brute-force password cracking (should the keys be stolen). The default is 32 rounds.
生成时会问存放路径和 passphrase。passphrase 不是服务器密码,而是给私钥文件本身加密的;设了之后,私钥被拷走也用不了。留着它,别为了省事按空。
生成结果是一对文件:id_ed25519(私钥,留在本机,权限 600)与 id_ed25519.pub(公钥,可以随便发给服务器)。
三、把公钥放到服务器
最省事的写法:
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@你的服务器IP
手工做法等价于:把公钥内容追加到服务器的 ~/.ssh/authorized_keys,并收紧权限。
mkdir -p ~/.ssh && chmod 700 ~/.ssh
cat >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
ssh 对家目录与 authorized_keys 的权限有要求,权限过松会直接拒绝密钥登录——这是“密钥明明放对了却还是要密码”的最常见原因。
四、先验证,再改配置
另开一个终端窗口,用密钥登录:
ssh -i ~/.ssh/id_ed25519 root@你的服务器IP
能进去、且没有提示输入服务器密码,才算这一步成立。原来那个会话先别关。
五、关掉密码登录
要改的项有两个,先在服务器上看清当前值:
grep -RniE "^(PermitRootLogin|PasswordAuthentication)" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/ 2>/dev/null
PermitRootLogin 的官方说明:
Specifies whether root can log in using ssh(1). The argument must be yes, prohibit-password, forced-commands-only, or no. The default is prohibit-password.
If this option is set to prohibit-password (or its deprecated alias, without-password), password and keyboard-interactive authentication are disabled for root.
PasswordAuthentication 的官方说明更短:
Specifies whether password authentication is allowed. The default is yes.
也就是说:想只留密钥登录,就把 PasswordAuthentication 设为 no;root 是否允许登录由 PermitRootLogin 单独决定。如果你的日常账号是普通用户、root 只在密钥下使用,prohibit-password 就够(这也是默认值);想彻底禁止 root 登录才写 no。
改法(先备份):
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
在 /etc/ssh/sshd_config 里写入或修改:
PermitRootLogin prohibit-password
PasswordAuthentication no
KbdInteractiveAuthentication no
KbdInteractiveAuthentication 的官方说明是默认 yes,ChallengeResponseAuthentication 是它的旧别名。密码类认证要关干净,这两项一起看。
关掉了却没生效?先查 Include
sshd_config 支持把别的文件读进来,官方原文:
Include the specified configuration file(s). Multiple pathnames may be specified and each pathname may contain glob(7) wildcards that will be expanded and processed in lexical order. Files without absolute paths are assumed to be in /etc/ssh.
Ubuntu 的默认主配置里就有把 /etc/ssh/sshd_config.d/*.conf 读进来的写法,而云镜像常常在 drop-in 文件里单独写了 PasswordAuthentication yes。这种情况下你改主配置也没用——后读入的值覆盖先读入的。
所以改完先查最终生效值,而不是查文件:
sshd -T | grep -iE "permitrootlogin|passwordauthentication|kbdinteractive"
(sshd -T 的具体行为以你所装版本的 sshd(8) 手册为准。)
确认无误后重启服务:
systemctl restart ssh
注意:重启后不要关掉当前会话,先开新窗口再登一次。失败就回到旧会话改回来,或从商家控制台进。
六、开防火墙
Ubuntu 官方文档给出的启用与放行命令分别是:
To enable ufw, run the following command from a terminal prompt:
$ sudo ufw enable
To open a port (SSH in this case):
$ sudo ufw allow 22
顺序必须是先放行、后启用:
sudo ufw allow 22
sudo ufw enable
sudo ufw status verbose
如果你改过 SSH 端口,这里要放行的是新端口,而不是 22。启用后再开一个新窗口验证一次能否登录——这也是最后一个“可能把自己锁在外面”的位置。
七、收尾检查清单
- 新窗口能用密钥登录,且没有输入服务器密码
-
sudo -v对普通用户生效(如有普通用户) -
sshd -T显示passwordauthentication no -
ufw status显示 active,且只放行了需要的端口 - 商家控制台的 VNC / 救援入口可用(真出事时唯一的退路)
八、锁死了怎么救
按可能性排序:
- 防火墙顺序错:用商家控制台的 VNC 进入,
ufw disable或放行 SSH 端口。 - sshd 配置写错:控制台里恢复备份
sshd_config.bak,再systemctl restart ssh。改配置前跑一次sshd -t做语法检查,能避免大半问题。 - 密钥登录不成立:多半是权限或
authorized_keys路径问题。控制台里检查~/.ssh是否为 700、authorized_keys是否为 600、文件内容是否为完整的一行公钥。
凡是靠控制台救回来的场景,都说明你当时把“验证新登录方式”这一步跳过了。
一句话总结
加固的顺序是:密钥先跑通 → 再关密码 → 最后开防火墙,每次改完都保留旧会话、开新窗口验证。配置是否生效看 sshd -T 的最终值,而不是你改的那个文件。