github部署密钥:如何为单个机器授权多个存储库

时间:2012-07-25 18:22:23

标签: github ssh-keys

所以,我有一个主持人,称之为rob。我在rob上使用了ssh-keygen来获取一个公钥,我在为存储库cheech添加一个新的部署密钥屏幕时给了github。现在我想在chong上部署rob。但是,如果我在github上为存储库chong添加新的部署密钥屏幕,并粘贴我在rob上生成的公钥,则会显示key already in use。我想,如果他们使用了密钥,我可以在chong上克隆rob,但是会拒绝许可。

很明显,这比我想象的要复杂得多,它涉及多个键或其他东西。我应该怎样做才能在chong上克隆rob

感谢您的帮助。

10 个答案:

答案 0 :(得分:62)

一旦将密钥作为部署密钥附加到一个仓库,就不可能 用于另一个回购。如果您在设置时遇到此错误 部署密钥,然后你需要修改你的遥控器并设置你的 ~/.ssh/config文件使用不存在的 github.com主机名 ssh将能够用于为您选择正确的ssh部署密钥 库中。

# first we remove the origin
$ git remote -v
origin  git@github.com:username/foo.git (fetch)
origin  git@github.com:username/foo.git (push)
$ git remote rm origin

# here we add a new origin using a host nickname called
# foo.github.com that we will reference with a Host stanza in our
# ~/.ssh/config to specify which key to use with which fake hostname.
$ git remote add origin git@fake-hostname-foo.github.com:username/foo.git
$ git remote -v
origin  git@fake-hostname-foo.github.com:username/foo.git (fetch)
origin  git@fake-hostname-foo.github.com:username/foo.git (push)

为您的存储库生成部署密钥并为其命名 合理的如:

$ ssh-keygen -t rsa -f ~/.ssh/id_rsa-foo -C https://github.com/username/foo
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/username/.ssh/id_rsa-foo.
Your public key has been saved in /home/username/.ssh/id_rsa-foo.pub.
The key fingerprint is:
c0:ff:ee:34:24:11:5e:6d:7c:4c:b1:a0:de:ad:be:ef https://github.com/username/foo
The key's randomart image is:
+--[ RSA 2048]----+
|  E   o..o.oo.   |
| M o o o .+CoW   |
|  + o = o. ..    |
| .   . +         |
|        S        |
|       o .       |
|        +        |
|       . o       |
|        ..o.     |
+-----------------+

一旦你 added the deploy key 然后,您需要将以下节添加到~/.ssh/config文件中:

Host fake-hostname-foo.github.com
    Hostname github.com
    IdentityFile ~/.ssh/id_rsa-foo

现在您可以使用以下方法进行测试:

$ ssh -T git@fake-hostname-foo.github.com
Hi username! You've successfully authenticated, but GitHub
does not provide shell access.

答案 1 :(得分:11)

我找到的最简单的解决方案是here

1)输入此命令(无论你需要多少键,都可以这样做):

  

ssh-keygen -t rsa -C“your_email@example.com”

2)当提示下面的语句时,键入一个唯一的名称(即foo1_rsa)。该文件将在您当前的目录中创建,如果您想要整洁,可能需要将其移动到.ssh:< / p>

  

输入要保存密钥的文件(/Users/you/.ssh/id_rsa):[按Enter键]

3)更新SSH配置文件:

  

vi~ / .ssh / config

可能是空的:

Host cheech github.com
Hostname github.com
IdentityFile ~/.ssh/foo1_rsa

Host chong github.com
Hostname github.com
IdentityFile ~/.ssh/foo2_rsa

答案 2 :(得分:3)

github的部署密钥是唯一的......您必须为其他存储库生成新密钥。再次运行ssh-keygen

请参阅github文档:https://help.github.com/articles/managing-deploy-keys

答案 3 :(得分:2)

如果您对GitHub帐户中的所有私有存储库的rob访问权限感到满意,则可以将该密钥作为部署密钥从cheech中删除,然后将其作为SSH密钥添加到您的GitHub帐户整体。这样,robcheech都可以chong次访问。

如果您的帐户中有其他您不希望rob访问的存储库,则无效。

如果您需要更精细的控制,则需要在rob上生成其他密钥,并将它们作为部署密钥分配给特定的存储库。

答案 4 :(得分:2)

我知道这已经有5年多了,但是这个热门问题没有被接受的答案,所以我认为这是考虑清洁度和未来可读性的最佳方式:

添加将用户部署到您的论坛

第1步:在您单位的域中为新的部署用户创建新的电子邮件地址。类似于 deploy@organisation.example.com

第2步:使用该邮箱创建新的GitHub帐户(GitHub calls these "machine users")为其提供一个用户名,例如 deploy-ExampleOrganisation ,这样它的作用就很明确了。

第3步:使用以下命令在您的服务器上创建一个名为“deploy”的用户:

useradd -d /home/deploy -m deploy

deploy @ servername 生成SSH密钥,指定无密码, /home/deploy/.ssh/id_rsa 作为文件位置:

ssh-keygen -t rsa -b 4096 -C "deploy@servername"

/home/deploy/.ssh/id_rsa.pub 的内容添加为新 deploy-ExampleOrganisation GitHub帐户的SSH密钥:转到设置&gt; SSH和GPG密钥&gt;新的SSH密钥

第4步:在您的组织中创建一个名为“只读部署用户”的团队,将新用户添加到团队并为团队提供读访问权限到任何将要部署的回购。 (如果您没有组织帐户,您仍然可以授予此用户访问多个私人存储库的权限)

步骤5:添加您自己的个人计算机的SSH密钥以部署用户的授权密钥文件(/ home / deploy / .ssh / authorized_keys)以便您(或您的)部署脚本)可以在部署代码时以部署身份登录。

