Using SSH Passphrases
We use ssh a lot, especially for access to our source code repository (currently CVS). We use a public key system with ssh, and most of our server accounts don't have a password at all; they can be accessed only with a key.
For security, we ask people to protect their key with a passphrase. However, it is very inconvenient to have to type in the passphrase on every single access to the repository. The solution to this is to use an ssh agent, but finding out the best way to do this isn't all that clear from the documentation.
On most Linux systems, the
ssh-agent program will already be running when you log into a graphical session. However, it won't have any keys cached in it. To add your keys, you can type
ssh-add in a terminal window. (You will, of course, be prompted for the passphrase.) From then on,
ssh will use your key from the agent and not prompt you for a passphrase. You won't be asked for it again until after you log out (or you explicitly remove the key from the agent).
However, it's annoying to have to remember to do this before you use ssh. A nicer solution is to have your graphical session prompt you for your ssh passphrase immediately after you log in.
To enable this, first install an
ssh-askpass program. On Debian-based systems, there are four packages that provide
ssh-askpass. The one we prefer is
ssh-askpass-fullscreen. If you want to play around with the four alternatives before settling on a permanent choice, you can try out each one by running it in a terminal (but don't enter your real password as it will be written to the terminal afterwards). You then use the Debian alternatives mechanism to switch the default between them (with
sudo update-alternatives --config ssh-askpass in a terminal).
However, you also need to arrange for the key-adding operation to take place at login. The simplest option is to create a file
~/.Xsession as follows:
ssh-add exec x-session-manager
This will cause
ssh-add to be run just before continuing with the normal session process.
It's also possible to have
ssh-agent, and therefore your cached keys, last across logins. For this, you need to use the
keychain program (found in the Debian package of the same name). Instead of using
ssh-add in your
~/.Xsession, you can use the following:
eval $(keychain --eval --noinherit id_dsa) exec x-session-manager
keychain will look for a previously-existing agent and attach to it. It will then add the id
id_dsa to it. The agent that
keychain starts, and the keys added to it, will persist after logout.
It's also possible to have
keychain work in a text login (including a remote login via ssh!). For this, you need to invoke it in your
~/.bash_profile (or equivalent, for other shells). Rather than duplicating the code for calling
keychain, it's tidier to have your
.bash_profile executed as part of your X session startup.
To do this, I removed
~/.Xsession and created a
~/.gnomerc as follows:
On my system (Debian Etch)
~/.gnomerc is run before the default
ssh-agent, which simplifies things slightly. I assume that KDE would be similar.
I then edited my
~/.bash_profile to contain a block like this:
if [ -z "$SSH_AUTH_SOCK" -a -x "$(which keychain)" ] then keychain id_dsa [ -f $HOME/.keychain/$HOSTNAME-sh ] && \ . $HOME/.keychain/$HOSTNAME-sh [ -f $HOME/.keychain/$HOSTNAME-sh-gpg ] && \ . $HOME/.keychain/$HOSTNAME-sh-gpg fi
This checks that the session doesn't already have an agent set up (in case you are using agent forwarding), and that you have the
keychain program installed, then runs the host-specific scripts that
keychain creates (as an alternative to using
--eval). So now
keychain will search for an existing agent and add my key to it from both text and graphical logins.
In addition, all the code in my
.bash_profile will be executed in a graphical login. This means that I set things like environment variables in
.bash_profile rather than
.bashrc, which is really how these files are designed to work.
If you're curious about the details of how
ssh-agent works, the short explanation is as follows. The X11 session mechanism already runs your session under the control of
/etc/X11/Xsession.d/*ssh-agent). However, there is no automatic action to add keys to the agent. In other words,
ssh-add has to be explicitly invoked. Also, without an
ssh-add has no way to prompt you for a passphrase and thus add your key to its cache.
Once a key is placed in the cache, programs can request them from the agent via a socket. They gather the necessary details for contacting the agent from environment variables that
ssh-agent sets up. This is why the whole session is run as a subprocess of the agent, so that all programs will inherit the appropriate environment variables.