Some notes from migrating towards encrypted SSH keys

May 16, 2014

I'll start with the admission: up until now I've used unencrypted SSH keys on my home and office workstations, ultimately because I didn't think that doing so made the risks particularly worse than using encrypted keys and it's undeniably more convenient. For hand-waving reasons I've recently decided to experiment with encrypted keys on at least my home machine so this is a collection of early notes on the process.

The most important part of making encrypted SSH keys convenient is to be running ssh-agent. Normal people will have this done automatically as part of their X session because GDM or xdm or the KDE equivalent sets all of this up for you. I'm the kind of crazy person who starts their X session by hand so I had to add a magic incantation to start it in the right way. On Fedora 20 and in my case this is:

xinit /usr/bin/ssh-agent /bin/env TMPDIR=$TMPDIR \
        /usr/bin/dbus-launch --exit-with-session \
        $HOME/.xinitrc -- <server args>

(This comes from /etc/X11/xdm/xinit/xinitrc-common. I assume the TMPDIR bit is necessary because ssh-agent normally changes $TMPDIR in the environment it passes to anything it starts.)

If you have an existing unencrypted SSH key (as I did) you encrypted it with 'ssh-keygen -p'. This prompts for everything and is smart enough to recognize that your key is unencrypted. Note that you don't encrypt the public key, just the private key.

Loading keys into your running ssh-agent is done with ssh-add. On Fedora 20, if you have the openssh-askpass package installed ssh-add will automatically use the graphical frontend from it when needed without you having to set $SSH_ASKPASS, which is somewhat contrary to the manpage. This behavior may also happen for other graphical ssh-add password agents; I haven't tested. I invoke ssh-add early on in my .xinitrc (after I've started my window manager but before almost anything else) so that I have automatic SSH logins available for anything else I want to start.

(I've found that I want a cover script for ssh-add because I don't put my SSH keys in the default place. The cover script is just 'ssh-add /path/to/identity-rsa', more or less.)

I find it somewhat annoying that I have yet to find a ssh-add password agent that will accept an X -geometry argument or any equivalent of it. I don't want to have to place the password window; I want it to just appear in a fixed place so I can park my mouse there and type the password. If I decide I really care about this the solution is to run ssh-add in a disposable xterm because I can definitely place those.

(Ie run 'xterm -geometry ... -e ssh-addkeys', where ssh-addkeys is my cover script. When ssh-add is run this way it just prompts on the terminal instead of popping up a graphical window for it.)

I lock my screen with the xlock from xlockmore. This offers a pretty convenient way to integrate with ssh-agent; you can run a command before the screen locks (ie 'ssh-add -D' to drop all keys) and then run a second command afterwards which gets fed the password you used to unlock the screen. If you use your regular password as your SSH key password, this can thus wind up re-adding your SSH keys to ssh-agent without any further input from you.

(Of course it would probably be more secure to use a separate password for your SSH keys, but then it would be less convenient and you might wind up locking your screen less (or not purging the keys from ssh-agent when you lock the screen). I've chosen to go with convenience here.)

This is getting long enough that I think I'm going to stop here for now. I have some remaining unsolved issues with encrypted keys but they'll go in a separate entry.

PS: users of more sophisticated desktop environments may have all of this integrated into their desktop's existing key management infrastructure so that everything unlocks on login without you having to do anything and screen locking is automatically handled and so on. This is certainly the way it should be and modern desktops do have general password stores.

Sidebar: a post-unlock xlock script

According to the xlock manpage, a sample script for the -pipepassCmd argument comes with xlock. This script is not packaged in the Fedora 20 version and since I had to dig it out of some web searches, here it is for anyone else (without the original comments):

#!/usr/bin/perl -w
use strict;
use Expect;

my $pass = <STDIN>;
my $exp = Expect->spawn('/u/cks/bin/X11/ssh-addkeys');
$exp->expect(10, ':');
$exp->send("$pass\r\n");
$exp->expect(10, ':');
$exp->hard_close;

On Fedora 20, you'll need the perl-Expect package. In general you'll need to change where it starts my ssh-addkeys script to something that runs ssh-add with whatever keys are appropriate for you.

(It's kind of a pity that ssh-add can't do this by itself. All it would take is an argument to specify 'just read the key from standard input and be done with it'.)


Comments on this page:

From 89.243.101.232 at 2014-05-16 04:41:52:

What doesn't help the tradeoff, is that the (current) encryption is somewhat outdated. The password is converted to an encryption key by a single round of MD5 (with salt).

StackExchange: Security of passphrase-protected private key.

The workaround suggested in the link applies a hard-coded 2000 iterations of HMAC-SHA1. Likely similar to the hashing for your local login password.

If you have an existing unencrypted SSH key (as I did) you encrypted it with ssh-keygen -p.

See also Improving the security of your SSH private key files.

By John Wiersba at 2015-09-18 13:32:47:

It's kind of a pity that ssh-add can't do this by itself. All it would take is an argument to specify 'just read the key from standard input and be done with it'.

I really don't understand why security-related software nowadays doesn't take a --stdin option or such to allow passwords to be passed safely from a script. Reading from /dev/tty with no option to read from a pipe is a major block to reusing components "the Unix Way". Even the venerable passwd, badly broken in this respect for years, has this option. Why don't ssh and ssh-add have it?

See if you can leverage sshpass to provide the password to ssh-add.

sshpass will happily read from STDIN, file (descriptor) and possibly an environment variable.

(I personally liked a FIFO as the ""file. }:-)

Written on 16 May 2014.
« My personal and biased view of sudo versus su
The problem of encrypted SSH keys and screen »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri May 16 01:48:51 2014
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.