为多个github项目使用相同的部署密钥

时间:2012-11-05 04:14:05

标签: git github ssh

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

请注意,Github不允许重用帐户级密钥的事实是有意义的(两个用户不应共享密钥)。我正在质疑部署密钥的限制。

要明确的是,我正在寻找解决方法(创建一个虚拟用户,使用多个密钥......),但仅用于解释部署密钥上的此限制的合理解释。

相关主题:

4 个答案:

答案 0 :(得分:20)

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

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

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

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


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

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

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

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

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

根据身份验证

  • 使用相同的密钥进行多次回购是可以的,当用户完成时(其密钥与他/她的帐户相关联)
  • 当利用回购附加密钥时,
  • 使用相同的密钥进行多次回购是不行的,因为您根本不知道访问了什么。
    这不同于“机器用户”,其中“用户”被宣布为许多回购的合作者 这里(部署密钥),没有“协作者”,只是授予repo的直接ssh访问权限。

答案 1 :(得分:4)

不幸的是,这是github错误解释密钥对与帐户或项目之间区别的情况。

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

相反,github强制执行项目的1:N映射到基于密钥对的身份。现实世界的模拟是,有一扇门允许访问项目,可以由许多不同的人解锁。但是,一旦他们中的任何一个拿到门的钥匙,他们再也无法获得任何其他门的任何其他钥匙。

如果密钥遭到破坏,从包含漏洞的角度来看,不经常重复使用密钥是有道理的。但这只是一个很好的管理政策。在原则上阻止密钥被多次使用没有多大意义。对于某些从未重复使用过的门有一些钥匙,嗯,再次归结为政策

稍微复杂的视图是将密钥对说明为角色。你可以拥有许多密钥对,因此可以承担很多角色。私钥对您的角色进行身份验证。

Github部署项目的键映射表明角色永远不会包含多个任务。这很难实现。

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

答案 2 :(得分:1)

我花了很多心思去理解其含义并提出了这种情况。

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

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

分配和管理如此多的唯一密钥肯定令人沮丧,但GitHub如何制定策略对安全性的影响很明显:当您撤销密钥时,您可以保证撤销该密钥授予的所有访问权限,因为它只在一个地方使用。

答案 3 :(得分:0)

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

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

如果您坚持使用 Github,这里是我写的 script,它允许您通过运行 ./generateDeployKey.sh repo_owner_name repo_name 简单地传递您的回购所有者名称和存储库名称,它会为您完成所有工作并输出您可能需要复制的任何内容。

将以下内容保存到名为 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