【问题标题】:Using the same deploy key for multiple github projects对多个 github 项目使用相同的部署密钥
【发布时间】:2012-10-24 22:02:00
【问题描述】:

Github 不允许将同一个 ssh 部署密钥用于多个项目,这在某些情况下会非常有用(例如 CI 服务器处理带有私有子模块的项目)。我已经看到各种帖子似乎说这种限制是出于“安全原因”,但我还没有看到一个令人信服的解释来说明这会带来什么风险。

请注意,Github 不允许重复使用 帐户级别 密钥这一事实是有道理的(两个用户不应共享密钥)。我要质疑的只是对 Deploy Keys 的限制。

需要明确的是,我不是寻找解决方法(创建一个虚拟用户,使用多个密钥,...),但只是为了对部署密钥的这种限制进行合理的解释。

相关话题:

【问题讨论】:

  • 由于没有更好的方法,我们创建了一个专门的部署用户,我们授予他对存储库的只读访问权限。最终结果是一样的。

标签: git github ssh


【解决方案1】:

您引用的解决方法(创建单个“构建”用户,或每个 repo 共享相同的id_rsa.REPONAME.pub)说明的唯一原因是:

避免为不同用户共享公钥/私钥

即使您的情况并非如此(构建多个项目),但允许重复使用相同的 ssh 密钥将为两个不同用户共享相同的 ssh 密钥提供可能性,这会破坏身份验证的目的。

认证方式:
“使用某个 ssh 密钥应该意味着您应该知道谁在使用它”。


GitHub 页面“Managing deploy keys”详细介绍了使用 ssh 的各种帐户:

  • SSH 代理转发:当您通过 SSH 连接到服务器并运行 git 命令时,代理转发使用已在本地开发计算机上设置的 SSH 密钥。
    您可以有选择地让远程服务器访问您的本地 ssh-agent,就像它在服务器上运行一样。
    因此无需在服务器上复制您的私钥。

  • 机器用户:(这是“虚拟帐户”策略)将密钥附加到用户帐户。由于此帐户不会被人类使用,因此称为机器用户。
    不过,您会像对待人类一样对待此用户,将密钥附加到机器用户帐户,就好像它是普通帐户一样。
    授予帐户协作者或团队访问其需要访问的存储库的权限。
    所以一个私钥关联到一个“机器用户”,每个服务器一个。

DHa 指出in the comments 是一个部署密钥限制数,并且您只能拥有一个机器用户帐户)

  • 部署密钥(每个 GitHub 存储库一个)存储在服务器上并授予对 GitHub 上单个存储库的访问权限的 SSH 密钥。
    此密钥直接附加到存储库,而不是附加到用户帐户
    不要转到您的帐户设置,而是转到目标存储库的管理页面。
    转到“Deploy Keys”并单击“Add deploy key”。粘贴公钥并提交。

这一次,ssh 密钥未附加到用户(您可以授予用户访问多个存储库的权限),而是附加到一个存储库。
授予 几个 repo 的 ssh 访问权限相当于“机器用户”。

认证方面:

  • 当用户完成时,对多个存储库使用相同的密钥是可以的(该密钥已与他/她的帐户关联)
  • 当密钥由存储库附加时,对多个存储库使用相同的密钥是不行的,因为您根本不知道访问了什么。
    这与将“用户”声明为许多 repo 的协作者的“机器用户”不同。
    这里(部署密钥),没有“合作者”,只是授予 repo 的直接 ssh 访问权限。

Yusuf Bhabhrawala 进一步说明了the comments 中的这种模型限制:

考虑这些非常合理的用例 - 使用私有 pip 模块的 python 项目或使用私有 npm 包的节点项目 - 都来自同一组织中的另一个 repo。

目前无法使用部署密钥或帐户密钥(这会暴露太多其他存储库)来部署这个非常简单的用例。

Chris Stenkamp 指向“How to discover where 'pip install git+ssh://...' is searching for ssh keys?”,这涉及到设置GIT_SSH_COMMAND 环境变量。

