多个GitHub账号和SSH配置

324
我遇到了一些问题,无法使两个不同的SSH密钥/GitHub账户协同工作。我的设置如下:
一个账户可以使用 git@github.com:accountname 访问库。
另一个账户可以使用 git@github.com:anotheraccount 访问库。
每个账户都有自己的SSH密钥。这两个SSH密钥都已添加,并创建了配置文件。但我不确定配置文件是否正确。我不太清楚如何指定访问 git@github.com:accountname 库时应使用 id_rsa,而访问 git@github.com:anotheraccount 库时应使用 id_rsa_anotheraccount

1
我发现这个链接很有帮助:https://medium.freecodecamp.org/manage-multiple-github-accounts-the-ssh-way-2dadc30ccaca - jgreen
我在~/.ssh/config中有3个不同的SSH身份。学校服务器的那个有密码;另外两个用于不同的工作/个人GitHub账户没有密码。运行git pull一直失败并要求输入学校密码,尽管已经有了单独的身份文件、“IdentitiesOnly=yes”、不同的域名和主机名,所有这些都在ssh-add -l中存在……无论如何,uni密钥始终是“第一个”。必须将其部分移到.ssh/config中的其他部分下面,现在从两个GitHub账户进行git pull成功而不需要请求uni ssh密码。 - mc01
1
这个问题在这里有详细的回答:https://superuser.com/questions/232373/how-to-tell-git-which-private-key-to-use - Julius Š.
使用 sshCommand git 配置选项,检查下面的答案 - marcelocra
14个回答

394

Andy Lester的回答是准确的,但我发现需要进行一个重要的额外步骤才能使其正常工作。在尝试设置两个配置文件,一个用于个人,另一个用于工作时,我的~/.ssh/config大致如下:

Host me.github.com
    HostName github.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/me_rsa

Host work.github.com
    HostName github.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/work_rsa

在我执行ssh-add ~/.ssh/work_rsa之前,我的工作配置文件一直没有生效。在那之后,连接到github使用了正确的配置文件。以前它们默认使用第一个公钥。

如果在使用ssh-add时出现无法打开与身份验证代理的连接,请检查:https://dev59.com/fGMm5IYBdhLWcg3wIsQ2#17695338


44
谢谢!"ssh-add" 是我所缺少的。 - sage
7
请参考 http://doblock.com/articles/using-public-keys-with-multiple-github-accounts。其中的关键新信息是,您可能需要在远程URL的主机名中添加用户名(例如,在此示例中为“work”),即 git@work.github.com:work/my_repo.git(而不是“git@github.com…”)。 - BobS
1
这个可以用:http://superuser.com/questions/232373/tell-git-which-private-key-to-use - Casey
17
为了解决“它们默认使用第一个公钥”的问题,请在您的~/.ssh/config文件的Host *部分中添加IdentitiesOnly yes。这会告诉ssh实际使用您指定的IdentityFiles,而不是向服务器发送所有公钥文件。 - Mechanical snail
如果我不使用GitHub而是在公司设置了GitLab,那么“Host”和“Host”名称应该设置为什么? - JaskeyLam
显示剩余18条评论

217

我最近不得不做这个事情,需要筛选所有这些答案和它们的评论,最终将信息拼凑在一起,因此我会在这里把它全部放在一个帖子中,以方便大家:


第一步:ssh密钥
创建你需要的任何密钥对。在这个例子中,我将我的默认/原始密钥命名为'id_rsa'(这是默认值),并将我的新密钥命名为'id_rsa-work':

ssh-keygen -t rsa -C "stefano@work.com"


步骤2:ssh配置
通过创建/修改~/.ssh/config来设置多个ssh配置文件。注意“Host”值略有不同:

# Default GitHub
Host github.com
    HostName github.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa

# Work GitHub
Host work.github.com
    HostName github.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa_work


步骤三:ssh-add
可能需要执行此操作,也可能不需要。要检查,请运行以下命令列出身份指纹:

$ ssh-add -l
2048 1f:1a:b8:69:cd:e3:ee:68:e1:c4:da:d8:96:7c:d0:6f stefano (RSA)
2048 6d:65:b9:3b:ff:9c:5a:54:1c:2f:6a:f7:44:03:84:3f stefano@work.com (RSA)

如果你的条目不在那里,那么运行以下命令:
ssh-add ~/.ssh/id_rsa_work


第四步:测试
为了测试您是否正确完成了所有操作,我建议进行以下快速检查:

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

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

请注意,根据您想要使用的密钥/身份,您需要更改主机名(github / work.github)。但现在您应该可以开始了! :)

