Archive for May 7th, 2006
ssh (secure shell) is an extremely useful tool. I won’t say much about it, because odds are if you are reading this blog you know what it is and what it does. One thing I’ve been meaning to do forever is set up my Linux machines to do passwordless authentication, mainly for security. A password is easy to hack, a private key is definitely not-so-much.
So I sat down yesterday and did some digging. And I found a great guide for configuring OpenSSH to use RSA/DSA keys on IBM’s Developer Works Library. The first step is, of course, to generate your keypair. From the article:
% ssh-keygenGenerating public/private rsa1 key pair.
Enter file in which to save the key (/home/drobbins/.ssh/identity): (hit enter)
Enter passphrase (empty for no passphrase): (enter a passphrase)
Enter same passphrase again: (enter it again)
Your identification has been saved in /home/drobbins/.ssh/identity.
Your public key has been saved in /home/drobbins/.ssh/identity.pub.
The key fingerprint is:a4:e7:f2:39:a7:eb:fd:f8:39:f1:f1:7b:fe:48:a1:09
Easy enough, and anyone who has used gpg will have a feel for what’s going on here. A public/private key pair is created in this step. The private key (identity in this example) is created and stored in the user’s .ssh directory. A matching public key (identity.pub) is also created.
The second step of the process is also fairly simple. You have to copy the contents of the public key into the .ssh/authorized_keys on the remote computer. One can use scp or ssh to do this. The beauty of public keys are that they can be freely shared. If someone grabs your public key, there’s not much they can do with it. And they definitely can’t use it to break into the remote machine. The most they can do is copy it onto a machine, then try to get you to log into their computer instead of the remote machine. But that still doesn’t gain them much.
But I digress. After the public key is added to the remote computer’s authorized_keys, ssh will no longer prompt for a password when connecting to the remote computer. It’ll attempt an RSA or DSA authentication, and – assuming you have the correct private key – you’ll be logged on passwordlessly.
Of course, ssh on the local machine will prompt you for the passphrase for your private key every time it is accessed. This is both a good thing (it provides even more security for your private key) and a bad thing (it is a pain in the ass to have to enter a long passphrase over and over and over.
The solution? ssh-agent!
ssh-agent, included with the OpenSSH distribution, is a special program designed to make dealing with RSA and DSA keys both pleasant and secure (see Part 1 of this series for an introduction to RSA and DSA authentication.)
ssh, is a long-running daemon designed for the sole purpose of caching your decrypted private keys.
sshincludes built-in support that allows it to communicate with
sshto acquire your decrypted private keys without prompting you for a password for every single new connection. With
ssh-agentyou simply use
ssh-addto add your private keys to
ssh-agent‘s cache. It’s a one-time process; after using
sshwill grab your private key from
ssh-agent, rather than bugging you by prompting for a passphrase. (IBM Developer Works Library)
In other words, ssh-agent caches your passphrase: enter it once, and ssh-agent remembers it for the rest of that log-in session. Which is definitely a step in the right direction. But there’s two problems with ssh-agent: first, when you log out of your current session, your cached passphrase is gone. Log back into your local computer and you have to run ssh-agent again. Second, shell scripts and other utilities can’t access the ssh-agent session, so they can’t take advantage of ssh-agent.
So there’s one more piece to add to the puzzle: keychain!
To solve these problems, I wrote a handy bash-based
keychain. What makes
keychainspecial is the fact that it allows you to use a single
ssh-agentprocess per system, not just per login session. This means that you only need to do one
ssh-addper private key, period. As we’ll see in a bit,
keychaineven helps to optimize the
ssh-addprocess by only trying to add private keys that aren’t already in the running
Here’s a run-through of how
keychainworks. When started from your ~/.bash_profile, it will first check to see whether an
ssh-agentis already running. If not, then it will start
ssh-agentand record the important SSH_AUTH_SOCK and SSH_AGENT_PID variables in the ~/.ssh-agent file for safe keeping and later use. Here’s the best way to start
keychain; like using plain old
ssh-agent, we perform the necessary setup inside ~/.bash_profile: (IBM Developer Works Library)
One note: if you use the example in the IBM link, the directory that they give in the last step of the example is incorrect. The newest versions of keychain create the file to source in ~/.keychain; the filename format is %HOSTNAME%-sh. So if your local machine hostname is ubuntu1, you’d want the following line in .bash_profile:
With that done, you have a fairly-secure solution. You enter your passphrase once, and the combination of keychain and ssh-agent caches that passphrase until you tell it not to. You can log in and out of your remote machine without needing to re-enter your passphrase. Shell scripts can access this to perform passwordless connections. And, as long as your local machine isn’t compromised (e.g. someone gains physical access to your computer), it’s fairly secure.
Oh, there is one last step: turning off password authentication for ssh. This ensures that the only way someone can make an ssh connection to the remote computer is if they have an RSA/DSA key listed in the authorized_keys file on the remote computer. I haven’t done this yet, because it does mean that no one can connect, not even me! I have to make sure I have a way to get to my computers from anywhere before I do this. I’m thinking I’ll probably get a cheap USB key, copy my private key onto it, and then take it with me.
I’ll post an update here once I turn off password authentication.