【讨论】:

  • GitHub 支持 Account Level 公钥和 Project Level 密钥(又名 Deploy Keys)。不允许重用 Account Level 密钥是有道理的,但我声称不允许 Deploy Keys 使用它是不行的。我的一个帐户级别密钥允许访问我的所有项目,那么为什么我不能拥有一个允许访问我的一些项目的部署密钥?它只是更具限制性,不会引起我能看到的任何担忧。在那种情况下,您对可能让两个不同的用户共享同一个 ssh 密钥的担忧不会出现。
  • 恐怕我不遵循你的推理。我问的是一个非常具体的场景(在多个项目中使用部署密钥),而您认为不可能的论点是提出了一个不相关的场景(两个用户共享 ssh 密钥)。只坚持 Deploy Key 场景,github 允许它的负面影响是什么?
  • @DavidEbbo 在help.github.com/articles/managing-deploy-keys 之后,这三种方法(帐户、部署或机器帐户)均不涉及共享用于访问所述存储库的私有 SSH 密钥。仅坚持部署密钥方案,因为它是服务器上的密钥,它在多个存储库上有效意味着在多个存储库上共享(或复制)私钥。这会减少身份验证方面,如果密钥被泄露,则会增加暴露的存储库数量。
  • 谢谢,该页面包含有趣的信息。如果我什么也没看到,我会在一两天内将您的回复标记为答案,但老实说,我仍然不相信这个论点。在两个 repos 上使用部署密钥并不比使用可以访问同一组 repos 的机器密钥弱。
  • 考虑这些非常合理的用例 - 使用私有 pip 模块的 python 项目或使用私有 npm 包的节点项目 - 都来自同一组织中的另一个 repo。目前,无论是使用部署密钥还是帐户密钥(这会暴露太多其他存储库),都无法部署这个非常简单的用例。
【解决方案2】:

我花了很多心思来解释其中的含义并想出了这个方案。

假设您为分配给多个存储库的用户创建了一个部署密钥。现在您想撤销该密钥,但它在多个地方使用。因此,您可能会无意中只撤销部分访问权限,而不是能够撤销所有访问权限。

这听起来像是一个好处,但是一旦考虑到人为因素,这种多对一的关系实际上本质上是不安全的。这是因为如果不检查每个存储库并单独比较每个公钥,以防您忘记了实际分配的位置,您就无法确定是否真的撤销了所有访问权限。

分配和管理如此多的唯一密钥确实令人沮丧,但 GitHub 如何制定其政策的安全隐患显而易见:当您撤销密钥时,您保证会撤销该密钥授予的所有访问权限,因为它只在一个地方使用。

【讨论】:

  • 我不相信这个解释。这与允许一个用户访问多个存储库有什么根本不同,这显然是允许的?如果您不再信任该用户,则需要从每个 repo 中删除他们。
  • @David: How is that fundamentally different from allowing one user to access multiple repositories, which is obviously allowed 你能进一步解释一下吗?我只有一个开发人员帐户,我看到您可以添加 ssh 密钥以进行帐户范围的访问(所有存储库一个密钥)或添加单独的部署密钥(每个存储库一个密钥)。这仍然是一对多或一对一的关系,在这两种情况下,撤销“one”键都会撤销“all”访问。
  • 为了进一步澄清,没有机会(据我所知)在多对一关系中意外分配密钥,在该关系中,访问权限在被撤销后可能存在于其他地方。这似乎是 GitHub 设置此限制的动机,但我只是猜测。
  • 在我看来,部署密钥有点像没有完整帐户但仍代表某种身份的“匿名用户”。不同之处在于,在帐户情况下,您授予对帐户的访问权限,而这间接授予对该帐户中所有 ssh 密钥的访问权限。在 Deploy Key 案例中,您跳过帐户抽象并直接授予对 ssh 密钥的访问权限。但除此之外,我认为安全需求没有什么不同。如果部署密钥的帐户或所有者变得邪恶,您需要从每个 repo 中删除它们。
  • 我认为您在这里的“多对一”推理是对他们选择这样做的为什么的最佳解释。正如您所说,您可以一步撤消一个用户(以及他们的密钥),但您不能一步从多个存储库中撤消一个部署密钥。话虽如此,我承认这个推理,但这并不意味着我必须喜欢这个结果,哈哈......对我来说明显的后续问题是,“为什么没有办法从多个回购中撤销一个密钥?” .构建该功能似乎并不特别复杂 - 不是微不足道的,但也不是超级难。希望有一天我们能得到更好的密钥管理。
【解决方案3】:

不幸的是,在这种情况下,github 只是误解了密钥对与帐户或项目之间的区别。

由于密钥对用于身份验证和授权,因此它实际上是一种身份。 Github 帐户是另一个身份。将 github 帐户连接到密钥对可以有效地在基于 github 帐户的身份和密钥对身份之间建立 1:N 映射。

