简体   繁体   English

为给定域的 git push 指定 SSH 密钥

[英]Specify an SSH key for git push for a given domain

I have the following use case: I would like to be able to push to git@git.company.com:gitolite-admin using the private key of user gitolite-admin , while I want to push to git@git.company.com:some_repo using 'my own' private key.我有以下用例:我希望能够使用用户gitolite-admin的私钥推送到git@git.company.com:gitolite-admin admin ,而我想推送到git@git.company.com:some_repo使用“我自己的”私钥。 AFAIK, I can't solve this using ~/.ssh/config , because the user name and server name are identical in both cases. AFAIK,我无法使用~/.ssh/config解决这个问题,因为两种情况下的用户名和服务器名都是相同的。 As I mostly use my own private key, I have that defined in ~/.ssh/config for git@git.company.com .由于我主要使用自己的私钥,因此我在~/.ssh/config中为git@git.company.com定义了该私钥。 Does anyone know of a way to override the key that is used for a single git invocation?有谁知道一种方法来覆盖用于单个git调用的密钥?

(Aside: gitolite distinguishes who is doing the pushing based on the key, so it's not a problem, in terms of access, ownership and auditing, that the user@server string is identical for different users.) (顺便说一句:gitolite 根据密钥区分谁在进行推送,因此就访问、所有权和审计而言,user@server 字符串对于不同用户来说是相同的,这不是问题。)

Even if the user and host are the same, they can still be distinguished in ~/.ssh/config .即使用户和主机相同,仍然可以在~/.ssh/config中进行区分。 For example, if your configuration looks like this:例如,如果您的配置如下所示:

Host gitolite-as-alice
  HostName git.company.com
  User git
  IdentityFile /home/whoever/.ssh/id_rsa.alice
  IdentitiesOnly yes

Host gitolite-as-bob
  HostName git.company.com
  User git
  IdentityFile /home/whoever/.ssh/id_dsa.bob
  IdentitiesOnly yes

Then you just use gitolite-as-alice and gitolite-as-bob instead of the hostname in your URL:然后,您只需使用gitolite-as-alicegitolite-as-bob而不是 URL 中的主机名:

git remote add alice git@gitolite-as-alice:whatever.git
git remote add bob git@gitolite-as-bob:whatever.git

Note笔记

You want to include the option IdentitiesOnly yes to prevent the use of default ids.您想包含选项IdentitiesOnly yes以防止使用默认 ID。 Otherwise, if you also have id files matching the default names, they will get tried first because unlike other config options (which abide by "first in wins") the IdentityFile option appends to the list of identities to try.否则,如果您还有与默认名称匹配的 id 文件,它们将首先被尝试,因为与其他配置选项(遵守“先入先出”)不同, IdentityFile选项附加到要尝试的身份列表中。 See: https://serverfault.com/questions/450796/how-could-i-stop-ssh-offering-a-wrong-key/450807#450807请参阅: https ://serverfault.com/questions/450796/how-could-i-stop-ssh-offering-a-wrong-key/450807#450807

You can utilize git environment variable GIT_SSH_COMMAND .您可以利用 git 环境变量GIT_SSH_COMMAND Run this in your terminal under your git repository:在您的 git 存储库下的终端中运行它:

GIT_SSH_COMMAND='ssh -i ~/.ssh/your_private_key' git submodule update --init

Replace ~/.ssh/your_private_key with the path of ssh private key you wanna use.~/.ssh/your_private_key替换为您要使用的 ssh 私钥的路径。 And you can change the subsequent git command (in the example is git submodule update --init ) to others like git pull , git fetch , etc.您可以将后续的 git 命令(在示例中为git submodule update --init )更改为其他命令,如git pullgit fetch等。

Configure your repository using git config使用git config配置存储库

git config --add --local core.sshCommand 'ssh -i <<<PATH_TO_SSH_KEY>>>'

This applies to your local repository only.这仅适用于您的本地存储库

An alternative approach to the one offered above by Mark Longair is to use an alias that will run any git command, on any remote, with an alternative SSH key. Mark Longair 提供的上述方法的另一种方法是使用别名,该别名将在任何远程上运行任何git 命令,并带有备用 SSH 密钥。 The idea is basically to switch your SSH identity when running the git commands.这个想法基本上是在运行 git 命令时切换您的 SSH 身份。

Advantages relative to the host alias approach in the other answer:相对于其他答案中的主机别名方法的优势:

  • Will work with any git commands or aliases, even if you can't specify the remote explicitly.即使您无法明确指定remote ,也可以使用任何git 命令或别名。
  • Easier to work with many repositories because you only need to set it up once per client machine, not once per repository on each client machine.更容易使用许多存储库,因为您只需要为每台客户端机器设置一次,而不是每台客户端机器上的每个存储库一次。

I use a few small scripts and a git alias admin .我使用了一些小脚本和一个 git alias admin That way I can do, for example:这样我就可以做到,例如:

git admin push 

To push to the default remote using the alternative ("admin") SSH key.使用备用(“admin”)SSH 密钥推送到默认远程。 Again, you could use any command (not just push ) with this alias.同样,您可以使用带有此别名的任何命令(不仅仅是push )。 You could even do git admin clone ... to clone a repository that you would only have access to using your "admin" key.您甚至可以执行git admin clone ...来克隆您只能使用“管理员”密钥访问的存储库。

Step 1: Create the alternative SSH keys, optionally set a passphrase in case you're doing this on someone else's machine.第 1 步:创建备用 SSH 密钥,可选择设置密码,以防您在其他人的计算机上执行此操作。

Step 2: Create a script called “ssh-as.sh” that runs stuff that uses SSH, but uses a given SSH key rather than the default:第 2 步:创建一个名为“ssh-as.sh”的脚本,该脚本运行使用 SSH 的东西,但使用给定的 SSH 密钥而不是默认密钥:

#!/bin/bash
exec ssh ${SSH_KEYFILE+-i "$SSH_KEYFILE"} "$@"

Step 3: Create a script called “git-as.sh” that runs git commands using the given SSH key.第 3 步:创建一个名为“git-as.sh”的脚本,该脚本使用给定的 SSH 密钥运行 git 命令。

#!/bin/bash
SSH_KEYFILE=$1 GIT_SSH=${BASH_SOURCE%/*}/ssh-as.sh exec git "${@:2}"

Step 4: Add an alias (using something appropriate for “PATH_TO_SCRIPTS_DIR” below):第 4 步:添加别名(使用下面的“PATH_TO_SCRIPTS_DIR”适当的名称):

# Run git commands as the SSH identity provided by the keyfile ~/.ssh/admin
git config --global alias.admin \!"PATH_TO_SCRIPTS_DIR/git-as.sh ~/.ssh/admin"

More details at: http://noamlewis.wordpress.com/2013/01/24/git-admin-an-alias-for-running-git-commands-as-a-privileged-ssh-identity/更多详情请访问:http: //noamlewis.wordpress.com/2013/01/24/git-admin-an-alias-for-running-git-commands-as-a-privileged-ssh-identity/

I've cribbed together and tested with github the following approach, based on reading other answers, which combines a few techniques:在阅读其他答案的基础上,我将以下方法拼凑在一起并使用 github 进行了测试,该方法结合了一些技术:

  • correct SSH config正确的 SSH 配置
  • git URL re-writing git URL 重写

The advantage of this approach is, once set up, it doesn't require any additional work to get it right - for example, you don't need to change remote URLs or remember to clone things differently - the URL rewriting makes it all work.这种方法的优点是,一旦设置好,它就不需要任何额外的工作来让它正确 - 例如,您不需要更改远程 URL 或记住以不同的方式克隆东西 - URL 重写使一切正常.

~/.ssh/config

# Personal GitHub
Host github.com
  HostName github.com
  User git
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/github_id_rsa

# Work GitHub
Host github-work
  HostName github.com
  User git
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/work_github_id_rsa

Host *
  IdentitiesOnly yes

~/.gitconfig

[user]
    name = My Name
    email = personal@personal.email

[includeIf "gitdir:~/dev/work/"]
    path = ~/dev/work/.gitconfig

[url "github-work:work-github-org/"]
    insteadOf = git@github.com:work-github-org/

~/dev/work/.gitconfig

[user]
    email = work@work.email

As long as you keep all your work repos under ~/dev/work and personal stuff elsewhere, git will use the correct SSH key when doing pulls/clones/pushes to the server, and it will also attach the correct email address to all of your commits.只要您将所有工作存储库保存在 ~/dev/work 和其他地方的个人资料下,git 将在对服务器执行拉取/克隆/推送时使用正确的 SSH 密钥,并且它还会将正确的电子邮件地址附加到所有你的承诺。

References:参考:

From git 2.10 upwards it is also possible to use the gitconfig sshCommand setting.从 git 2.10 开始,也可以使用 gitconfig sshCommand 设置。 Docs state :文档状态

If this variable is set, git fetch and git push will use the specified command instead of ssh when they need to connect to a remote system.如果设置了这个变量,当 git fetch 和 git push 需要连接到远程系统时,它们将使用指定的命令而不是 ssh。 The command is in the same form as the GIT_SSH_COMMAND environment variable and is overridden when the environment variable is set.该命令与 GIT_SSH_COMMAND 环境变量的形式相同,并在设置环境变量时被覆盖。

An usage example would be: git config core.sshCommand "ssh -i ~/.ssh/[insert_your_keyname]一个使用示例是: git config core.sshCommand "ssh -i ~/.ssh/[insert_your_keyname]

In some cases this doesn't work because ssh_config overriding the command, in this case try ssh -i ~/.ssh/[insert_your_keyname] -F /dev/null to not use the ssh_config.在某些情况下这不起作用,因为 ssh_config 覆盖了命令,在这种情况下尝试ssh -i ~/.ssh/[insert_your_keyname] -F /dev/null不使用 ssh_config。

One Unix based systems (Linux, BSD, Mac OS X), the default identity is stored in the directory $HOME/.ssh , in 2 files: private key: $HOME/.ssh/id_rsa public key: $HOME/.ssh/id_rsa.pub When you use ssh without option -i , it uses the default private key to authenticate with remote system.一个基于 Unix 的系统(Linux、BSD、Mac OS X),默认身份存储在目录$HOME/.ssh中,在 2 个文件中: private key: $HOME/.ssh/id_rsa public key: $HOME/.ssh/id_rsa.pub当您使用不带选项-issh时,它使用默认私钥与远程系统进行身份验证。

If you have another private key you want to use, for example $HOME/.ssh/deploy_key , you have to use ssh -i ~/.ssh/deploy_key ...如果您有另一个要使用的私钥,例如$HOME/.ssh/deploy_key ,则必须使用ssh -i ~/.ssh/deploy_key ...

It is annoying.这很烦人。 You can add the following lines in to your $HOME/.bash_profile : ssh-add ~/.ssh/deploy_key ssh-add ~/.ssh/id_rsa您可以在$HOME/.bash_profile中添加以下行: ssh-add ~/.ssh/deploy_key ssh-add ~/.ssh/id_rsa

So each time you use ssh or git or scp (basically ssh too), you don't have to use option -i anymore.因此,每次您使用sshgitscp (基本上也是ssh )时,您不必再使用选项-i了。

You can add as many keys as you like in the file $HOME/.bash_profile .您可以在文件$HOME/.bash_profile中添加任意数量的键。

Another alternative is to use ssh-ident, to manage your ssh identities .另一种选择是使用ssh-ident 来管理您的 ssh 身份

It automatically loads and uses different keys based on your current working directory, ssh options, and so on... which means you can easily have a work/ directory and private/ directory that transparently end up using different keys and identities with ssh.它会根据您当前的工作目录、ssh 选项等自动加载和使用不同的密钥……这意味着您可以轻松地拥有一个工作/目录和私有/目录,最终透明地使用不同的密钥和身份与 ssh。

I am using Git Bash on Win7.我在 Win7 上使用 Git Bash。 The following worked for me.以下对我有用。

Create a config file at ~/.ssh/config or c:/users/[your_user_name]/.ssh/config.在 ~/.ssh/config 或 c:/users/[your_user_name]/.ssh/config 创建一个配置文件。 In the file enter:在文件中输入:

Host your_host.com
     IdentityFile [absolute_path_to_your_.ssh]\id_rsa

I guess the host has to be a URL and not just a "name" or ref for your host.我猜主机必须是一个 URL,而不仅仅是主机的“名称”或参考。 For example,例如,

Host github.com
     IdentityFile c:/users/[user_name]/.ssh/id_rsa

The path can also be written in /c/users/[user_name]/.... format路径也可以写成 /c/users/[user_name]/.... 格式

The solution provided by Giordano Scalzo is great too. Giordano Scalzo 提供的解决方案也很棒。 https://stackoverflow.com/a/9149518/1738546 https://stackoverflow.com/a/9149518/1738546

One possibility to use ~/.ssh/config is to use the Match restriction instead of the Host restriction.使用~/.ssh/config的一种可能性是使用Match限制而不是Host限制。 In particular Match Exec calls a shell command to decide whether to apply the declarations or not.特别是Match Exec调用一个 shell 命令来决定是否应用声明。 In bash you could use the following command:在 bash 中,您可以使用以下命令:

[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]

This uses the bash [ command to verify if two strings are equal.这使用 bash [命令来验证两个字符串是否相等。 In this case it is testing if the string git@git.company.com:gitolite-admin matches the output that is obtained from the $(git config --get remote.origin.url)'' command.在这种情况下,它正在测试字符串git@git.company.com:gitolite-admin是否匹配从$(git config --get remote.origin.url)''命令获得的输出。

You can use any other command that identifies the repository that the shell is on.您可以使用任何其他命令来标识 shell 所在的存储库。 For this to work it is important to have the $SHELL variable defined to your shell, in my case /bin/bash .为此,在您的 shell 中定义$SHELL变量很重要,在我的例子中是/bin/bash The full example would then be the following ~/.ssh/config :完整的示例将如下所示~/.ssh/config

Match Exec "[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/gitolite-admin
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

Match Exec "[ git@git.company.com:some_repo = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/yourOwnPrivateKey
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

In this example I assumed that ~/.ssh/yourOwnPrivateKey contains your own private key and that ~/.ssh/gitolite-admin contains the private key of the user gitolite-admin .在此示例中,我假设~/.ssh/yourOwnPrivateKey包含您自己的私钥,并且~/.ssh/gitolite-admin包含用户gitolite-admin的私钥。 I included the IdentitiesOnly yes declaration to make sure that only one key is offered to the git server, mentioned by Mark Longair .我包含了IdentitiesOnly yes声明,以确保只向 git 服务器提供一个密钥,正如 Mark Longair 所提到的。 The other declarations are just standard ssh options for git.其他声明只是 git 的标准 ssh 选项。

You can add this configuration if you have several some_repo that you want to use with different keys.如果您有多个要与不同密钥一起使用的some_repo ,则可以添加此配置。 If you have several repositories at git@git.company.com and most of them use the ~/.ssh/yourOwnPrivateKey it makes more sense to include this key as default for the host.如果您在git@git.company.com有多个存储库,并且其中大多数使用~/.ssh/yourOwnPrivateKey ,则将此密钥作为主机的默认值包含在内更有意义。 In this case the ~/.ssh/config would be:在这种情况下, ~/.ssh/config将是:

Match Exec "[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/gitolite-admin
  IdentitiesOnly yes

Host git.company.com
  IdentityFile ~/.ssh/yourOwnPrivateKey
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

Note that the order matters and the Host git.company.com restriction should appear after the Match Exec one or ones.请注意,顺序很重要, Host git.company.com限制应出现在Match Exec一个或多个之后。

To use a specific key on the fly:要即时使用特定键:

GIT_SSH_COMMAND='ssh -i $HOME/.ssh/id_ed25519 -o IdentitiesOnly=yes -F /dev/null' git push origin c13_training_network

Explanation:解释:

  • local ENV var before doing the push执行推送之前的本地 ENV var
  • -i specifies key -i指定键
  • -F forces an empty config so your global one doesn't overwrite this temporary command -F强制一个空配置,所以你的全局配置不会覆盖这个临时命令

As someone else mentioned, core.sshCommand config can be used to override SSH key and other parameters.正如其他人提到的, core.sshCommand配置可用于覆盖 SSH 密钥和其他参数。

Here is an exmaple where you have an alternate key named ~/.ssh/workrsa and want to use it for all repositories cloned under ~/work .这是一个示例,其中您有一个名为~/.ssh/workrsa的备用键,并希望将它用于克隆下的所有存储库~/work

  1. Create a new .gitconfig file under ~/work :~/work下创建一个新的.gitconfig文件:
[core]
  sshCommand = "ssh -i ~/.ssh/workrsa"
  1. In your global git config ~/.gitconfig , add:在您的全局 git config ~/.gitconfig中,添加:
[includeIf "gitdir:~/work/"]
  path = ~/work/.gitconfig

如果您已经有默认的 ssh 密钥配置,但想对特定存储库使用不同的配置,那么这应该可以解决问题:

git config core.sshCommand "ssh -i ~/.ssh/github-personal -o IdentitiesOnly=yes -F /dev/null"

If using Git's version of ssh on windows, the identity file line in the ssh config looks like如果在 Windows 上使用 Git 的 ssh 版本,ssh 配置中的身份文件行看起来像

IdentityFile /c/Users/Whoever/.ssh/id_rsa.alice

where /c is for c:其中/c代表c:

To check, in git's bash do要检查,在 git 的 bash 中做

cd ~/.ssh
pwd 

You might need to remove (or comment out) default Host configuration您可能需要删除(或注释掉)默认主机配置.ssh/配置

For git to figure out, that it should use a different SSH keys, apart from changing your config file, as mentioned here: https://stackoverflow.com/a/7927828/1306884 you may also need to purge and reload an active SSH identities.为了让 git 弄清楚,除了更改配置文件之外,它应该使用不同的 SSH 密钥,如此处所述: https ://stackoverflow.com/a/7927828/1306884 您可能还需要清除并重新加载活动的 SSH身份。

On Mac, do the following:在 Mac 上,执行以下操作:

ssh-add -D
ssh-add ~/.ssh/id_rsa_one_that_you_want_to_use_instead

Using these two commands, and setting up the GIT URL to match the string defined in the Host of the ssh/config file, should allow you to use different SSH keys, for a different repositories.使用这两个命令,并设置 GIT URL 以匹配在 ssh/config 文件的Host中定义的字符串,应该允许您为不同的存储库使用不同的 SSH 密钥。

For example for Host work.github.com use work.github.com as an URL when cloning your repository git@work.github.com:your/repository.git .例如,对于Host work.github.com ,在克隆存储库git@work.github.com:your/repository.git时使用work.github.com作为 URL。

you most specified in the file config key ssh:您最常在文件配置密钥 ssh 中指定:

# Default GitHub user
Host one
 HostName gitlab.com
 User git
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/key-one
 IdentitiesOnly yes

#two user
Host two
 HostName gitlab.com
 User git
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/key-two
 IdentitiesOnly yes

Note: There's a way to apply the git config proposed in a previous answer for directories, not just at the repo level.注意:有一种方法可以将先前答案中建议的 git config 应用于目录,而不仅仅是在 repo 级别。

In my case, all projects were under the ~/work/ directory, so I updated my gitconfig as follows:在我的例子中,所有项目都在~/work/目录下,所以我更新了我的 gitconfig 如下:

# ~/.gitconfig
...

[includeIf "gitdir:~/work/**"]
  path = "~/work/.gitconfig"
# ~/work/.gitconfig
[user]
  email = amr@work.com
  name = Amr Awad
  sshCommand = ssh -i ~/.ssh/work

and now all repos inside the ~/work/ directory use the work key ~/.ssh/work without the need for configuring each repo separately.现在~/work/目录中的所有存储库都使用工作密钥~/.ssh/work ,而无需单独配置每个存储库。

here is the simple approach :这是简单的方法:

-From your local root git folder. - 从您的本地根 git 文件夹。

-Check the current type of authentication method HTTPS or SSH of your local repository. - 检查本地存储库的当前身份验证方法 HTTPS 或 SSH 类型。

   git remote -v

 Example using HTTPS:
 origin  https://github.com/juantorres9/SQLite_crash_cours.git (fetch)
 origin  https://github.com/juantorres9/SQLite_crash_cours.git (push)
 Example using SSH:
 origin  git@github.com:juantorres9/SQLite_crash_cours.git (fetch)
 origin  git@github.com:juantorres9/SQLite_crash_cours.git (push)

-Set the authentication method of your choice in case it's not already set. - 设置您选择的身份验证方法,以防尚未设置。

 For setting SSH
 git remote set-url origin git@github.com:USERNAME/REPOSITORY.git
 For setting HTTPS
 git remote set-url origin https://github.com/USERNAME/REPOSITORY.git

-Check again in case you want to double check - 再次检查,以防你想仔细检查

 git remote -v

-You are now able to use git push:fetch using your configured method. -您现在可以使用配置的方法使用 git push:fetch。

git push origin master

Note Last but not least , check updated official doc https://docs.github.com/en/get-started/getting-started-with-git/managing-remote-repositories注意最后但同样重要的是,检查更新的官方文档https://docs.github.com/en/get-started/getting-started-with-git/managing-remote-repositories

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

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