2
这是一个很好的回复。我必须使用ssh-add添加两个ssh密钥以利用配置文件。谢谢 :) - gaurav.singharoy
我想要补充的是,当你运行ssh-keygen -t rsa时,它会给你一个默认的文件名,这时你可以输入你自定义的文件名。 - Daniel Viglione
最佳答案之一。此外,这个视频也帮了我很多。https://www.youtube.com/watch?v=fnSRBRiQIU8&feature=youtu.be - TestingWithArif
好的帖子,如果这篇文章包括设置您的git配置“电子邮件”将会很好:https://help.github.com/articles/setting-your-commit-email-address-in-git/ - Dave Engineer
如果其他人在执行“ssh-agent”时遇到“连接代理错误”,请查看以下链接:https://dev59.com/K1QK5IYBdhLWcg3wSeAK - uniquegino
如果我的公司的 GitHub 存储库类似于 https://github.com/somename-internal,我应该怎么做才能在配置文件中区分个人账户(形式为 github.com)和工作存储库(带有额外的 "/somename-internal")?请问我需要做哪些更改? - undefined

56

假设alice是一个github.com用户,拥有两个或更多的私有存储库repoN。对于这个例子,我们将只使用名为repo1repo2的两个存储库。

https://github.com/alice/repo1

https://github.com/alice/repo2

您需要从这些存储库中拉取而不需要在服务器上或多个服务器上输入密码。例如,您想执行git pull origin master,并且希望此操作在不要求密码的情况下完成。

您不喜欢处理ssh-agent,您已经发现(或正在发现)~/.ssh/config文件,该文件让您的ssh客户端根据主机名和用户名知道要使用哪个私钥,只需简单的配置条目即可,如下所示:

Host github.com
  HostName github.com
  User git
  IdentityFile /home/alice/.ssh/alice_github.id_rsa
  IdentitiesOnly yes

所以你已经创建了自己的 (alice_github.id_rsa, alice_github.id_rsa.pub) 密钥对,然后你也去修改了你存储库的 .git/config 文件,并将你的远程 origin 的 URL 修改为像这样:

[remote "origin"]
        url = "ssh://git@github.com/alice/repo1.git"

最后,您需要进入存储库的“设置>部署密钥”部分,并添加“alice_github.id_rsa.pub”的内容。这样,您就可以毫无问题地执行“git pull origin master”,而无需输入密码。
但第二个存储库怎么办?
因此,您的直觉是获取该密钥并将其添加到repo2的“部署密钥”中,但是github.com会报错并告诉您该密钥已被使用。
现在,您需要生成另一个密钥(当然不带密码)(使用“ssh-keygen -t rsa -C“ alice@alice.com”),为了避免出现混乱,现在将以以下方式命名您的密钥:
- repo1密钥对:(repo1.alice_github.id_rsa,repo1.alice_github.id_rsa.pub) - repo2密钥对:(repo2.alice_github.id_rsa,repo2.alice_github.id_rsa.pub)
现在,您需要将新的公钥放置在github.com的repo2的“部署密钥配置”中,但现在您面临SSH问题。
如果存储库托管在同一github.com域上,那么SSH如何知道要使用哪个密钥?
您的.ssh / config文件指向github.com,当执行拉操作时,它不知道要使用哪个密钥。
因此,我发现了一个github.com的技巧。您可以告诉您的SSH客户端每个存储库位于不同的github.com子域中,在这些情况下,它们将是repo1.github.com和repo2.github.com。
因此,第一件事是编辑存储库克隆的.git / config文件,以便它们看起来像这样:
[remote "origin"]
        url = "ssh://git@repo1.github.com/alice/repo1.git"

针对repo2

[remote "origin"]
        url = "ssh://git@repo2.github.com/alice/repo2.git"

然后,在您的.ssh/config文件中,现在您将能够为每个子域输入配置 :)

Host repo1.github.com
  HostName github.com
  User git
  IdentityFile /home/alice/.ssh/repo1.alice_github.id_rsa
  IdentitiesOnly yes

Host repo2.github.com
  HostName github.com
  User git
  IdentityFile /home/alice/.ssh/repo2.alice_github.id_rsa
  IdentitiesOnly yes

现在你可以从两个代码仓库中执行git pull origin master而无需输入密码。
如果您有多台机器,可以将密钥复制到每台机器上并重用它们,但我建议为每台机器和代码仓库生成1个密钥。虽然您需要处理更多的密钥,但如果其中一个密钥被泄露,您将不太容易受到攻击。

