GitHub Actions 中的 SSH“主机密钥验证失败” - 但密钥存在于known_hosts 中

j.u*_*ruh 12 ssh continuous-integration continuous-deployment docker github-actions

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

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

Dockerfile:

FROM ubuntu:latest

COPY entrypoint.sh /entrypoint.sh

RUN apt update && apt install openssh-client -y
RUN chmod +x entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Run Code Online (Sandbox Code Playgroud)

入口点.sh:

FROM ubuntu:latest

COPY entrypoint.sh /entrypoint.sh

RUN apt update && apt install openssh-client -y
RUN chmod +x entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Run Code Online (Sandbox Code Playgroud)

动作.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 }}
Run Code Online (Sandbox Code Playgroud)

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

#!/bin/sh

mkdir -p ~/.ssh/
echo "$1" > ~/.ssh/private.key
chmod 600 ~/.ssh/private.key
echo "$2" > ~/.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
Run Code Online (Sandbox Code Playgroud)

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

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 }}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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}}

Run Code Online (Sandbox Code Playgroud)

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

我已经尝试解决这个问题几个小时了,但我似乎错过了一个关键细节。有人遇到过类似的问题或者知道我做错了什么吗?

j.u*_*ruh 12

因此,经过几个小时的搜索,我发现了问题所在。当使用选项强制接受所有主机密钥时,-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"

known_hosts显然,人们还可以永久更改文件的位置ssh_config(请参阅此处)。

希望这可以在某个时候帮助某人。


Jan*_*nik 7

对于 2023 年的 GitHub runner,该.ssh目录不存在,因此您必须known_hosts首先创建它:

mkdir -p ~/.ssh/ && touch ~/.ssh/known_hosts
Run Code Online (Sandbox Code Playgroud)

然后添加公共 SSH 主机密钥:

ssh-keyscan [hostname] >> ~/.ssh/known_hosts
Run Code Online (Sandbox Code Playgroud)

和私钥:

eval $(ssh-agent)
ssh-add - <<< "${{ secrets.SSH_PRIVATE_KEY }}"
Run Code Online (Sandbox Code Playgroud)