错误信息
Host key verification failed.
也可能输出为
- No ED25519 host key is known for 127.0.0.1 and you have requested strict checking.
- fatal: Could not read from remote repository.
Git 会在其后输出“fatal: Could not read from remote repository.”。前一行中的密钥类型(`ED25519`、`ECDSA`、`RSA`)是服务器提供的类型。
含义
ssh 无法确认服务器就是它声称的那台主机,因此在身份验证之前就中止了。要么主机不在 `known_hosts` 中,而 ssh 又无法询问你(批处理模式、CI、没有终端的 Git 命令);要么主机已有记录,但记录的是另一个密钥。前一行会说明是哪种情况:未知主机显示“No … host key is known for …”,密钥变更的主机则显示醒目的“REMOTE HOST IDENTIFICATION HAS CHANGED”警告。
原因
首次连接时没有终端
常见CI 运行器、cron 任务、Docker 构建以及脚本中的 `git`,一开始的 `known_hosts` 都是空的。在 `BatchMode yes` 下或没有 TTY 时,ssh 无法显示确认提示,于是直接失败。
主机密钥与记录的不同
常见服务器重装、IP 地址被另一台机器复用、负载均衡器后面的各台主机密钥不同——或者连接被拦截。参见“REMOTE HOST IDENTIFICATION HAS CHANGED”条目。
用到的 known_hosts 文件并不是你以为的那个
偶见CI 或 sudo 中的 `HOME` 不同、`UserKnownHostsFile` 指向别处,或者文件属于另一个用户,ssh 无法读写。
修复方法
- 1.
验证主机密钥后再记录
`ssh-keyscan` 显示的是网络返回给你的内容;信任之前,先把它的指纹与可信来源提供的指纹比对。
bash # Store the server's host key once, after checking its fingerprint out of band. ssh-keyscan -t ed25519 server.example.com > /tmp/hostkey ssh-keygen -lf /tmp/hostkey # compare with the fingerprint from your provider/console cat /tmp/hostkey >> ~/.ssh/known_hosts - 2.
把验证过的 known_hosts 提供给 CI
把验证过的那一行存为机密,或者存入仓库。`StrictHostKeyChecking no` 或在运行时执行 `ssh-keyscan`,都会让作业接受任何应答的主机。
yaml # GitHub Actions: put the verified known_hosts line into a secret, not ssh-keyscan at run time - name: Configure SSH run: | install -d -m 700 ~/.ssh echo "${{ secrets.DEPLOY_KNOWN_HOSTS }}" > ~/.ssh/known_hosts chmod 600 ~/.ssh/known_hosts - 3.
使用 Git 托管平台公布的密钥
GitHub、GitLab 和 Bitbucket 都公布了各自的主机密钥指纹;GitHub 还可以通过其 meta API 获取。
bash # GitHub publishes its SSH host keys (also at https://api.github.com/meta, "ssh_keys") curl -s https://api.github.com/meta | jq -r '.ssh_keys[] | "github.com " + .' >> ~/.ssh/known_hosts