2
.ssh/config中指定与主机匹配的子域是关键步骤 - 非常感谢。 - Mike Miller
Host 组件的解释很好,谢谢。 - Des
嗨,我有两台机器,你能告诉我如何将一台笔记本电脑的密钥复制到另一台上吗?是先复制然后重命名吗?这样行得通吗? - Shashank Bhatt
你的密钥通常在你的~/.ssh文件夹里面,只需以任何方式将文件复制过去即可。 - Gubatron

43

我在Github上有两个账户,以下是我在Linux中所做的事情,使其正常运行。

密钥

  • 使用ssh-keygen 创建2对RSA密钥,并适当地进行命名,以便生活更轻松。
  • 通过ssh-add path_to_private_key 将私钥添加到本地代理。
  • 对于每个Github账户,上传一个(不同的)公钥。

配置

~/.ssh/config

Host github-kc
    Hostname        github.com
    User git
    IdentityFile    ~/.ssh/github_rsa_kc.pub
    # LogLevel DEBUG3

Host github-abc
    Hostname        github.com
    User git
    IdentityFile    ~/.ssh/github_rsa_abc.pub
    # LogLevel DEBUG3

为仓库设置远程url:

  • 对于主机中的仓库github-kc:

git remote set-url origin git@github-kc:kuchaguangjie/pygtrans.git
  • 在主机github-abc中的存储库:

  • git remote set-url origin git@github-abc:abcdefg/yyy.git
    

    说明

    ~/.ssh/config中的选项:

    • Host github-<identify_specific_user>
      Host 可以是任何可以标识主机和帐户的值,它不需要是一个真实的主机, 例如 github-kc 标识我本地笔记本电脑上 Github 上的一个帐户。

      在为 git 存储库设置远程 URL 时,这就是要放在 git@ 后面的值,这就是存储库映射到 Host 的方式,例如:git remote set-url origin git@github-kc:kuchaguangjie/pygtrans.git


    • [以下是Host的子选项]
    • Hostname
      指定实际的主机名,对于 GitHub,只需使用 github.com
    • User git
      对于 GitHub,用户始终为 git
    • IdentityFile
      指定要使用的密钥,只需将公钥的路径放入其中。
    • LogLevel
      指定日志级别以进行调试,如果出现任何问题,则 DEBUG3 提供最详细的信息。


    可爱--不需要ssh-add path_to_private_key--这可能是因为在这种情况下代理不是必需的。配置文件明确定义了密钥路径。 - Mark Chackerian
    4
    我认为您不需要使用 ssh-add,因为您的密钥没有密码保护,或者(如果您正在使用 Mac)OSX 密钥链正在处理它。ssh-add 可以避免您每次访问密钥时都需要输入密码。 - Ashhar Hasan
    很好,直接了当,正是我所需要的。谢谢。 - Dhaval
    非常好的解释。关键在于使用“git remote set-url ...”命令告诉git使用正确的主机引用来指定使用哪个ssh密钥! - EricX

    19

    在您的~/.ssh/config文件中使用IdentityFile参数:

    Host github.com
        HostName github.com
        IdentityFile ~/.ssh/github.rsa
        User petdance
    

    谢谢,但这并不完全准确。我找到了答案并在下面分享了。 - radesix
    我非常确定我的方法在你的情况下会起作用。你可以识别不同的用户和不同的身份文件。只需要在配置段落中给每个人一个不同的Host参数就行了。 - Andy Lester
    1
    根据我找到的链接,Andy,我需要从主机中删除“.com”。一旦我这样做了,它就正常工作了。 - radesix

    16

    编辑ssh配置文件(正如其他答案所建议的那样)可能不是最简单的选择。另一个可能更简单的方法是在个别存储库中配置使用不同的(例如非默认的)ssh密钥。

    在要使用不同密钥的存储库内运行以下命令:

    git config core.sshCommand 'ssh -i ~/.ssh/id_rsa_anotheraccount'
    

    如果您的密钥受到密码保护,而您不想每次都输入密码,您需要将其添加到ssh-agent。以下是如何在UbuntumacOS中执行此操作。

    您还可以使用全局git配置和条件包含(请参见示例),以将此方法扩展到多个存储库。


    1
    你甚至可以在全局的.gitconfig中使用includeIf进行配置。 - marcelocra
    这个答案对我来说是最有用的。我不想每次想要克隆东西时都手动更改URL,但这很容易添加到我已经在使用的脚本中,以便在开始工作之前为每个工作目录设置我的电子邮件地址和其他身份详细信息。 - tripleee

    9

    我花了很多时间来理解所有步骤。所以让我们逐步描述:

    1. Create new identity file using ssh-keygen -t rsa. Give it an alternative like proj1.id_rsa and hit with no doubt because you don't need a passphrase.
    2. Add new section in .ssh/config:

      Host proj1.github.com
          HostName github.com
          PreferredAuthentications publickey
          IdentityFile ~/.ssh/proj1.id_rsa
      
    考虑第一部分,并注意到 proj1.github.com,我们稍后会回到这一部分。
    3.将身份添加到 ssh 代理中ssh-add ~/.ssh/proj1.id_rsa 4.这是我第一次搞砸的事情-现在当您想克隆 proj1 存储库时,您需要使用配置文件中的主机 proj1.github.comgit clone git@proj1.github.com
    一个很好的教程: 链接 不要混淆主机。

    感谢提供教程链接!您有一个错别字:密钥名称 id_rsa_proj1proj1_id_rsa 实际上应该相同。您还可以将教程中关于 .git/config 设置的部分添加到您的答案中。 - cezar
    你还有一个拼写错误:proj1.id_rsaproj1_id_rsa不同。 - cezar

    5
    在我的情况下,以上解决方案都无法解决我的问题,但是ssh-agent可以。基本上,我执行了以下操作:
    1. 使用下面显示的ssh-keygen生成密钥对。它将生成一对密钥(在此示例中为.\keyfile.\keyfile.pub
    2. ssh-keygen -t rsa -b 4096 -C "yourname@yourdomain" -f keyfile

    3. 上传keyfile.pub到git提供者
    4. 在您的计算机上启动ssh-agent(您可以使用ps -ef | grep ssh-agent检查它是否已运行)
    5. 运行ssh-add .\keyfile以添加凭据
    6. 现在,您可以运行git clone git@provider:username/project.git

    3
    作为@stefano回答的补充, 当为另一个帐户生成新的SSH密钥时,最好使用带有 -f 的命令。
    ssh-keygen -t rsa -f ~/.ssh/id_rsa_work -C "your@mail.com"
    

    由于在路径~/.ssh/中不存在id_rsa_work文件,我手动创建了这个文件,但是它并没有起作用 :(


    3

    使用多个Git账户并且克隆时不需要进行任何更改的最简单方法是将您的用户名添加到ssh配置中。

    1. 打开~/.ssh/config。如果不存在,请创建
    2. 按照以下方式添加您的主机条目
    Host github.com:<YOUR_GITHUB_USERNAME>
      AddKeysToAgent yes
      IdentityFile ~/.ssh/<YOUR_SSH_KEY_FILENAME>
    

    请将<YOUR_GITHUB_USERNAME>替换为您想要的GitHub用户名(个人或工作)。将<YOUR_SSH_KEY_FILENAME>替换为.ssh文件夹中的密钥文件名(例如:id_ed25519)。 为您想要维护的每个GitHub帐户添加主机记录。
    现在,git clone将变得简单,只需使用git clone github.com:<YOUR_GITHUB_USERNAME>/your-repo.git即可。克隆时不需要记住自定义的gihub域名 ;-)
    这里有更多信息的gist:https://gist.github.com/udantha/fed5439630eaf4651272f4fba6e1c6a3

    这实际上是最佳答案之一。其中的:<YOUR_GITHUB_USERNAME>部分非常重要。原因在于,假设您想将一个私有的git仓库引用为package.json文件中的一个包,如果您最终需要使用类似下面的内容:"package": "git+ssh://git@new-host:<user>/<repo>.git"这意味着每个人都必须更新他们的.ssh配置文件以与您的相匹配。但是,如果您包含了:<YOUR_GITHUB_USERNAME>,那么可以确保每个人无论是否拥有多个ssh密钥,都可以直接访问它。 - Jim Heising
    这实际上是最好的答案之一。:<YOUR_GITHUB_USERNAME> 部分非常重要。原因是,假设你想在 package.json 文件中引用一个私有的 git 仓库作为一个包,如果最终你不得不使用类似这样的东西:"package" : "git+ssh://git@new-host:<user>/<repo>.git"这意味着每个人都必须更新他们的 .ssh 配置文件以匹配你的。但是,如果你包含 :<YOUR_GITHUB_USERNAME>,那么你可以确保每个人都可以直接访问它,无论他们是否有多个 ssh 密钥。 - undefined
    但是我可以在需要直接推送的地方使用不同的用户名/组织。在这种情况下,我们需要添加多个“host:username”组合。基于目录的解决方案可以很好地代替配置ssh配置文件更新git配置文件core.sshcommand = "ssh -i ~/.ssh/<ssh-key>" - Snigdhajyoti

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接