简体   繁体   English

Git 多个 SSH macos 设置卡在一个帐户上

[英]Git multiple SSH macos setup stuck on one account

I'm having a problem using two Github SSH keys on my macos where it gets stuck on the first account used after a reboot.我在我的 macos 上使用两个 Github SSH 密钥时遇到问题,它卡在重启后使用的第一个帐户上。

Background:

My mac is set up with two Github accounts - one for a personal repository and one for a business repo.我的 mac 设置了两个 Github 帐户 - 一个用于personal存储库,一个用于business存储库。 The business repo is private.商业回购是私人的。 The personal repo is public, but only my personal account has access to push.个人回购是公开的,但只有我的个人帐户可以访问推送。

System setup:

My system and global configs are empty我的系统和全局配置为空

~/.ssh/config: ~/.ssh/配置:

# business
Host business
 HostName github.com
 User git
 IdentityFile ~/.ssh/id_rsa 
 UseKeychain yes
 AddKeysToAgent yes

#personal
Host personal
 HostName github.com
 User git
 IdentityFile ~/.ssh/id_rsa_personal
 UseKeychain yes
 AddKeysToAgent yes

personalreporoot/.git/config个人reporoot/.git/config

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[user]
    name = personalgithubaccount
    email = mypersonalemail@pm.me

[remote "origin"]
    url = git@personal:mygithubuser/personalrepo
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
    remote = origin
    merge = refs/heads/main

businessreporoot/.git/config businessreporoot/.git/config

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[user]
    name = businessgithubaccount
    email = businessemail@businessdomain.com
[remote "origin"]
    url = git@business:businessname/businessrepo
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
    remote = origin
    merge = refs/heads/main

It all worked as intended until I restarted my computer.在我重新启动计算机之前,一切都按预期工作。 I noticed the problem when I was trying to push to my personal repository.当我尝试推送到我的个人存储库时,我注意到了这个问题。 It errored saying business account didn't have permission to push to the personal repo.它错误地说企业帐户无权推送到个人回购。

I spent a number of hours trying through Stack Overflow and internet articles, most of which recommended deleting my macos Keychain git entries and removing osxkeychain from the config files, but no no avail.我花了几个小时尝试通过 Stack Overflow 和互联网文章,其中大部分建议删除我的 macos 钥匙串git条目并从配置文件中删除 osxkeychain,但无济于事。 Finally, resorting to troubleshooting 101, I rebooted and viola, I could push to the personal account and it used my personal credential now instead of my business credential.最后,求助于故障排除 101,我重新启动并中提琴,我可以推送到个人帐户,它现在使用我的个人凭据而不是我的企业凭据。

BUT -- then I went to git pull on the business repo and it said it was unable to find the repository.但是 - 然后我去了git pull业务仓库,它说它无法找到仓库。 Figuring I had the reciprocal problem and it was now stuck on my personal account, I rebooted, pulled the business repo and it worked, but now I couldn't push to my personal repository because git was trying to use my business repo credential again.考虑到我遇到了互惠问题并且它现在卡在我的个人帐户上,我重新启动,提取业务回购并且它工作,但现在我无法推送到我的个人存储库,因为 git 试图再次使用我的业务回购凭证。

I found a workaround in This SO article that linked to these instructions .我在链接到这些说明这篇 SO 文章中找到了解决方法。 It seems that running $ ssh-add -D after a reboot will make Git respect each repo's SSH key.似乎在重新启动后运行$ ssh-add -D将使 Git 尊重每个 repo 的 SSH 密钥。 But a subsequent macos restart brings the problem back.但是随后的 macOS 重启又使问题再次出现。

So...the questions are, why does Git get pinned to the first SSH credential used after a reboot, why does clearing SSH identities with $ ssh-add -D fix the problem, and how do I improve my setup so I don't have to do the workaround after restarts?所以......问题是,为什么 Git 会被固定到第一个 SSH 凭据在重新启动后使用,为什么清除 SSH 身份并使用$ ssh-add -D修复问题重新启动后不必做解决方法吗?

TL;DR TL;博士

Use IdentitiesOnly yes and IdentityFile to carefully claim to be just one person.使用IdentitiesOnly yesIdentityFile小心地声称自己只是一个人。 That is, update your sections a bit:也就是说,稍微更新您的部分:

Host business
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa
    IdentitiesOnly yes

Then make sure you use the URL ssh://business/path/to/work-repo.git for work repositories (or business:path/to/repo.git if you like the short version), and ssh://personal/path/to/personal-repo.git for the personal ones. Then make sure you use the URL ssh://business/path/to/work-repo.git for work repositories (or business:path/to/repo.git if you like the short version), and ssh://personal/path/to/personal-repo.git用于个人。

Long

So...the questions are, why does Git get pinned to the first SSH credential used after a reboot...所以......问题是,为什么 Git 会被固定到重启后使用的第一个 SSH 凭据......

