Wednesday, October 18, 2017

Painless and secure SSH key management

Background

SSH keys are great – they let you log into remote machines without typing your password every time. You should protect them with their own passphrases, though, so anyone who gets your key doesn’t automatically get access to all your shell accounts. This means you have to set up an ssh-agent to hold your keys. (Otherwise you’d have to type the key’s passphrase every time, and you haven’t achieved very much.)

It's not obvious how best to manage the ssh-agent: When to start a new one, when to load new keys, etc. (Some systems like OS X will start an ssh-agent for you on login, which makes things a big simpler.)

My goal here is to describe a platform-independent setup that is secure enough for my purposes, and convenient to use. I think it might work well for others too.

tl;dr

Source this in your .bashrc, name your keys like ~/.ssh/*-key, and type kc when you want to load them.

Goals

  1. I don’t have to type my password every time I log into a remote machine with ssh.
  2. Conversely, I don’t want my credentials saved in memory forever. I want to be re-prompted from time to time.
  3. My credentials should be encrypted on-disk, so someone who grabs my hard drive or gets access to a backup doesn’t have unfettered access to them.
  4. I don’t want to use an extra program to manage things. I want to depend on ssh-agent, my .bashrc, and nothing else.
  5. The solution should work most Linux distros and OS X without modification.

Goals 1-3 are fairly general, and I think most people should want those things. Goals 4 and 5 are particular to my workflow, and are what prompted my solution.

Solution

See this file: .bashrc.ssh-agent, which is a simple modification of existing scripts that wrap ssh-agent.

Usage works like this:

  • Source the script from your .bashrc: . ~/.bashrc.ssh-agent
  • Put your keys in ~/.ssh, ending with the *-key suffix. (This lets you easily exclude keys from auto-loading by changing the suffix. For instance, you could have ~/.ssh/home-key and ~/.ssh/work-key.)
  • Give all your keys the same passphrase.
  • To load keys, type kc. You should be prompted for your passphrase.

The first time you open a terminal after restarting, you should see “Initializing new SSH agent…”. You shouldn’t see anything in subsequent terminals.

If you add a key, you can run kc again to load it up.

If something happens to the running ssh-agent, you'll have to re-run kc in every running terminal window to load the new context.

It works like this:

  1. At login, it checks if an ssh-agent (launched by us) is running, and starts one if not.
  2. On demand, it load all keys into the running ssh-agent. (This might be because you just restarted your machine, or because your keys expired and you want to reload them. We’ll save them for 18 hours, because that will cause you to get re-prompted every day. They’ll usually expire overnight, so you’ll get prompted in the morning.)

This is is based heavily off of a gist by Michael Zedeler which did the agent management. I added the key-loading logic I wanted.

Alternatives

  • Some recent versions of OS X and some Linux distros will automatically start an ssh-agent for you. You may be able to just run ssh-add <your-keys>.
  • The gist this is based off of by Michael Zedeler is a great example to build off of.
  • Keychain provides very similar functionality bundled in a standalone application. This solution is heavily inspired by Keychain.

Sunday, July 23, 2017

SELinux, ssh keys, and backing up your home directory

I'm fairly inexperienced with the ins and outs of SELinux, so this was novel to me:

I recently restored a /home partition from a backup, after which ssh key login stopped working.

I went through all the normal checks (permissions on my home directory, ~/.ssh, ~/.ssh/authorized_keys).

I started a debug sshd with "/usr/sbin/sshd -d -p 2222" -- and key login worked!.

The culprit turned out to be SELinux -- if I turned off enforcement with setenforce 0, I could log in via ssh keys again. Sure enough, there were messages in /var/log/audit/audit.log mentioning denied access to authorized_keys.

Running sudo restorecon -rv . from my restored home directory got things working again (and showed some helpful output about the changing contexts).

So, the real take-away (which is obvious for anyone who's more used to SELinux than me), is to if your ssh keys aren't being recognized, be sure to check /var/log/audit/audit.log as well.

Most of what I learned about this is from this blog post.

Sunday, October 26, 2014

Compiling Tor on CentOS 6.5

$ yum groupinstall "Development Tools"
$ yum install libevent-devel openssl-devel
$ ./configure
$ make
$ make install

That's it. I actually started writing this when I thought it would be more complicated.

It looks like the RPM for CentOS doesn't work with NTor (the new, faster) handshakes. There's some discussion on tor-relays@ about this here.

Tuesday, October 14, 2014

CrashPlan doesn't load on Ubuntu 14.04

These instructions from CrashPlan are spot on.

I installed webkit and added a line to run.conf as they described, and everything worked fine.

Saturday, June 7, 2014

Compiling mosh-chrome on 64-bit Ubuntu 14.04

mosh-chrome is great. For me, it addresses the last major feature that's keeping me from just using a light, cheap Chromebook as my day-to-day laptop as opposed to some beautiful/grotesque beast like a Thinkpad.

Anyway, these are my notes from compiling mosh-chrome on a relatively stock 64-bit (amd64) Ubuntu 14.04 machine:

  • Install the following packages: git subversion build-essential cmake autoconf libc6:i386 libstdc++6:i386 protobuf-compiler
    (Some of these are standard dev tools, some are 32-bit packages you won't get by default with a 64-bit dev toolchain, and there's one Google-specific tool thrown in there.)
  • pod2man gives an error when attempting to compile openssl. I wrote down a nasty workaround here last night. It's ugly but it worked for me.

That's it.

Compiling openssl 1.0.1g with Perl 5.18, the terrible way

[Edit: 2014-12-28: Newer versions of pod2man don't have this problem, apparently. The openssl issue has been closed, and this works for me now without the workaround below.]

It appears that openssl 1.0.1g doesn't compile with Perl 5.18 because the 5.18 of pod2man is stricter than previous versions, resulting in lots of errors like this:

cms.pod around line 457: Expected text after =item, not a number

There are patches ([1], [2], [3], plus the link above) that deal with this, but I couldn't find one that applied cleanly against openssl 1.0.1g.

In this particular case, I'm building openssl as a prerequisite for something else and won't be installing any manpages anywhere, so I actually don't care at all about building the documentation. So instead of actually fixing this, I just blanked out all the files:

$ echo "=pod" > ./../blank.pod
$ find . -name '*.pod' -exec 'cp' './../blank.pod' '{}' \;

This seems to be the simplest thing that works without modifying the build process at all or removing files, if one can't get any of the above patches to apply.

[Edited 2014-10-06 to simplify command for blanking pod files.]

Friday, April 25, 2014

Using a Custom Window Manager in Ubuntu 14.04

I just installed Ubuntu 12.04 on my Thinkpad X1 carbon (laptop). These are my notes about using a custom window manager via .xsession files; perhaps they'll be useful to someone else, too. (Notably, this is assuming you already know everything about configuring your WM and just want to know how to do it in the latest Ubuntu.)

I chose Ubuntu because the installation on a laptop has been painless for the last 4 years (10.04, 12.04, and 14.04 LTS).

To use a custom .xsession file, create a file /usr/share/xsessions/xsession.desktop, with the following contents:

[Desktop Entry]
Encoding=UTF-8
Name=Xsession
Comment=Run ~/.xsession
Exec=/etc/X11/Xsession

This will create an option on the login page (once you've chosen a user) called "Xsession". It relies on an ~/.xsession file being present, however.

Create a file ~/.xsession. The only thing it needs to do is exec your window manager. You can, optionally, put lines before that to set up your environment. (There are plenty of tutorials online for using xsession files in general.) What I appreciate about xsession files is that they let you keep a large part of your configuration separate from your window manager.

This is the xsession file I'm using for awesome:

/usr/bin/xscreensaver -nosplash &
/usr/bin/nm-applet &
caffeine >/dev/null 2>&1 &
blueman-applet >/dev/null 2>&1 &

exec /usr/bin/awesome

You can see it starts up a few applications (using &, so they don't block!), then exec's awesome.

Now, when you log in (Ubuntu's display manager is lightdm), choose "Xsession" and you're ready to rock.