AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 856194
Accepted
Roger Lipscombe
Roger Lipscombe
Asked: 2017-06-17 02:22:41 +0800 CST2017-06-17 02:22:41 +0800 CST 2017-06-17 02:22:41 +0800 CST

安全地将主机(例如 GitHub)添加到 SSH known_hosts 文件

  • 772

如何known_hosts安全地将主机密钥添加到 SSH 文件?

我正在设置一台开发机器,并且我想(例如)防止在我使用 SSHgit克隆存储库时出现提示。github.com

我知道我可以使用StrictHostKeyChecking=no(例如这个答案),但这并不安全。

到目前为止,我发现...

  1. GitHub 在GitHub 的 SSH 密钥指纹中发布他们的 SSH 密钥指纹

  2. 我可以ssh-keyscan用来获取github.com.

我如何结合这些事实?给定一个预填充的指纹列表,我如何验证 的输出是否ssh-keyscan可以添加到known_hosts文件中?


我想我在问以下问题:

如何获取返回的密钥的指纹ssh-keyscan?

假设我已经接受了 SSH的 MITM,但我可以信任 GitHub HTTPS 页面(因为它具有有效的证书链)。

这意味着我有一些(可疑的)SSH 主机密钥(来自ssh-keyscan)和一些(可信的)密钥指纹。我如何验证一个与另一个?


相关:我如何散列输出的主机部分ssh-keyscan?或者我可以混合散列/未散列的主机known_hosts吗?

ssh
  • 8 8 个回答
  • 95228 Views