相反,github 强制将项目 1:N 映射到基于密钥对的身份。现实世界的模拟是,有一扇门可以让许多不同的人打开该项目的访问权限。但是一旦他们中的任何一个人拿到了门钥匙,他们就再也拿不到任何其他门的钥匙了。

如果密钥被泄露,从遏制违规的角度来看,不要经常重复使用密钥是有意义的。但这只是一个很好的管理政策原则上阻止一个密钥被多次使用没有多大意义。有些门的钥匙永远不会重复使用,嗯,这又取决于政策


稍微复杂一点的视图是将密钥对表示为角色。您可以拥有许多密钥对,因此担任许多角色。私钥用于验证您的角色。

Github 的项目部署键映射声明一个角色永远不能包含多个任务。这很少是现实的。

当然,这些都不会改变 github 允许的内容。

【讨论】:

  • 嘿。当它比公认的答案更正确时,它是如何被否决的,这有点有趣。从字面上看,没有任何东西可以防止与多个用户共享密钥。
  • 是的,有缺陷的推理变成了不必要的限制。警告至多是唯一需要的措施。正如该问题中的另一位评论者所说(stackoverflow.com/questions/40515569/…):“采取最小的阻力路径将只涉及将密钥复制到多台机器,从而导致更大的安全风险。GitHub 应该让用户选择并承担风险每个存储库的基础。”
【解决方案4】:

我知道您不是在寻找解决方法,但我想很多用户登陆此页面并且也想要一个简单的解决方案。您周围的工作发布了与in github docs 类似的链接。如果手动完成,该过程很容易出错。

仅供参考,Bitbucket.org 没有此限制。你可以use the same read-only access key on multiple repos。这使得使用具有多个 repos 的单个生产服务器变得超级容易

如果你坚持使用 Github,这是我写的 script,它允许你通过运行 ./generateDeployKey.sh repo_owner_name repo_name 简单地传递你的 repo 所有者名称和存储库名称,它会为你做所有事情并输出你可能需要的任何东西复制。

将以下内容保存到名为generateDeployKey.sh的新文件中

#!/bin/sh
# This script generates a ssh key for a single repository
# and adds a custom configuration to the users (not global) ssh config file,
# and outputs the public key for you to copy and paste as the repo deploy key
# and outputs the url for you to clone the repo on the machine.
# Github docs ref:
# https://docs.github.com/en/developers/overview/managing-deploy-keys#using-multiple-repositories-on-one-server
#
# 1. Add the script to the user account of the machine. The home directory is fine.
# 2. Make the script executable by running the following command as the user:
# chmod u+x generateDeployKey.sh
# 3. Run script like `./generateDeployKey.sh REPO_OWNER_NAME REPO_NAME` Note the space between owner and repo name. Example:
# ./generateDeployKey.sh yourname hello_world
# If you make a mistake with what you pass in, you can remove change from your ~/.ssh/config file
# by deleting the most recent "New Key Generated on...." and deleting the related .pub and private keys


# Check if user passed in both parameters
if [ -z "$1" ] || [ -z "$2" ]
then
  echo "Make sure to pass in both parameters REPO_OWNER_NAME and REPO_NAME. Example:"
  echo "./generateDeployKey.sh yourname hello_world"
else
  REPO_OWNER_NAME=$1
  REPO_NAME=$2
  KEY_PATH=~/.ssh/id_rsa.$REPO_NAME
  echo "Generating ssh key At ${KEY_PATH}"
  ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa.${REPO_NAME}
  echo "Your ssh deploy key is:"
  PUB_KEY_PATH=$KEY_PATH".pub"
  cat $PUB_KEY_PATH
  echo ""
  # Will create config if it does not exist
  echo "Updating ~/.ssh/config"
  DATE_TIME=$(date +"%Y-%m-%d at %r")
  echo "
  # New Key Generated on $DATE_TIME
  Host github.com-$REPO_NAME
    HostName github.com
    User git
    IdentityFile $KEY_PATH" >> ~/.ssh/config
  echo ""
  echo "Here is your hostname's alias to interact with the repository using SSH:"
  echo "git clone git@github.com-$REPO_NAME:$REPO_OWNER_NAME/$REPO_NAME.git"
fi

【讨论】:

    猜你喜欢
    • 2019-12-18
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 2017-12-19
    • 1970-01-01
    相关资源
    最近更新 更多