在公钥认证中,客户端证明自己持有私钥,但它并不告诉客户端到达的是哪台服务器。服务器的主机密钥与本地 known_hosts 数据库,提供身份检查的后一半。

客户端私钥认证与服务器主机身份核验是不同检查。安装前,将候选指纹与独立可信的所有者或控制台指纹比较。yes 拒绝未知或变化的密钥;accept-new 接受首次见到的密钥但没有独立身份保证,仍拒绝变化。复核轮换、保存私有运维记录,ssh -G 不等于握手测试。
SSH 服务器身份依赖观察到的主机密钥与独立可信参考之间的比较。严格检查拒绝未知或变化的密钥。首次使用时信任与网络密钥扫描,都不能独立认证首次接触的服务器。

把首次接触与轮换分开

在 StrictHostKeyChecking=yes 下,SSH 拒绝未知主机与变化的密钥。对于一个固定生产端点,只要期望密钥通过可信渠道安装,这就是最安全的默认值。accept-new 是面向预期会出现新主机的、更窄的方便选项:它接受一个从未见过的密钥,但仍拒绝被更改的密钥。

Host production-site
    HostName www.example.test
    User deploy
    IdentityFile ~/.ssh/site_ed25519
    StrictHostKeyChecking yes
    UserKnownHostsFile ~/.ssh/known_hosts

不要通过给部署脚本加 StrictHostKeyChecking=no 来"修复"警告。它会在客户端限制条件下允许连接到密钥已变化的主机;警告可能仍被打印,但原本遇到身份问题就拒绝的检查已被削弱。如果主机被重建,请记录替换后的指纹,并复核旧密钥为何不再有效。

让指纹可复核

在首次连接之前,从主机所有者或控制台获取指纹,再与客户端看到的值比较。密钥变更应有工单、维护说明或其他他人可检视的解释。

同一规则适用于自动化:known-hosts 文件是带有安全后果的配置,不是可丢弃的缓存数据。把它与部署记录一起备份,但不要把私钥或复制的凭据随站点制品一起公开。

accept-new 是首次使用时信任,并不能独立证明第一次连接的服务器真实可信。ssh-keyscan 能采集候选公钥,但通过同一条不可信网络取回它,并不能认证它。安装前先将指纹与独立可信渠道取得的值比较。

把上面的配置单独保存为 deploy.conf,在不连接服务器的情况下检查有效配置:

ssh -G -F ./deploy.conf production-site | \
  grep -E '^(hostname|user|stricthostkeychecking|userknownhostsfile) '

结果应显示配置中的主机、用户、known-hosts 路径与严格检查(客户端输出可能为 true 或 yes)。这只解析配置,并不测试真实握手。非标准端口的 known-hosts 条目通常采用 [hostname]:port。将主机公钥指纹保存在私有运维发布记录中,不要随公共网站发布;即使主机公钥不是秘密,主机名也可能暴露内部拓扑。

来源