43

我有一个主机,叫它rob。我使用 ssh-keygen onrob获取了一个公钥,我在为存储库添加新的部署密钥屏幕中将其提供给了 github cheech。现在我也想部署chongrob但是,如果我转到 github 上为存储库添加新的部署密钥屏幕,并粘贴我在其chong上生成的公钥。我想,如果密钥正在使用中,我可以克隆,但表示权限被拒绝。robkey already in usechongrob

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

4

10 回答 10

71

一旦一个密钥作为部署密钥附加到一个存储库,它就不能在另一个存储库上使用。如果您在设置部署密钥时遇到此错误,那么您需要修改您的远程并设置您的 ~/.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.     |
+-----------------+

添加部署密钥后,您 需要将以下节添加到~/.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.
于 2012-10-03T09:04:46.137 回答
12

我发现的最简单的解决方案在此处概述。

1)输入这个命令(你会为你需要的许多键执行此操作):

ssh-keygen -t rsa -C "your_email@example.com"

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

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

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
于 2014-01-15T05:59:04.520 回答
3

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

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

于 2012-07-25T21:44:42.023 回答
2

如果您愿意授予rob对 GitHub 帐户中所有私有存储库的访问权限,则可以将密钥作为部署密钥从其中删除cheech,然后将其作为 SSH 密钥添加到整个 GitHub 帐户中。这将rob允许同时访问cheechchong

如果您的帐户中有您不想rob访问的其他存储库,这将不起作用。

如果您需要更细粒度的控制,您将需要生成额外的密钥rob并将它们作为部署密钥分配给特定的存储库。

于 2012-08-02T18:59:42.027 回答
2

我知道这已经有 5 年以上的历史了,但是对于这个流行的问题没有公认的答案,所以这是我认为考虑到清洁度和未来可读性的最佳方法:


将部署用户添加到您的团队

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

第 2 步:使用该邮箱创建一个新的 GitHub 帐户(GitHub 将这些称为“机器用户”)给它一个像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"

在新的 deploy-ExampleOrganisation GitHub 帐户上添加/home/deploy/.ssh/id_rsa.pub的内容作为 SSH 密钥:转到Settings > SSH and GPG keys > New SSH Key

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

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

繁荣!就是这样......您现在拥有一个干净且自我记录的流程。


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

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

  • 没有黑客!它是具有明确名称的标准用户帐户,通过真实主机名访问存储库。
  • 更少的键浮动。
  • 如果/当您确实移动到其他服务器时,很容易为您的 Deploy 用户在所有这些服务器上提供一个帐户,只需向她的 GitHub 帐户添加 1 个新密钥,她在新服务器上的帐户就可以部署代码了。
  • 部署用户只有低权限只读访问团队中列出的存储库,并且您的个人 SSH 密钥远离服务器,因此如果某些讨厌的人确实获得了对您服务器的访问权限,他们无法对您的所有存储库造成严重破坏也是。
  • 部署工具配置文件(例如 Capistrano)不会弄脏包含那些令人困惑的假主机名。(当他们开始在服务器之外传播时,我真的对这种方法感到不舒服。)
  • 如果你忘记了你在几年内是如何做到这一点的,文件所有权将引导你到部署用户ls -la,SSH 密钥将引导你到 GitHub 帐户名ssh -T git@github.com,希望你能再次完全跟上速度。
  • 最后……这是GitHub推荐的方法。
于 2017-10-11T18:39:28.907 回答
2

Managing multiple GitHub deploy keys may be made easy with my tiny npm module github-add-key. It uses the approach described in this great answer, and all you'll need is

$ github-add-key rob/chong

in your locally cloned rob/chong and follow the simple automated process.

于 2017-02-07T07:20:43.607 回答
2

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

这可以通过自定义 GIT_SSH_COMMAND 来完成。由于 ssh .config 仅获取主机,因此您必须创建别名来处理不同的路径。或者,当 git CLI将 repo 的路径发送到 GIT_SSH_COMMAND 时,您可以在自定义脚本中拦截请求,添加在 git 和 ssh 之间。

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

可以在此处找到执行此操作的一种方法。

用法:

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/文件夹。

于 2020-06-08T11:41:53.223 回答
2

虽然 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
于 2017-08-26T08:39:29.660 回答
1

我在这里没有看到任何好的或简单的答案,所以我想我会提出我的解决方案。我不喜欢需要更改域名、使用包装脚本、搞乱密钥环或弄乱 .ssh 配置文件的答案。SSH 只是 git 的传输方式,所以我不想用黑客和设置填充我的重要 ssh 文件夹和配置,以使用多个部署密钥,一旦设置我不关心并且每个仓库只有一个。这应该是一个 git config - 它是。

此外,为什么不将凭据保留在 repo 的 .git 文件夹中,这样如果删除 repos 文件夹,就会删除部署密钥?

假设 /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"

但我更喜欢将它保存在 repo 的内部 .git 文件夹中,所以如果我删除 repo 的文件夹,我知道周围没有凭据,毕竟每个部署密钥只能有一个 repo。

于 2018-09-26T00:08:00.920 回答
0

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

于 2014-06-03T20:55:06.413 回答