非交互式 git clone(ssh 指纹提示)

qwe*_*qwe 170 ssh git

我想以非交互式方式克隆一个 repo。克隆时,git 要求确认主机的指纹:

The authenticity of host 'bitbucket.org (207.223.240.182)' can't be established.
RSA key fingerprint is 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40.
Are you sure you want to continue connecting (yes/no)? no
Run Code Online (Sandbox Code Playgroud)

每次出现这个问题时,我如何强制“是”?我尝试使用yes yes | git clone ...,但它不起作用。

编辑:这是一个解决方案:我可以自动将新主机添加到 known_hosts 吗?(使用 ssh-keyscan 将所有内容添加到 known_hosts)。

aut*_*tra 136

“StrictHostKeyChecking no”和“ssh-keyscan”选项都不安全。您需要手动指纹验证在某一点,以避免MITM攻击,如果你坚持使用ssh。

实际上,您有两个选择:

使用 https 协议代替 git

它不会要求您提供指纹,因为不涉及 ssh,而是使用 https。出于安全考虑,您信任安装在操作系统上的根证书。如果您使用的是极简镜像或 Docker,则可能需要安装 ca-certificates 包。

如果你真的想要 git+ssh 协议

你真的需要在运行时添加密钥吗?这并不安全,因为您没有检查指纹,这让您容易受到 MiTM 攻击。这不仅仅是理论上的,而且已经被证明是有效的。

在运行您的脚本之前,从 github(在您的本地机器上)获取密钥:

ssh-keyscan github.com >> githubKey
Run Code Online (Sandbox Code Playgroud)

生成指纹:

ssh-keygen -lf githubKey
Run Code Online (Sandbox Code Playgroud)

并根据此页面中列出的内容手动检查它(好吧,您信任 https 证书和 OpenSSL 为您带来原始 github 网站,但它仍然比盲目接受公钥要好得多)。

或者(信任相同的HTTPS和OpenSSL),你可以从获取它https://api.github.com/meta这样的:curl -s https://api.github.com/meta | jq ."ssh_key_fingerprints" | grep RSA。(感谢@willscripted 这个)

然后,您通过添加将其硬编码到您的脚本中:

echo '<copy paste the content of 'cat githubKey' on your machine>'  >> ~/.ssh/known_hosts
Run Code Online (Sandbox Code Playgroud)

在 git clone 之前。

GitHub 公钥仅在他们认为已被泄露(或不够安全)时才会更改。如果出现这种情况,您无论如何都希望脚本失败。

  • 不幸的是,如果您使用两因素身份验证,则无法使用 GitHub 进行非交互式 HTTPS。 (2认同)
  • Github 的密钥扫描指纹现在可以根据开发人员 api 中的值进行验证。`curl -i https://api.github.com/meta`。我们仍然可以信任证书,但现在是实时的,而不是手动一次。 (2认同)

小智 130

我不认为这是最好的解决方案,但它对我来说是一个解决方案。

回答:

known_hosts使用ssh-keyscan命令将域名添加到文件解决了这个问题:

ssh-keyscan <enter_domainname_e.g._github.com> >> ~/.ssh/known_hosts

  • 仅当密钥不存在时才添加密钥`ssh-keygen -F github.com || ssh-keyscan github.com &gt;&gt;~/.ssh/known_hosts` (15认同)
  • 请不要这样做。这完全不安全:指纹不是为了惹恼您,而是为了确保您不会面临中间人攻击。请看我下面的回答。 (9认同)
  • 作为配置管理或配置运行的一部分执行一次应该没问题。如果指纹在未来发生变化,那么 ssh 将按预期工作并提醒您证书已更改,并返回非 0 退出代码。这可能会停止您使用 ssh 或 git 的任何脚本。 (4认同)
  • 这不是政治正确的问题:-) 这是安全与否的问题。当且仅当您在“ssh-keyscan”之后以及将其添加到“.ssh/known_hosts”之前手动检查指纹以使其与 github 在其网站上发布的指纹相同时,您的解决方案才是安全的。你可以通过多种方式做到这一点,我的就是其中之一。您还可以在脚本中进行同样的检查,但最终结果是这样的:您需要脚本知道它期望哪个指纹,并且如果它没有收到正确的指纹,您需要它失败。 (2认同)

小智 11

我相信这里更好的选择是备份和清空~/.ssh/known_hosts文件,手动执行 SSH 连接,验证 IP 地址和指纹mv ~/.ssh/known_hosts ~/bitbucket_hosts,然后使用~/bitbucket_hosts脚本中的内容自动将已知指纹附加到 known_hosts 文件(不要t忘记恢复原来的~/.ssh/known_hosts)。

这一步只需要执行一次(我相信在任何机器上),一旦你有了指纹,你就可以把它合并到你的自动化脚本中。


udo*_*dan 11

添加密钥.ssh/known_hosts似乎是正确的做法。

虽然当您自动执行任务时,您希望确保密钥尚未包含并添加到每个clone/pull任务中。

如果尚未找到,此代码段将仅添加指纹:

if [ ! -n "$(grep "^bitbucket.org " ~/.ssh/known_hosts)" ]; then ssh-keyscan bitbucket.org >> ~/.ssh/known_hosts 2>/dev/null; fi
Run Code Online (Sandbox Code Playgroud)


小智 7

虽然我当然理解您希望自动化这样的过程,但这样做是不明智的。SSH 和相关网络子组件在使用安全协议时犹豫不决的原因是警告人们系统的公钥是未知的。这是故意的 - 用户需要明确通知系统主机是预期的。您不希望自动接受提供给您的每个公钥,否则 SSH 或 TLS/SSL 中的部分安全性可能会受到损害。一个例子是通过中间人攻击,例如当代理软件在您期望的主机位置提供它自己的密钥时。

谨慎行事。

如果您不担心网络上的代码来源,您应该在克隆时明确且专门使用 git:// 协议 - 它是无需身份验证的明文。

  • 我可以明确地看到我们需要强制使用 ``git clone`` 的非交互式使用的用例……但这并不意味着我们需要接受任何检查(特别是指纹检查)。就我而言,我会很高兴在这样的事情上自动失败。 (3认同)

Wre*_* T. 5

正如杰夫霍尔所说,这样做很危险,因为它允许未被发现的中间人攻击。但是,您可以使用ssh 中的StrictHostKeyChecking no选项来禁用检查主机密钥。但是,如果我是你,我会非常小心这个选项。

  • 它还允许中间人,对吗? (4认同)