SSH 密钥登录与安全加固
两类密钥不要混淆
- 用户密钥:私钥留在 WSL2;公钥追加到 VPS 用户的
~/.ssh/authorized_keys。它回答“谁在登录”。 - 主机密钥:私钥留在 VPS 的
/etc/ssh/;客户端在首次连接时保存公钥指纹。它回答“连到的是不是原来那台服务器”。
私钥没有 .pub 后缀,绝不能复制到 VPS、网站或聊天中。需要确认身份时输出公钥指纹:
test -f "$LOCAL_SSH_PUBLIC_KEY"
ssh-keygen -lf "$LOCAL_SSH_PUBLIC_KEY"
安装用户公钥
ssh-copy-id -i "$LOCAL_SSH_PUBLIC_KEY" "$VPS_USER@$VPS_PUBLIC_IPV4"
ssh-copy-id会追加公钥,不应覆盖已有的 authorized_keys。远端权限通常应为:
stat -c '%a %U:%G %n' ~/.ssh ~/.ssh/authorized_keys
# 期望:目录 700,文件 600
明确测试“只用公钥”
普通 ssh 成功可能仍是密码认证。用客户端选项排除密码:
ssh \
-i "$HOME/.ssh/id_ed25519" \
-o IdentitiesOnly=yes \
-o PreferredAuthentications=publickey \
-o PasswordAuthentication=no \
-o KbdInteractiveAuthentication=no \
"$VPS_USER@$VPS_PUBLIC_IPV4"
必须在第二个新会话中通过,同时保留原始已知可用会话。
用配置片段加固 sshd
Ubuntu 支持 /etc/ssh/sshd_config.d/*.conf。OpenSSH 对多数指令采用“获得的第一个值”,而通配符文件名按词法顺序读取。因此较晚的 99-...conf 不一定覆盖较早的 cloud-init 设置;必须检查实际 include 顺序和有效值。
grep -nE '^[[:space:]]*Include|^[[:space:]]*(PermitRootLogin|PasswordAuthentication|KbdInteractiveAuthentication|PubkeyAuthentication|AuthenticationMethods)' \
/etc/ssh/sshd_config
sudo find /etc/ssh/sshd_config.d -maxdepth 1 -type f -print
在确认顺序后创建一个足够早、职责单一的片段,例如:
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
PasswordAuthentication 与 KbdInteractiveAuthentication控制不同的认证方法。在 Ubuntu 上,PAM 的键盘交互认证仍可能要求输入账户密码。AuthenticationMethods publickey 明确要求公钥认证。这套配置用于“只用密钥”的服务器;若现有策略要求额外的键盘交互 MFA,不能原样套用。这里不删除用户或已有公钥。
验证、重载、再验证
sudo sshd -t
sudo sshd -T | grep -E \
'^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|authenticationmethods) '
预期有效值:
permitrootlogin no
passwordauthentication no
kbdinteractiveauthentication no
pubkeyauthentication yes
authenticationmethods publickey
sshd -t 无输出且退出码为 0 才算语法通过。如果配置中有 Match 块,还要用 sudo sshd -T -C user=<login>,addr=<client-ip>,host=<client-hostname> 检查实际登录条件下的有效策略,并替换其中的占位符。全局配置输出不能代替这项条件检查。
上述检查通过后,再执行 sudo systemctl reload ssh 重新加载配置,不需要重启整台 VPS。随后从 WSL2 打开第三个全新公钥会话。
首次连接时的主机指纹
看到 “authenticity can't be established” 时,不要机械输入 yes。可以从已知可信的旧路径读取 VPS 公钥指纹:
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
与客户端提示逐字一致后再接受。系统重装会合理地改变主机密钥;未计划的变化则可能是地址复用、中间人攻击或连错机器。
故障排查
sudo sshd -t
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|authenticationmethods) '
sudo journalctl -fu ssh.service
客户端可增加 -vvv查看协商过程,但日志可能包含用户名、地址和路径,公开前要脱敏。任何新连接失败都应停止防火墙收口,并保留现有会话。