SSH Keys and SSH-Agent

ssh-agent and SSH Keys

SSH keypairs

SSH keypairs are a way of using SSH more securely and/or without a password. Keys are random-seeming strings of bits that get fed into encryption algorithms. Such keys can be generated in pairs - so that messages encrypted with one key can only be decrypted with the other (i.e. not the original key), etc. Usually one key of the pair is designated as the public key, and another the private key. The public keyfile ends in the extension .pub; the private keyfile typically has the same name as the public file but without the extension. Since each key is necessary to decrypt messages from the other, you can safely upload your public key to services (such as Bitbucket or Github) as a means of authentication. When you try to log in, the server will send you a message encrypted with your public key which ssh then proves it can decrypt by sending an encrypted response, blah blah blah - point being only someone in possession of the other key will be able to respond correctly to the messages. This provides a way to log people in without passwords - a way that is actually much more secure than password use.

Generating keypairs

You can generate a keypair on the command line with:

ssh-keygen

It will prompt you for a filename (and an optional encryption password, which it is recommended that you do) and store the pair in ~/.ssh If you want passwordless login to a server or service that allows it, you then upload the {keyname}.pub file to the remote service in accordance with instructions they provide.

If you want to log in to aclweb.org via ssh without a password, just append your public key to ~/.ssh/authorized_keys. From your local machine, this should work:

cat ~/.ssh/{your_keyfile}.pub | ssh {username}@aclweb.org "cat >> ~/.ssh/authorized_keys"

The next time you type ssh {username}@aclweb.org it should log you in without prompting for a password (note, however, that if you have more than one key on your local machine - which you should (one for each service) if you're doing a lot of this) - you may need to use ssh-agent to indicate what the proper key is. Either that, or note the key in your config file. Both methods are covered below.

SSH-config

SSH checks a config file before doing its stuff. That file is usually simply ~/.ssh/config. You can feed ssh information about various services in the following format:

Host acl
      HostName www.aclweb.org
      User u36925139
      IdentityFile ~/.ssh/id_rsa

This blurb, for example, tells ssh that acl means www.aclweb.org, and that when someone is usig it they are user u36925139 and authenticate using the ssh keyfile ~/.ssh/id_rsa

This enables me to log in to aclweb.org by simply typing the following at the command prompt:

ssh acl

Very convenient!

Of course, sometimes it doesn't work without a little help from ssh-agent...

Starting ssh-agent

We log in to certain remote services - Bitbucket in particular - using ssh keypairs to avoid having to enter a password at login (also, this method is generally more secure). To manage multiple ssh keys, it is necessary to use the ssh-agent service. This is an operating system program that manages active ssh keys.

When you first log in, ssh-agent is not running by default. To start it, type this at the commandline:

eval `ssh-agent`

It should respond with something like:

Agent pid 7410

Adding Keys to ssh-agent

Even though ssh-agent is now running, it doesn't help much without keys. To add a key:

ssh-agent add ~/.ssh/{name_of_key}

For Bitbucket, the name of the key you need is:

ssh-agent add ~/.ssh/aclbb_rsa

Depending on whether the key itself is encrypted, it may prompt you for a password. aclbb_rsa is encrypted.

Seeing which keys are active

You can see a list of keys that ssh-agent currently recognizes with:

ssh-agent -l

This is helpful for checking, when a login fails, that the key is actually added to the chain.

Removing keys from ssh-agent

One wrinkle with ssh-agent is that it assumes the key id_rsa by default. If this key exists, it will sometimes get activated in the course of using the program, and for remote services that assume you're using a key by that name (and be warned: Bitbucket is one such service), they may stop trying to authenticate after the process fails on id_rsa - leaving you scratching your head wondering why you can't log in to a service that has never given you trouble before, even though the relevant key is definitely added to ssh-agent!

To remove a key:

ssh-agent -d ~/.ssh/{name_of_key}

Clearing out ssh-agent instances

Still not really sure why this is the case, but if lots of instances of ssh-agent build up, it sometimes happens that Apache takes an excruciatingly long time to restart fcgi scripts after you make changes. This is relevant to the Central Authentication system, which runs as an fcgi script.

To see how many instances of ssh-agent are running, type the following on the command line:

ps aux | grep ssh-agent

If there are lots of them, and you're getting 500 errors from an fcgi process, this is the likely cause. You can clear them all out (you should, of course, do this anyway, even if you're not trying to rescue an fcgi script) with:

killall ssh-agent