<强>轰!就是这样...... 你现在拥有一个干净且自我记录的流程。

P.S。我尝试了aculich高度评价的答案,但是感觉很脏,用虚假的主机名来搞乱,我想,如果我在几年后回到这里,我会轻易弄清楚我做了什么来创建所有的键并理解如何SSH配置文件使那些有趣的不存在的远程地址工作?可能不是!

部署用户优于假主机名方法的优势:

  • 没有黑客!它是具有明确名称的标准用户帐户,通过真实主机名访问回购。
  • 少量钥匙漂浮在周围。
  • 如果/当您迁移到其他服务器时,很容易为您的Deploy用户提供所有这些服务器的帐户,只需在她的GitHub帐户中添加1个新密钥,她在新服务器上的帐户就可以部署代码了。
  • 部署用户只有低权限对只有团队中列出的存储库的只读访问权限,并且您的个人SSH密钥不在服务器上,所以如果一些讨厌的人确实可以访问您的服务器,他们就不会惹恼所有你的回购也。
  • 部署工具配置文件(例如Capistrano)不要弄脏包含那些令人困惑的虚假主机名。 (当他们开始在服务器之外传播时,我真的对这种方法感到不舒服。)
  • 如果你忘了你多年来如何做到这一点,文件所有权将引导你到部署用户ls -la,SSH密钥将引导你到GitHub帐户名ssh -T git@github.com,然后希望你完全恢复了速度。
  • 最后......这是GitHub推荐的方法。

答案 5 :(得分:2)

正如其他人指出的那样,部署密钥是唯一的。到目前为止,最好的方法是ssh .config别名,但我发现了一种更简洁的方法:

这可以通过自定义GIT_SSH_COMMAND来完成。由于ssh .config仅获取主机,因此您必须创建别名以处理不同的路径。另外,作为GIT_SSH_COMMAND的git CLI sends the path of the repo,您可以在git和ssh之间添加的自定义脚本中拦截请求。

您可以创建一个解决方案,在其中提取路径并添加相关的身份文件(如果在服务器上可用)。

可以找到一种执行此操作的方法here

用法:

cp deploy_key_file ~/.ssh/git-keys/github-practice
GIT_SSH_COMMAND=custom_keys_git_ssh git clone git@github.com:github/practice.git

您可以全局定义GIT_SSH_COMMAND=custom_keys_git_ssh,而只需将密钥文件添加到~/.ssh/git-keys/文件夹中。

答案 6 :(得分:1)

使用我的小"R"模块github-add-key可以轻松管理多个GitHub部署密钥。它使用this极好的答案中描述的方法,您需要的只是

  

$ github-add-key rob / chong

在您本地克隆的npm中,并按照简单的自动化流程进行操作。

答案 7 :(得分:0)

您还可以创建一个ssh包装器并将其作为GIT_SSH传递。此选项的优点是您不必更改git遥控器。 https://stackoverflow.com/a/14221028/3461

答案 8 :(得分:0)

虽然Pimkin的想法很棒,但我不想为此安装node,所以我在bash中创建了类似的东西:

https://gist.github.com/blvz/8eeebacae11011c25fc79eff12f49ae9

安装并使用:

curl https://gist.githubusercontent.com/blvz/8eeebacae11011c25fc79eff12f49ae9/raw/6f2f7f3709a0fe852d8a3a5bb125325e3ffbc7d8/gh-deploy-clone.sh > /usr/local/bin/gh-deploy-clone
chmod +x /usr/local/bin/gh-deploy-clone

gh-deploy-clone user/repo

# You can also give it a name, in case
# you have multiple deploy targets:

gh-deploy-clone user/repo staging

答案 9 :(得分:0)

我在这里没有看到任何好的或简单的答案,因此我认为自己应该提出解决方案。我不喜欢您需要更改域名,使用包装器脚本,拧紧钥匙圈或弄乱.ssh配置文件的答案。 SSH只是git的传输方式,所以我不想用一些技巧和设置来填充我重要的ssh文件夹和配置,以使用多个部署密钥,这些密钥一旦设置我就不会在意,每个回购仅包含一个。这应该是git config-确实如此。

此外,为什么不将凭据保存在存储库的.git文件夹中,以便删除存储库文件夹也删除部署密钥?

假设/ tmp / deploy_key是您的私有部署密钥的初始(临时)位置。

# Initial clone of repo    
GIT_SSH_COMMAND="ssh -i /tmp/deploy_key" git clone git@github.com:folder/reponame.git

# cd to the folder to assure we only change config for the repo instead of user/global.
cd reponame
# Could probably just mv instead of cp/chmod/rm the key but lets be precise
cp /tmp/deploy_key ./.git/deploy_key
chmod 600 ./.git/deploy_key
rm /tmp/deploy_key

# This is the magic - note the backslash escaping the $ as PWD is always the repo's
# folder when pulling or pushing etc... and at git (run) command time $PWD is the
# repo's root folder.
git config core.sshCommand "ssh -i \$PWD/.git/deploy_key"

当然,您也可以将密钥存储在其他位置,并使用没有$ PWD作为部署密钥的绝对路径:-

# Initial clone of repo    
GIT_SSH_COMMAND="ssh -i /path/to/a/deploy_key" git clone git@github.com:folder/reponame.git
# cd to repo to configure only for this repo
cd reponame
git config core.sshCommand "ssh -i /path/to/a/deploy_key"

但是我更喜欢将其保存在存储库的内部.git文件夹中,因此,如果我删除存储库的文件夹,我知道没有凭证可以挂了,毕竟每个部署密钥只能有一个存储库。