Specifying Different SSH key for git
With my recent
articles on
creating multiple vagarant virtual machines, I noticed connecting to
virtual machines using command: vagarant ssh
, was taking longer and
failing frequently.
Most annoyingly, my blogging virtual machine was inaccessible, which is fine because the data and operating system are separate and I recreated the system, while traveling on the train of all places!
With a new system, I added back the SSH key to post blog articles and all of the sudden, the blogging virtual machine is inaccessible again.
What gives?!
A Better Solution
Instead of destroying and rebuilding again, I decided to find another
way to use git without replacing the SSH keys, since that is what
vagrant ssh
was failing on and if I am actively changing SSH keys,
it’s probably the most likely issue.
There are solutions to this issue, the one I have chosen this time is
to use git’s GIT_SSH_COMMAND
setting to provide another SSH key.
Other solutions use ssh-add
or configuring the SSH configuration
file that I have explored as well in the past. This is a valid
solution and can work for other scenarios, but can never get ssh-add
to work reliably with different keys and accounts. I just feel a bit
lost with all of these security configurations, so I prefer a more
manual but straight-forward method.
Requirements
If you would like to follow along, or understand my setup, these are the requirements:
- SSH version 2.17.0 or newer
- multiple github.com accounts with different credentials, i.e. work and personal.
- SSH key that is password protected! - Less of a requirement but good security practice!
Solution: GIT_SSH_COMMAND
I solved my problem by prepending a: GIT_SSH_COMMAND=
to my git
command. I will go over the technique, then discuss its benefits.
Configuring GIT_SSH_COMMAND
When configuring the environment variable: GIT_SSH_COMMAND
, git will
use this SSH key instead of the default one in ~/.ssh/id_rsa
.
To configure this variable, the value is basically a valid SSH command, for example, being able to SSH login to a server.
In this case, the configuration requires a different SSH key, so use
the -i
flag.
$ ssh -i /path/to/private/key <username>@<server address>
For github, there is no server to log into, so specifying the SSH key is sufficient:
$ ssh -i /path/to/private/key
This is the basis of the GIT_SSH_COMMAND
option, to use the option,
prepend the option with the above SSH command to any git command:
$ GIT_SSH_COMMAND="ssh -i /path/to/private/ssh/key" git <command>
This configures git to use a different SSH key than the default one in
~/.ssh/id_rsa
.
Benefits of Approach
The main reasons why I chose this appraoch is to allow my virtual machines to access github but without copying SSH keys into the virtual machine and/or reconfiguring github for new SSH keys each time.
This avoids creating a new SSH key in the virtual machine, which may
conflict with vagrant ssh
. The jury is still out on this, but
losing access to a virtual machine on your own computer is a bit silly
if you ask me. ^_^;
Another benefit of this solution is one can cleanly manage multiple
SSH keys for different accounts without tricky SSH configurations and
ssh-add
commands.
The number of times where I have pushed to the repository with
unintended credentials… I prefer to have the SSH key with the
project instead of having all the SSH key in the ~/.ssh
directory.
Demerits of Approach
By adding GIT_SSH_COMMAND
, you need to add this option every time
you want to use a git command, well, most notably git push
and git
fetch
since those are the only commands that require identity credentials.
One way to overcome this annoyance is to use configure git using command:
git config add core.sshCommand="ssh -i /path/to/private/ssh/key"
But I haven’t got this to work. :-/ (on 2.7.4 at least!)
This option only appears from git version 2.17.0 or newer! The
misleading thing about git config
is that I can add unsupported
options and there will be no errors raised.
Update git
This is one of the first times I had to update git to a version to get a feature that is not in the system’s default git.
$ sudo add-apt-repository ppa:git-core/ppa -y
$ sudo apt-get update
$ sudo apt-get install git -y
$ git --version
After updating git, to check command configuration, use: git config
-l
:
$ git config -l
push.default=simple
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
core.sshcommand=ssh -i /path/to/id_rsa
remote.origin.url=[email protected]:...git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.email=[email protected]
user.name=First Last
branch.fix_http_status_999.remote=origin
branch.fix_http_status_999.merge=refs/heads/fix_http_status_999
And Voila!
Non-git Update Solution
If you can’t update git on your system, a quick way to add
GIT_SSH_COMMAND
to reduce this annoyance is to make bash aliases for
git in your .bashrc
file:
alias git2="GIT_SSH_COMMAND='ssh -i /path/to/private/ssh/key'"
This will work in a pinch. ;-)
Conclusion
Using GIT_SSH_COMMAND
to manage SSH keys for github adds another
level of complexity when working with git, but I find this to my
preferred solution when I do not want to spend time tinkering with SSH
configurations. I know where the key is and I can keep things simple.
Ideally, upgrading git to a version that is newer than 2.17 so it
supports the GIT_SSH_COMMAND
option.
Another option is to have an alias in .bashrc
, which will work in
any system.
Finally, manually prepending the option GIT_SSH_COMMAND="ssh -i ..."
each time is not a deal breaker since only git fetch
and git push
require an SSH key.
In either case, these are all valid options to solve this problem.