GitHub 操作中的 SSH "Host key verification failed" - 但密钥存在于 known_hosts

SSH "Host key verification failed" in GitHub Actions - but key exists in known_hosts

我在 GitHub 操作中遇到了最奇怪的错误,我已经尝试解决了好几个小时,但我完全没有想法。

我目前使用的是一个非常简单的 GitHub 动作。最终目标是在其他工作流程中通过 ssh 运行 特定 bash 命令。

Docker 文件:

FROM ubuntu:latest

COPY entrypoint.sh /entrypoint.sh

RUN apt update && apt install openssh-client -y
RUN chmod +x entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

entrypoint.sh:

#!/bin/sh

mkdir -p ~/.ssh/
echo "" > ~/.ssh/private.key
chmod 600 ~/.ssh/private.key
echo "" > ~/.ssh/known_hosts

echo "ssh-keygen"
ssh-keygen -y -e -f ~/.ssh/private.key
echo "ssh-keyscan"
ssh-keyscan <IP>

ssh -i ~/.ssh/private.key -tt <USER>@<IP> "echo test > testfile1"
echo "known hosts"
cat ~/.ssh/known_hosts
wc -m ~/.ssh/known_hosts

action.yml

name: "SSH Runner"
description: "Runs bash commands in remote server via SSH"
inputs:
  ssh_key:
    description: 'SSH Key'
  known_hosts:
    description: 'Known Hosts'
runs:
  using: 'docker'
  image: 'Dockerfile'
  args:
    - ${{ inputs.ssh_key }}
    - ${{ inputs.known_hosts }}

同一存储库中的当前工作流文件:

on: [push]

jobs:
  try-ssh-commands:
    runs-on: ubuntu-latest
    name: SSH MY_TEST
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: test_ssh
        uses: ./
        with:
          ssh_key: ${{secrets.SSH_PRIVATE_KEY}}
          known_hosts: ${{secrets.SSH_KNOWN_HOSTS}}

在 github 操作在线控制台中,我得到以下输出:

ssh-keygen
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "2048-bit RSA, converted by root@844d5e361d21 from OpenSSH"
AAAAB3NzaC1yc2EAAAADAQABAAABAQDaj/9Guq4M9V/jEdMWFrnUOzArj2AhneV3I97R6y
<...>
9f/7rCMTJwae65z5fTvfecjIaUEzpE3aen7fR5Umk4MS925/1amm0GKKSa2OOEQnWg2Enp
Od9V75pph54v0+cYfJcbab
---- END SSH2 PUBLIC KEY ----
ssh-keyscan
# <IP>:22 SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
# <IP>:22 SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
# <IP>:22 SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
# <IP>:22 SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
# <IP>:22 SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
<IP> ssh-ed25519 AAAAC3NzaC1lZD<...>9r5SNohBUitk
<IP> ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRNWiDWO65SKQnYZafcnkVhWKyxxi5r+/uUS2zgYdXvuZ9UIREw5sumR95kbNY1V90<...>
qWXryZYaMqMiWlTi6ffIC5ZoPcgGHjwJRXVmz+jdOmdx8eg2llYatRQbH7vGDYr4zSztXGM77G4o4pJsaMA/
***
Host key verification failed.
known hosts
***
175 /github/home/.ssh/known_hosts

据我了解,*** 用于替换 GitHub 秘密,在我的例子中,它是已知主机的密钥。 ssh-keyscan 的结果是 *** cat known_host 应该意味着 known_hosts 文件是正确的并且连接应该有可能。因为在这两种情况下,控制台输出都被 GitHub 成功审查。由于该文件包含 175 个字符,我可以假设它包含实际密钥。但是正如人们所看到的那样,脚本失败并显示 Host key verification failed.

当我在另一个工作流程中使用完全相同的输入数据手动执行相同的步骤时,我成功了。从我的本地计算机使用相同的 private_keyknown_host 文件进行 ssh 也是如此。

例如,这适用于完全相同的秘密

- name: Create SSH key
        run: |
          mkdir -p ~/.ssh/
          echo "$SSH_PRIVATE_KEY" > ../private.key
          sudo chmod 600 ../private.key
          echo "$SSH_KNOWN_HOSTS_PROD" > ~/.ssh/known_hosts
        shell: bash
        env:
          SSH_PRIVATE_KEY: ${{secrets.SSH_PRIVATE_KEY}}
          SSH_KNOWN_HOSTS: ${{secrets.SSH_KNOWN_HOSTS}}
- name: SSH into DO and run
        run: >
          ssh -i ../private.key -tt ${SSH_USERNAME}@${SERVER_IP}
          "
            < commands >
          "

entrypoint.sh 中的 ssh 命令上使用 -o "StrictHostKeyChecking no" 标志也可以。但出于安全原因,我想避免这种情况。

几个小时以来,我一直在努力解决这个问题,但我似乎遗漏了一个关键细节。有人遇到过类似问题或知道我做错了什么吗?

首先,在您的入口点也添加一个 chmod 600 ~/.ssh/known_hosts

为了测试,我会检查 options around ssh-keyscan 是否有任何区别:

ssh-keyscan -H <IP>
# or
ssh-keyscan -t rsa -H <IP>

检查您的密钥是否使用默认的 rsa public-密钥密码系统生成。
HostKeyAlgorithms used might be set differently,在这种情况下:

ssh-keyscan -H -t ecdsa-sha2-nistp256 <IP>

经过数小时的搜索,我发现了问题所在。 当使用 -o "StrictHostKeyChecking no" 选项强制接受所有主机密钥时,不会创建 ~/.ssh/known_hosts 文件。这意味着我在容器中安装的 openssh-client 似乎无法从该文件中读取。 所以告诉 ssh 命令在哪里寻找文件解决了这个问题:

ssh -i ~/.ssh/private.key -o UserKnownHostsFile=/github/home/.ssh/known_hosts -tt <USER>@<IP> "echo test > testfile1"

显然也可以永久更改 ssh_configknown_hosts 文件的位置(参见 here)。

希望这对某些人有所帮助。