It doesn't, really—and this isn't really a macOS issue, it's general across any ssh setup (though the details will vary depending on whether and how you use ssh-agent; macOS sets you up so that all new Terminal windows share one agent by default, which is normally what you want anyway).它不是,真的 - 这不是一个真正的 macOS 问题,它在任何 ssh 设置中都很普遍(尽管细节会因您是否以及如何使用 ssh-agent 而异;macOS 设置您以便所有新的终端 windows默认共享一个代理,这通常是您想要的)。 The trick to understanding this is to understand how ssh keys work: how ssh presents keys to the sites to which you wish to authenticate, and how GitHub uses these ssh keys. The trick to understanding this is to understand how ssh keys work: how ssh presents keys to the sites to which you wish to authenticate, and how GitHub uses these ssh keys.

First, let's define an ssh key.首先,让我们定义一个 ssh 密钥。 It is:这是:

  • a string of bytes you use with certain encryption algorithms;您与某些加密算法一起使用的一串字节;
  • built from public and private keys.由公钥和私钥构建。

In general, you keep the private key private to yourself and present the public key, or something encrypted with the private key, or something encrypted with both keys, or whatever: the details aren't terribly important.通常,您将私钥对自己保密并提供公钥,或者用私钥加密的东西,或者用两个密钥加密的东西,或者其他什么:细节并不是非常重要。 What we know (and care about) is that the public key gets given out, and the private key doesn't, and we can just pretend that the "key" you present to some other web site (such as github.com ) is the public key.我们知道(并且关心)的是公钥会被给出,而私钥不会,我们可以假装你提供给其他 web 站点的“密钥”(例如github.com )公钥。

Now, just offering the key itself does not prove that you are you .现在,仅仅提供钥匙本身并不能证明你就是 Someone could have sneakily copied your public key during some earlier transaction.有人可能在较早的交易中偷偷复制了您的公钥。 So GitHub (or whoever you are connecting to) will send you some encrypted, randomized data that you can only decrypt if you have your private key.因此,GitHub(或您要连接的任何人)将向您发送一些加密的随机数据,只有在您拥有私钥时才能解密 You decrypt it and thereby prove to GitHub that not only do you have the public key you sent them, but also you're the holder of the corresponding private key.您解密它,从而向 GitHub 证明您不仅拥有您发送给他们的公钥,而且您是相应私钥的持有者。

GitHub, then, take these two things into account and now know that you are who you claimed to be. GitHub,那么,考虑到这两件事,现在知道你就是你声称的那个人。 But who did you claim to be?但你声称自己是谁? Why, whoever owns that public key, that's who.为什么,谁拥有那个公钥,那就是谁。

So, suppose you have two keys, both of which work.所以,假设你有两个键,它们都可以工作。 Today, you present public key A first.今天,您首先提供公钥A。 They send you a challenge to test whether you really are the holder of the private half of A and you respond correctly.他们向您发送了一个挑战,以测试您是否真的是A的私人一半的持有者,并且您的响应正确。 Well, that settles it: you're A .好吧,这就解决了:你是A

Tomorrow, you call them up and present public key B first.明天,你打电话给他们并首先出示公钥B。 They send you a challenge, you respond correctly, and that settles it.他们给你一个挑战,你做出正确的回应,这就解决了。 You're B .你是B。

You are who you offered the first time .你是你第一次提供的人。 So the person you are , as far as GitHub is concerned, is the person you claimed to be the first time .所以你这个,就GitHub而言,就是你第一次自称的那个人。

But suppose that on Saturday (if tomorrow is Friday) you offer public key A but fail to send the right response , then offer public key B and do send the right response .但是假设在星期六(如果明天是星期五)您提供公钥A未能发送正确的响应,则提供公钥B发送正确的响应 GitHub will now think that you're B . GitHub 现在会认为你是B

So GitHub really believe that you're whoever you successfully claim to be.所以 GitHub真的相信你就是你成功声称的那个人。 That means that even if you always offer A first, revoking your private key for A will suffice to make you become B .这意味着即使你总是先提供A ,撤销A的私钥也足以让你成为B。 That's more or less what your ssh-add -D does.这或多或少是您的ssh-add -D所做的。 (Your ssh can be smart and not even offer the public key if it doesn't have the right private key, since there's no point in claiming to be A if you're planning to fail the challenge. Either way works, of course, but overall it's better not to rattle the door too much with a million key attempts: people, or properly programmed computers, will get suspicious.) (您的 ssh 可以很聪明,如果它没有正确的私钥,甚至不提供公钥,因为如果您打算在挑战中失败,那么声称自己是A毫无意义。当然,任何一种方式都有效,但总体而言,最好不要用一百万次按键尝试过多地敲门:人或正确编程的计算机会产生怀疑。)

In the end, this means you must make sure that Git doesn't offer the wrong key first.最后,这意味着您必须首先确保 Git没有提供错误的密钥。 When using the agent, you can add as many keys as you like and ssh will be able to "see" all of them.使用代理时,您可以添加任意数量的密钥,ssh 将能够“看到”所有这些密钥。 It will offer all of the working key-pairs, in some order, unless you use IdentitiesOnly yes .它将以某种顺序提供所有有效的密钥对,除非您使用IdentitiesOnly yes If you do use this line, it will offer only the keys for which there are IdentityFile lines and/or -i options.如果您确实使用此行,它将仅提供具有IdentityFile行和/或-i选项的键。 (Note that you can list more than one file, and ssh will still try multiple keys, in whatever order.) (请注意,您可以列出多个文件,并且 ssh 仍会尝试多个键,无论顺序如何。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM