VPS首次SSH连接怎么防中间人攻击?cloud-init临时密钥方案详解

新开一台 VPS,第一次 SSH 连接时,客户端会弹出一个著名的警告:

The authenticity of host 'xxx' can't be established.
ECDSA key fingerprint is SHA256:xxxxx.
Are you sure you want to continue connecting (yes/no)?

大多数人会直接输入 yes。但这个步骤其实存在中间人攻击(MitM)风险:如果有人在你和 VPS 之间劫持了 SSH 连接,你可能正在和攻击者的服务器握手,而不是你自己的机器。Joachim Schipper 在博客中详细分析了这个问题,并给出了一个实用的 cloud-init 解决方案。

风险有多大

SSH 的信任模型基于首次连接信任(Trust On First Use, TOFU):第一次连接时,客户端无法验证服务器的指纹,只能选择信任。之后每次连接,客户端会检查服务器指纹是否变化,如果变了就报警。

这个模型在以下场景下有风险:

  • 新机器首次连接:你还没有可信的指纹来验证
  • 重装系统后首次连接:旧指纹失效,新指纹未经验证
  • 通过不可信网络连接:比如公共 WiFi、咖啡厅网络

攻击者如果能劫持网络流量(比如通过 ARP 欺骗、DNS 劫持或 BGP 劫持),就可以在中间插入自己的 SSH 服务器,记录你的密码和所有会话内容。

cloud-init 临时密钥方案

Joachim 提出的方案利用 cloud-init(大多数云服务器在首次启动时运行的初始化脚本)来生成一个临时的 SSH 密钥对,并将公钥注入到新机器中。

工作原理:

  1. 在启动 VPS 之前,本地生成一对临时 SSH 密钥
  2. 通过 cloud-init 配置,将公钥注入到新机器的 authorized_keys
  3. VPS 启动后,用这个临时密钥进行首次连接
  4. 首次连接成功后,替换为正式的 SSH 密钥

这种方法的好处是:首次连接时使用密钥认证而非密码,即使中间人截获了连接,也无法获取你的密码(因为根本没用密码)。而且临时密钥用完即弃,不影响长期安全。

具体操作步骤

第一步:生成临时密钥

ssh-keygen -t ed25519 -f ~/.ssh/temp_vps_key -N "" -C "temp-vps-key"

这会在 ~/.ssh/ 下生成 temp_vps_key(私钥)和 temp_vps_key.pub(公钥)。

第二步:准备 cloud-init 配置

创建一个 cloud-init 配置文件 cloud-init.yaml

#cloud-config
ssh_authorized_keys:
  - ssh-ed25519 AAAA...你的临时公钥... temp-vps-key
chpasswd:
  list: |
    root:随机强密码
  expire: true
ssh_pwauth: false

这个配置做了三件事:注入临时公钥、设置初始密码并要求首次登录后修改、禁用密码登录。

第三步:创建 VPS 时传入 cloud-init

大多数云服务商(Vultr、DigitalOcean、Linode、阿里云、腾讯云等)在创建实例时都有”User Data”或”Cloud-Init”选项。将上面的配置粘贴进去。

第四步:首次连接并验证

ssh -i ~/.ssh/temp_vps_key root@你的VPS_IP

连接成功后,立即查看服务器的 SSH 主机密钥指纹:

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

将这个指纹保存下来,用于后续连接的验证。

第五步:替换为正式密钥并清理

# 在服务器上添加你的正式公钥
echo "你的正式公钥" >> ~/.ssh/authorized_keys
# 从 authorized_keys 中删除临时公钥
# 删除临时密钥
rm ~/.ssh/temp_vps_key ~/.ssh/temp_vps_key.pub

更进一步:SSHFP DNS 记录

如果你有自己的域名,还可以配置 SSHFP DNS 记录来验证 SSH 主机密钥。SSHFP 记录将服务器的 SSH 密钥指纹存储在 DNS 中,客户端连接时会自动比对。配合 DNSSEC 使用,可以实现密码学级别的验证。

常见问题

Q: 所有云服务商都支持 cloud-init 吗?

A: 大多数主流云服务商都支持,但小众的 IDC 可能不支持。创建实例时看有没有”User Data”或”初始化脚本”选项。

Q: 如果我用的是 Windows 怎么办?

A: Windows 上可以用 PuTTY 或 Windows Terminal + OpenSSH Client,密钥认证流程类似。临时密钥可以通过 PowerShell 的 ssh-keygen 生成。

Q: 这个方案能完全防止中间人攻击吗?

A: 没有方案能 100% 防止。cloud-init 方案大幅降低了风险(用密钥替代密码),但理论上攻击者仍然可以劫持连接并记录会话内容。最安全的做法是结合 SSHFP、VPN 或物理验证指纹。

总结

对于站长来说,VPS 安全从第一次 SSH 连接就开始了。cloud-init 临时密钥方案是一个简单但有效的安全加固措施,操作不复杂但能显著降低首次连接的风险。建议在每次新开 VPS 时都采用这个流程。

本文参考来源:Stop MitM on first SSH connection — Joachim Schipper

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容