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

Dav*_*bbo 78 git ssh github

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

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

为了清楚起见,我不是在寻找变通方法(创建一个虚拟用户,使用多个密钥......),但仅仅是为了解释部署密钥上的这种限制.

相关主题:

Von*_*onC 23

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

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

尽管在您的情况下不会出现这种情况(构建多个项目),但允许重用相同的ssh密钥会使两个不同的用户共享相同的ssh密钥,这将破坏身份验证的目的.

身份验证意味着:
"使用某个ssh密钥应该意味着你应该知道谁在使用它".


GitHub页面" 管理部署密钥 "使用ssh详细说明了各种帐户:

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

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

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

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

身份验证方面:

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

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

jtl*_*sey 7

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

仅供参考,Bitbucket.org 没有此限制。您可以在多个存储库上使用相同的只读访问密钥。这使得使用具有多个存储库的单个生产服务器变得非常容易

如果您坚持使用 Github,这里是我编写的一个脚本,它允许您通过运行简单地传递您的存储库所有者名称和存储库名称./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
Run Code Online (Sandbox Code Playgroud)


Jen*_*ser 6

Unfortunately, this is a scenario where github just misinterprets the distinction between a key pair and an account or project.

Since a key pair is used for authentication and authorization, it is effectively an identity. Github accounts are another identity. Connecting github accounts to key pairs effecticely establishes a 1:N mapping between github account based identities and key pair identities.

Conversely, github enforces a 1:N mapping of projects to key pair based identities. The real world analogue is that there is a door granting access to the project that can be unlocked by many different people. But once any of them gets a key to the door, they cannot get any other keys for any other doors, ever again.

如果密钥被泄露,从遏制破坏的角度考虑,不要经常重用密钥是有意义的。但这只是一个好的管理政策原则上,防止多次使用密钥没有多大意义。某些门的一些钥匙从未被重复使用,好吧,这又取决于政策


稍微复杂一点的视图是将密钥对说明为角色。您可以拥有许多密钥对,因此可以扮演许多角色。私钥可以验证您的角色。

Github对项目的部署密钥映射指出,一个角色永远不能包含多个任务。这很少是现实的。

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

  • 呵呵。当它比接受的答案更正确时,它是如何被否决的,这有点有趣。从字面上看,**没有**可以阻止与多个用户共享密钥。 (2认同)
  • 是的,有缺陷的推理变成了不必要的限制。警告至多是唯一需要采取的措施。正如这个问题的另一位评论者所说(/sf/ask/2836089861/):“采取阻力最小的途径就是将密钥复制到多台机器,从而导致更大的安全风险。GitHub 应该让用户在每个存储库的基础上选择并承担风险。” (2认同)