可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
A rather unusual situation perhaps, but I want to specify a private SSH-key to use when executing a shell (git) command from the local computer.
Basically like this:
git clone git@github.com:TheUser/TheProject.git -key \"/home/christoffer/ssh_keys/theuser\"
Or even better (in Ruby):
with_key(\"/home/christoffer/ssh_keys/theuser\") do
sh(\"git clone git@github.com:TheUser/TheProject.git\")
end
I have seen examples of connecting to a remote server with Net::SSH that uses a specified private key, but this is a local command. Is it possible?
回答1:
Something like this should work (suggested by orip):
ssh-agent bash -c \'ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git\'
if you prefer subshells, you could try the following (though it is more fragile):
ssh-agent $(ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git)
Git will invoke SSH which will find its agent by environment variable; this will, in turn, have the key loaded.
Alternatively, setting HOME
may also do the trick, provided you are willing to setup a directory that contains only a .ssh
directory as HOME
; this may either contain an identity.pub, or a config file setting IdentityFile.
回答2:
None of these solutions worked for me.
Instead, I elaborate on @Martin v. Löwis \'s mention of setting a config
file for SSH.
SSH will look for the user\'s ~/.ssh/config
file. I have mine setup as:
Host gitserv
Hostname remote.server.com
IdentityFile ~/.ssh/id_rsa.github
IdentitiesOnly yes # see NOTES below
And I add a remote git repository:
git remote add origin git@gitserv:myrepo.git
And then git commands work normally for me.
git push -v origin master
NOTES
- The
IdentitiesOnly yes
is required to prevent the SSH default behavior of sending the identity file matching the default filename for each protocol. If you have a file named ~/.ssh/id_rsa
that will get tried BEFORE your ~/.ssh/id_rsa.github
without this option.
References
- Best way to use multiple SSH private keys on one client
- How could I stop ssh offering a wrong key
回答3:
Other people\'s suggestions about ~/.ssh/config
are extra complicated. It can be as simple as:
Host github.com
IdentityFile ~/.ssh/github_rsa
回答4:
Starting from Git 2.3.0 we also have the simple command (no config file needed):
GIT_SSH_COMMAND=\'ssh -i private_key_file\' git clone user@host:repo.git
You may need a restart for the ssh service on your machine.
回答5:
Contents of my_git_ssh_wrapper:
#!/bin/bash
ssh -i /path/to/ssh/secret/key $1 $2
Then you can use the key by doing:
GIT_SSH=my_git_ssh_wrapper git clone git@github.com:TheUser/TheProject.git
回答6:
To sum up answers and comments, the best way to set up git to use different key files and then forget about it, which also supports different users for the same host (e.g. a personal GitHub account and a work one), which works on Windows as well, is to edit ~/.ssh/config
(or c:\\Users\\<your user>\\.ssh\\config
) and specify multiple identities:
Host github.com
HostName github.com
IdentityFile /path/to/your/personal/github/private/key
User dandv
Host github-work
HostName github.com
IdentityFile /path/to/your/work/github/private/key
User workuser
Then, to clone a project as your personal user, just run the regular git clone
command.
To clone the repo as the workuser
, run git clone git@github-work:company/project.git
.
回答7:
With git 2.10+ (Q3 2016: released Sept. 2d, 2016), you have the possibility to set a config for GIT_SSH_COMMAND
(and not just an environment variable as described in Rober Jack Will\'s answer)
See commit 3c8ede3 (26 Jun 2016) by Nguyễn Thái Ngọc Duy (pclouds
).
(Merged by Junio C Hamano -- gitster
-- in commit dc21164, 19 Jul 2016)
A new configuration variable core.sshCommand
has been added to
specify what value for GIT_SSH_COMMAND to use per repository.
core.sshCommand:
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.
The command is in the same form as the GIT_SSH_COMMAND
environment variable and is overridden when the environment variable is set.
It means the git clone
can be:
cd /path/to/my/repo
git config core.sshCommand \'ssh -i private_key_file\'
# later on
git clone host:repo.git
回答8:
As stated here: https://superuser.com/a/912281/607049
You can configure it per-repo:
git config core.sshCommand \"ssh -i ~/.ssh/id_rsa_example -F /dev/null\"
git pull
git push
回答9:
I went with the GIT_SSH environment variable.
Here\'s my wrapper, similar to that from Joe Block from above, but handles any amount of arguments.
File ~/gitwrap.sh
#!/bin/bash
ssh -i ~/.ssh/gitkey_rsa \"$@\"
Then, in my .bashrc, add the following:
export GIT_SSH=~/gitwrap.sh
回答10:
Way better idea to add that host or ip to the .ssh/config
file like so:
Host (a space separated list of made up aliases you want to use for the host)
User git
Hostname (ip or hostname of git server)
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_(the key you want for this repo)
回答11:
When you need to connect to github with a normal request (git pull origin master
), setting the Host as *
in ~/.ssh/config
worked for me, any other Host (say, \"github\" or \"gb\") wasn\'t working.
Host *
User git
Hostname github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_xxx
回答12:
Many of these solutions looked enticing. However, I found the generic git-wrapping-script approach at the following link to be the most useful:
How to Specify an ssh Key File with the git
command
The point being that there is no git
command such as the following:
git -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/git/repo.git
Alvin\'s solution is to use a well-defined bash-wrapper script that fills this gap:
git.sh -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/git/repo.git
Where git.sh
is:
#!/bin/bash
# The MIT License (MIT)
# Copyright (c) 2013 Alvin Abad
# https://alvinabad.wordpress.com/2013/03/23/how-to-specify-an-ssh-key-file-with-the-git-command
if [ $# -eq 0 ]; then
echo \"Git wrapper script that can specify an ssh-key file
Usage:
git.sh -i ssh-key-file git-command
\"
exit 1
fi
# remove temporary file on exit
trap \'rm -f /tmp/.git_ssh.$$\' 0
if [ \"$1\" = \"-i\" ]; then
SSH_KEY=$2; shift; shift
echo \"ssh -i $SSH_KEY \\$@\" > /tmp/.git_ssh.$$
chmod +x /tmp/.git_ssh.$$
export GIT_SSH=/tmp/.git_ssh.$$
fi
# in case the git command is repeated
[ \"$1\" = \"git\" ] && shift
# Run the git command
git \"$@\"
I can verify that this solved a problem I was having with user/key recognition for a remote bitbucket repo with git remote update
, git pull
, and git clone
; all of which now work fine in a cron
job script that was otherwise having trouble navigating the limited-shell. I was also able to call this script from within R and still solve the exact same cron
execute problem
(e.g. system(\"bash git.sh -i ~/.ssh/thatuserkey.pem pull\")
).
Not that R is the same as Ruby, but if R can do it... O:-)
回答13:
You could use GIT_SSH environment variable. But you will need to wrap ssh and options into a shell script.
See git manual: man git
in your command shell.
回答14:
The trick for me was to use git@hostname instead of http://hostname
回答15:
In Windows with Git Bash you can use the following to add a repository
ssh-agent bash -c \'ssh-add \"key-address\"; git remote add origin \"rep-address\"\'
for example: ssh-agent bash -c \'ssh-add /d/test/PrivateKey.ppk; git remote add origin git@git.test.com:test/test.git\'
Which private key is in drive D, folder test of computer. Also if you want to clone a repository, you can change git remote add origin
with git clone
.
After enter this to Git Bash, it will ask you for passphrase!
Be Aware that openssh private key and putty private key are diiferent!
If you have created your keys with puttygen, you must convert your private key to openssh!
回答16:
If none of the other solutions here work for you, and you have created multiple ssh-keys, but still cannot do simple things like
git pull
then assuming you have two ssh key files like
id_rsa
id_rsa_other_key
then inside of the git repo you are struggling with (cd into there), try:
ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_rsa_other_key
and also make sure your github default username and userid are correct by:
git config user.name \"Mona Lisa\"
git config user.email \"mona.lisa@email.com\"
See https://gist.github.com/jexchan/2351996 for more more information.
回答17:
I use zsh
and different keys are loaded to my zsh shell\'s ssh-agent
automatically for other purposes (i.e. access to remote servers) on my laptop. I modified @Nick\'s answer and I\'m using it for one of my repos that needs to be refreshed often. (In this case it\'s my dotfiles
which I want same and latest version across my all machines, wherever I\'m working.)
bash -c \'eval `ssh-agent`; ssh-add /home/myname/.dotfiles/gitread; ssh-add -L; cd /home/myname/.dotfiles && git pull; kill $SSH_AGENT_PID\'
- Spawn an ssh-agent
- Add read-only key to agent
- Change directory to my git repo
- If
cd
to repo dir is successful, pull from remote repo
- Kill spawned ssh-agent. (I wouldn\'t want many of agents lingering around.)
回答18:
for the gitlab RSAAuthentication yes
Host gitlab.com
RSAAuthentication yes
IdentityFile ~/.ssh/your_private_key_name
IdentitiesOnly yes
doc is here
回答19:
If SSH port number is not 22(default), add Port xx
in ~/.ssh/config
In my case (synology),
Host my_synology
Hostname xxxx.synology.me
IdentityFile ~/.ssh/id_rsa_xxxx
User myname
Port xx
Then clone using Host title in config. (\"my_synology\". to avoid @chopstik \'s \"*\")
git clone my_synology:path/to/repo.git
回答20:
You need to create a ~/.ssh/config as below
Host <Your bitbucket server>
User <userid>
Hostname <Your bitbucket server as above>
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa<file> This is your private key file
permission as below
-rw------- $HOME/.ssh/config
Add your public key into your git (cat ~/.ssh/id_rsa_pub [or simillar name])
and then git clone as below
git clone ssh://blahblah@blah.com/userid/test.git
回答21:
If you\'re like me, you can:
Keep your ssh keys organized
Keep your git clone commands simple
Handle any number of keys for any number of repositories.
Reduce your ssh key maintenance.
I keep my keys in my ~/.ssh/keys
directory.
I prefer convention over configuration.
I think code is law; the simpler it is, the better.
STEP 1 - Create Alias
Add this alias to your shell: alias git-clone=\'GIT_SSH=ssh_wrapper git clone\'
STEP 2 - Create Script
Add this ssh_wrapper script to your PATH:
#!/bin/bash
# Filename: ssh_wrapper
if [ -z ${SSH_KEY} ]; then
SSH_KEY=\'github.com/l3x\' # <= Default key
fi
SSH_KEY=\"~/.ssh/keys/${SSH_KEY}/id_rsa\"
ssh -i \"${SSH_KEY}\" \"$@\"
EXAMPLES
Use github.com/l3x key:
KEY=github.com/l3x git-clone https://github.com/l3x/learn-fp-go
The following example also uses the github.com/l3x key (by default):
git-clone https://github.com/l3x/learn-fp-go
Use bitbucket.org/lsheehan key:
KEY=bitbucket.org/lsheehan git-clone git@bitbucket.org:dave_andersen/exchange.git
NOTES
Change the default SSH_KEY in the ssh_wrapper script to what you use most of the time. That way, you don\'t need to use the KEY variable most of the time.
You may think, \"Hey! That\'s a lot going on with an alias, a script and some directory of keys,\" but for me it\'s convention. Nearly all my workstations (and servers for that matter) are configured similarly.
My goal here is to simplify the commands that I execute regularly.
My conventions, e.g., Bash scripts, aliases, etc., create a consistent environment and helps me keep things simple.
KISS and names matter.
For more design tips check out Chapter 4 SOLID Design in Go from my book: https://www.amazon.com/Learning-Functional-Programming-Lex-Sheehan-ebook/dp/B0725B8MYW
Hope that helps. - Lex