8 个回答

  • Voted
  1. Best Answer
    Michael
    2019-06-19T07:54:01+08:002019-06-19T07:54:01+08:00

    “安全地”向文件添加密钥的最重要部分known_hosts是从服务器管理员那里获取密钥指纹。密钥指纹应如下所示:

    2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA)
    

    对于 GitHub,通常我们不能直接与管理员交谈。但是,他们将密钥放在他们的网页上,这样我们就可以从那里恢复信息。

    手动安装密钥

    1)从服务器获取密钥副本并获取其指纹。注意:在检查指纹之前执行此操作。

    $ ssh-keyscan -t rsa github.com | tee github-key-temp | ssh-keygen -lf -
    # github.com:22 SSH-2.0-babeld-f3847d63
    2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA)
    

    2)从服务器管理员处获取密钥指纹的副本 - 在这种情况下,导航到包含 github.com 上信息的页面

    1. 去 github.com
    2. 转到帮助页面(如果已登录,则在右侧菜单上;否则在主页底部)。
    3. 在入门部分中,转到使用 SSH 连接到 GitHub
    4. 转到测试您的 SSH 连接
    5. 将该页面中的 SHA256 指纹复制到您的文本编辑器中以供以后使用。

    3)比较两个来源的密钥

    通过在文本编辑器中将它们直接放在另一个之上,很容易查看是否发生了变化

    2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA) #key recovered from github website
    2048 SHA256:nThbg6kXUpJ3Gl7E1InsaspRomtxdcArLviKaEsTGY8 github.com (RSA) #key recovered with keyscan
    

    (请注意,第二个密钥已被操纵,但它看起来与原始密钥非常相似 - 如果发生这种情况,您将受到严重攻击,应该联系受信任的安全专家。)

    如果密钥不同,请中止该过程并与安全专家联系

    4)如果密钥比较正确,那么你应该安装你已经下载的密钥

    cat github-key-temp >> ~/.ssh/known_hosts
    

    或者为系统上的所有用户安装(以 root 身份):

    cat github-key-temp >> /etc/ssh/ssh_known_hosts
    

    自动安装密钥

    如果您需要在构建过程中添加密钥,则应遵循上述手动过程的步骤 1-3。

    完成后,检查github-key-temp文件的内容并制作一个脚本以将这些内容添加到您已知的主机文件中。

    if ! grep github.com ~/.ssh/known_hosts > /dev/null
    then
         echo "github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts
    fi
    

    您现在应该摆脱所有ssh已StrictHostKeyChecking禁用的命令。

    • 54
  2. Wee
    2017-06-17T02:32:54+08:002017-06-17T02:32:54+08:00

    您可以在 known_hosts 文件中混合散列/未散列条目。

    所以如果你想添加 github 密钥,你可以这样做:

    ssh-keyscan github.com >> ~/.ssh/known_hosts

    如果要散列,请添加 -H

    ssh-keyscan -H github.com >> ~/.ssh/known_hosts

    注意:这很容易受到 MITM 攻击,它只回答问题的“相关”部分。

    • 38
  3. Jakuje
    2017-06-17T03:42:33+08:002017-06-17T03:42:33+08:00

    最简单的方法是使用 手动获取密钥ssh-keyscan,手动验证它们:

    $ ssh-keyscan -t rsa github.com | ssh-keygen -lf -
    # github.com:22 SSH-2.0-libssh-0.7.0
    2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA)
    

    并将它们添加到您的脚本中,然后该脚本将携带“权威”公钥。

    • 5
  4. Aleksandar Gajic
    2020-03-20T03:00:50+08:002020-03-20T03:00:50+08:00

    我编写了简单的脚本(add_to_known_hosts)来处理这个问题:

    它不会在 known_hosts 文件中创建重复的条目,它会检查指纹是否与作为第二个参数提供的指纹匹配。

    #!/usr/bin/env bash
    # The first argument should be hostname (or IP)
    # The second argument should be the SSH fingerprint from the server admin.
    # Example: add_to_known_hosts github.com SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8
    
    host=$1
    fingerprint=$2
    
    ip=$(getent hosts $1 | awk '{ print $1 }')
    echo $ip
    
    keys=$(ssh-keyscan -t rsa $host $ip)
    
    # Iterate over keys (host and ip)
    while IFS= read -r key; do
        # Extract Host name (or IP)
        key_host=$(echo $key | awk '{ print $1 }')
    
        # Extracting fingerprint of key
        key_fingerprint=$(echo $key | ssh-keygen -lf - | awk '{ print $2 }')
    
        # Check that fingerprint matches one provided as second parameter
        if [[ $fingerprint != $key_fingerprint ]]; then
          echo "Fingerprint match failed: '$fingerprint' (expected) != '$key_fingerprint' (got)";
          exit 1;
        fi
        
        # Add key to known_hosts if it doesn't exist
        if ! grep $key_host ~/.ssh/known_hosts > /dev/null
        then
           echo "Adding fingerprint $key_fingerprint for $key_host to ~/.ssh/known_hosts"
           echo $key >> ~/.ssh/known_hosts
        fi
    done <<< "$keys"
    
    • 5
  5. gene_wood
    2022-04-14T07:18:51+08:002022-04-14T07:18:51+08:00

    现在 GitHub通过其元数据 API 端点(截至 2022 年 1 月)提供其 SSH 密钥和指纹,您可以利用您对 GitHub 使用的 TLS 证书的信任(api.github.com因为它由位于您系统的受信任的根证书存储)以安全地获取其 SSH 主机密钥。

    如果你已经jq安装了,你可以用这个单线做到这一点

    curl --silent https://api.github.com/meta \
      | jq --raw-output '"github.com "+.ssh_keys[]' >> ~/.ssh/known_hosts
    

    或者如果你想使用 Python

    curl --silent https://api.github.com/meta | \
      python3 -c 'import json,sys;print(*["github.com " + x for x in json.load(sys.stdin)["ssh_keys"]], sep="\n")' \
      >> ~/.ssh/known_hosts
    
    • 3
  6. Etienne Jacquot
    2021-04-02T15:13:38+08:002021-04-02T15:13:38+08:00

    自动化 SSH Known_Hosts 指纹检查

    我一直在尝试在 Jupyterhub 上的 Python 中执行此操作一段时间,但@Michael 的回答真的很有帮助!

    让我们明确一点——通过设计,这个步骤是为了确认已知主机不应该被自动化,因为它容易受到中间人的攻击(更多信息在这里,但应该很明显为什么这是一个问题)。

    使用 Python 和 Bash 手动检查 GitHub.com 的 SSH RSA 指纹

    不安全的解决方法-o "StrictHostKeyChecking no"可以用于测试,但很高兴有替代方案。

    • 请注意,我在 Jupyter 中使用bang 来为&!调用 bash 命令ssh-keyscancat
    # MANUALLY GET TRUSTED RSA FINGERPRINT FOR GITHUB
    # https://docs.github.com/en/github/authenticating-to-github/githubs-ssh-key-fingerprints
    
    rsa_pubkey_fingerprint = 'SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8'
    
    # Get the host rsa info for github, write to a file
    # pipe to get the RSA FingerPrint, and finally write that fingerprint to file
    
    !ssh-keyscan -t rsa github.com | tee ./github_ssh_test | ssh-keygen -lf - >> ./fingerprint_rsa
    

    断言指纹匹配以确认已知主机

    您现在可以使用 python 断言来确保我们受信任的 RSA 指纹与 Scanned-over-your-internet RSA 指纹的真实性:

    assert(rsa_pubkey_fingerprint == open("./fingerprint_rsa", "r").read().split()[1])
    
    # if the assertion passes and the trusted matches the scanned
    # it'll write to your known_hosts file!
    
    !cat ./github_ssh_test >> $HOME/.ssh/known_hosts
    
    # you are now good to test your SSH connection
    !ssh -T [email protected]
    

    感谢和一个更好的解决方法来忽略严格的检查!

    • 2
  7. OHY
    2022-01-19T09:47:42+08:002022-01-19T09:47:42+08:00

    如果您想在生成新密钥之前检查密钥是否存在:

    ssh-keygen -F github.com || ssh-keyscan github.com >> ~/.ssh/known_hosts
    

    此外,就我而言,我不得不提到一个特定的端口:

    ssh-keygen -F "[<host>]:<port>" || ssh-keyscan -p <port> <host> >> ~/.ssh/known_hosts
    
    • -1
  8. Bogdan
    2021-01-30T14:18:37+08:002021-01-30T14:18:37+08:00

    要生成 known_hosts 文件,在生成您的私钥和公钥并将公钥复制到 site.com 之后,您可以执行

    ssh -T [email protected]
    
    • -2

相关问题

  • 如何最好地设置 ssh 隧道以访问远程网络 (Linux)

  • SSH 和重定向

  • 通过 SSH 会话使用 NET USER 命令拒绝访问

  • SSH 服务器零日漏洞利用 - 保护自己的建议

  • ubuntu apt-get upgrade - 如何在 shell 中单击确定?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve