OpenSSH public-keys, ssh-agent and Keychain
February 3rd, 2007
I have always though that ssh-agent has some limitations. One of those limitations is that when invoked from .bashrc or .zshrc in the following way:
`eval ssh-agent`
will cause one ssh-agent instance to be spawned for every shell, which is a waste of resources. An easy solution is to use Keychain, which is also described here.
Basically, Keychain is a wrapper for ssh-agent. Keychain will start a ssh-agent and tell it to load one or several private keys. Additionally, Keychain will create two shell scripts into ${HOME}/.keychains named ${HOST}-sh (for SH-compatible shells) and ${HOST}-csh (for CSH-compatible shells) that can be sourced, for example, from within .bashrc, .zshrc or .cshrc, in order to set up the environment variables required for ssh-agent to be usable by other tools like ssh.
A typical ${HOME}/.keychains/${HOST}-sh file looks like this:
SSH_AUTH_SOCK=/tmp/ssh-AIVkg1MfHH/agent.942; export SSH_AUTH_SOCK; SSH_AGENT_PID=943; export SSH_AGENT_PID;
Adding the following lines at the end of .bashrc or .zshrc will get Keychain invoked automatically by the shell:
### KEYCHAIN ###
/opt/local/bin/keychain ~/.ssh/id_dsa
source ~/.keychain/${HOST}-sh
Keychain will search for an existing ssh-agent process. If no existing ssh-agent process exists, Keychain will spawn one telling it to load one or several private keys (passed as parameters to Keychain). Next, Keychain will update ${HOME}/.keychain/${HOST}-sh and ${HOME}/.keychain/${HOST}-csh to set up the proper environment variables and their corresponding values.
Kudos to Daniel Robbins — the original author — and Aron Griffis — the current Gentoo mantainer. This neat piece of software is extremely useful to me and I use it every day
Reusing existing OpenSSH v4 connections
November 11th, 2005
Reusing existing OpenSSH v4 connections comments a very interesting feature of OpenSSH 4: reusing open connections.
- ControlMaster
Enables the sharing of multiple sessions over a single network connection. When set to “yes” ssh will listen for connections on a control socket specified using the ControlPath argument.
- ControlPath
Specify the path to the control socket used for connection sharing as described in the ControlMaster section above or the string “none” to disable connection sharing. In the path, ‘%h’ will be substituted by the target host name, ‘%p’ the port and ‘%r’ by the remote login username. It is recommended that any ControlPath used for opportunistic connection sharing include all three of these escape sequences.
Assume that you’re on the host itchy and you wish to connect multiple times to the host scratchy.
Connect the first time with :
ssh scratchy -M -S /tmp/%r@%h:%pHere we’ve set two options:
-MThis is setting the “ControlMaster” option.
-S /tmp/%r@%h:%pThis is the setting for the ControlPath specifying that we should save the master socket as /tmp/user@hostname:port.
Now that we’ve setup the master connection we can connect a second time with:
ssh scratchy -S /tmp/%r@%h:%pThis time the connection is immediate. There is no option negotiation, etc, taking place. We can verify this by adding a
-vflag:
skx@itchy:~$ ssh -v scratchy -S /tmp/%r@%h:%p OpenSSH_4.2p1 Debian-5, OpenSSL 0.9.8a 11 Oct 2005 debug1: Reading configuration data /home/skx/.ssh/config debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * Linux scratchy.my.flat 2.6.8-1-386 #1 ... The programs included with the Debian GNU/Linux system are free software; ... ... snipThere we see the connection just occurs almost immediately, with none of the usual OpenSSH negotiation taking place.
Rather than messing around upon the command line we can setup these options within the configuration file .ssh/config, simply add a new stanza reading:
Host * ControlPath /tmp/%r@%h:%pNow we can connect as normal, so long as we make the first connection to any host with
-M(for “Master”) all subsequent connections will be much faster.
Cool, huh?
If you don’t think you can remember to specify the
-Mflag for the first one then you can also force this by setting your options to:
Host * ControlMaster auto ControlPath /tmp/%r@%h:%p(Using autoask instead of auto will force the connection to prompt you whether you wish to setup a socket)