*nix Tip of the Day: SSH Private/Public Keys

Posted Sun 11 May 2008 18:00 under category tips

Hello kind readers, and welcome to by *nix Tip of the Day. It's finals week, and I'm sort of slacking, so I thought I'd post some of my accumulated folk wisdom on the Internet, so that it might help others.

Today's topic is SSH Private/Public Keys. If any of you are CS majors, or go to a tech-heavy school, or generally interact with Linux/OS X/Solaris/HP-UX/AIX/any other *nix, you've probably used SSH. SSH, at its most basic, is a replacement for telnet and rlogin; it allows you to get a shell at a remote machine. However, it does so securely (hence, Secure SHell) using strong encryption. SSH, particularly modern implementations like OpenSSH also has other subsystems like scp (a replacement for rcp, which is in turn a remote version of cp), sftp (a secure replacement for FTP), and such.

Most people, when using SSH, use password authentication. They type ssh user@host and, when prompted, type in their login password to host. This isn't necessarily a bad thing -- it's braindead-easy to set up, generally secure, and works the same way as remote logins have since the beginning of time.

There are some problems with this setup. One of the most obvious is that if you offer password authentication, your system's security is only as good as its worst password. Every user that picks "god" or "password" as his password paints a giant target on your machine.

Enabling password authentication, even if all of your users have strong passwords, still makes you a target. There are plenty of botnets out there that connect to servers and try sshing in with random usernames (and root, of course, but I assume you have root login disabled/restricted in SSH. You do, right? If not, go do so.). It's unlikely that they'll ever break a good password, but that's still traffic hitting your box. Disable password authentication, though, and they go away. Botnets (thankfully) never try to connect using anything else.

So, password authentication isn't great. What should you do instead? Well, it turns out that SSH supports something called public key authentication. The basic idea here is that the remote user has a small file called a private key that they keep with them (on their laptop, or on a flash drive). This key allows them to access the remote server (optionally without any password at all, although this is discouraged on a flash key or laptop) more securely. The authentication is done using either a DSA or RSA with a key-length of between 768 and 2048 bits, which is all technical stuff that you don't care about. Let's talk about setup.

The first thing to do is to prepare the client system and generate the key. The following commands should take care of that:

if [ ! -d ~/.ssh ]  then
    mkdir ~/.ssh
    chmod 700 ~/.ssh
    ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa
    chmod 600 ~/.ssh/*

When you are prompted for a password by ssh-keygen, you should enter something long that you will not forget. It should not be your account password. If you really trust the client system (for example, if it's a desktop machine with no remote login sitting inside a bank vault that nobody could ever break into), you can leave this field empty. But I do not recommend it.

But how do you go about using this key? Note that the keygen will have created a file called ~/.ssh/id_rsa.pub. This is your public key, and needs to be uploaded to every machine that you need access to. Let's call the remote machine remote and the local machine local. The following code should do what you need:

scp ~/.ssh/id_rsa.pub user@remote:~/local.pub
ssh user@remote
if [ ! -d ~/.ssh ] then 
    mkdir ~/.ssh
    chmod 700 ~/.ssh
cat local.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
rm local.pub

If all went well, you should now be able to log into remote using your public key. If you attempt to ssh user@remote, you should be prompted "Enter passphrase for key '/home/user/.ssh/id_rsa'". Type in the passphrase you entered during the key creation step and you're all set.

If typing in this passphrase all of the time seems like a pain in the rear to you, you're not alone. Check back later for the next article in the series, on the use of ssh-agent. It's awesome, I tell you.

Note: I am not responsible for any borkage that these commands might cause. As far as I know, they're correct, but I still disclaim any and all liability. Yadda yadda yadda.

Updated 2008-05-13 00:55 to use correct permissions for the contents of \~/.ssh