GitSSHWrapper
Encapsulate the code you need to write out a permissive GIT_SSH script that can be used to connect git to protected [email protected] repositories.
Includes two bin scripts, git-ssh-wrapper
and git-ssh
that can be used
inline to call git with GIT_SSH set properly. See examples below.
What it does
This gem provides a simple way to connect to git servers using keys that have not been added to your authentication agent with ssh-add, or keys which you only have saved as a string instead of written to a file.
This is especially useful for scripts that need to automate connections to a server using keys that are not intended to be part of the system on which the script is running.
This script is designed to always work even if hosts keys change or the ssh agent is being too paranoid or having a bad day.
A common use case is connecting to github.com to retrieve repositories, submodules, or ref listings using read-only "deploy keys" or bundling a Gemfile that contains private repositories accessible by a certain deploy key.
Command Line
You can use the included command line tool to call git commands directly.
$ git-ssh-wrapper ~/.ssh/id_rsa git fetch origin
$ git merge origin/master
$ git-ssh-wrapper ~/.ssh/id_rsa git push origin master
$ git-ssh-wrapper ~/.ssh/id_rsa bundle install
A shortcut command git-ssh
is also included that inserts git
automatically.
$ git-ssh ~/.ssh/id_rsa fetch origin # git fetch origin
You'll probably use this version if you're writing commands by hand.
Ruby Example
Accessing git servers programatically in ruby:
# :log_level default is 'INFO'
def get_refs
wrapper = GitSSHWrapper.new(:private_key_path => '~/.ssh/id_rsa', :log_level => 'ERROR')
`env #{wrapper.git_ssh} git ls-remote [email protected]:martinemde/git-ssh-wrapper.git`
ensure
wrapper.unlink
end
OR
def get_refs
private_key_data_string = get_key_data_somehow
GitSSHWrapper.with_wrapper(:private_key => private_key_data_string) do |wrapper|
wrapper.set_env
`git ls-remote [email protected]:martinemde/git-ssh-wrapper.git`
end
end
OR
wrapper = GitSSHWrapper.new(:private_key => Pathname.new('id_rsa').read)
`git ls-remote [email protected]:martinemde/git-ssh-wrapper.git`
wrapper.unlink
The wrapper creates Tempfiles when it is initialized. They will be cleaned at program exit, or you can unlink them by calling #unlink.
How it works
When connecting to a git server using ssh, if the GIT_SSH environment variable
is set, git will use $GIT_SSH instead of ssh
to connect.
The script generated will look something like this: (as long as I've kept this documentation up-to-date properly)
unset SSH_AUTH_SOCK
ssh -o CheckHostIP=no \
-o IdentitiesOnly=yes \
-o LogLevel=LOG_LEVEL \
-o StrictHostKeyChecking=no \
-o PasswordAuthentication=no \
-o UserKnownHostsFile=TEMPFILE \
-o IdentityFile=PRIVATE_KEY_PATH \
$*
The result is an ssh connection that won't use your ssh-added keys, won't prompt for passwords, doesn't save known hosts and doesn't require strict host key checking.
A tempfile is generated to absorb known hosts to prevent these constant warnings:
Warning: Permanently added 'xxx' (RSA) to the list of known hosts.
The tempfile is cleaned when the wrapper is unlinked or the program exits.