跳到主要内容

SSH 密钥登录与安全加固

两类密钥不要混淆​

  • 用户密钥:私钥留在 WSL2;公钥追加到 VPS 用户的 ~/.ssh/authorized_keys。它回答“谁在登录”。
  • 主机密钥:私钥留在 VPS 的 /etc/ssh/;客户端在首次连接时保存公钥指纹。它回答“连到的是不是原来那台服务器”。

私钥没有 .pub 后缀,绝不能复制到 VPS、网站或聊天中。需要确认身份时输出公钥指纹:

[LOCAL: WSL2]
test -f "$LOCAL_SSH_PUBLIC_KEY"
ssh-keygen -lf "$LOCAL_SSH_PUBLIC_KEY"

安装用户公钥​

[LOCAL: WSL2]
ssh-copy-id -i "$LOCAL_SSH_PUBLIC_KEY" "$VPS_USER@$VPS_PUBLIC_IPV4"

ssh-copy-id会追加公钥,不应覆盖已有的 authorized_keys。远端权限通常应为:

[REMOTE: VPS]
stat -c '%a %U:%G %n' ~/.ssh ~/.ssh/authorized_keys
# 期望:目录 700,文件 600

明确测试“只用公钥”​

普通 ssh 成功可能仍是密码认证。用客户端选项排除密码:

[LOCAL: WSL2]
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 顺序和有效值。

[REMOTE: VPS]
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

在确认顺序后创建一个足够早、职责单一的片段,例如:

/etc/ssh/sshd_config.d/00-personal-infra.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey

PasswordAuthentication 与 KbdInteractiveAuthentication控制不同的认证方法。在 Ubuntu 上,PAM 的键盘交互认证仍可能要求输入账户密码。AuthenticationMethods publickey 明确要求公钥认证。这套配置用于“只用密钥”的服务器;若现有策略要求额外的键盘交互 MFA,不能原样套用。这里不删除用户或已有公钥。

验证、重载、再验证​

[REMOTE: VPS]
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 公钥指纹:

[REMOTE: known-good session]
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

与客户端提示逐字一致后再接受。系统重装会合理地改变主机密钥;未计划的变化则可能是地址复用、中间人攻击或连错机器。

故障排查​

[REMOTE: keep known-good session open]
sudo sshd -t
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|authenticationmethods) '
sudo journalctl -fu ssh.service

客户端可增加 -vvv查看协商过程,但日志可能包含用户名、地址和路径,公开前要脱敏。任何新连接失败都应停止防火墙收口,并保留现有会话。

探索关联打开关联网络