The 101 Uses of OpenSSH: Part II of II
Okay. You're ready to enter the next level of ssh-geekdom by creating yourself a user key pair. Here's what you do.
First, on your client system (the machine you wish to use as a remote console) you need to run ssh-keygen. You've got some choices: among other things, you can specify either RSA or DSA keys; key-length; an arbitrary “comment” field; the name of the key-files to be written; and the passphrase (if any) the private key will be encrypted with.
Now that RSA's patent has expired, choosing the algorithm is somewhat arbitrary. On the other hand, the SSH protocol v.2, which is the version submitted to the IETF for consideration as an Internet Standard, uses DSA keys. If you don't care either way, I recommend DSA. But if for any reason you want RSA then go for it. The -d flag sets DSA as the algorithm, otherwise RSA is the default.
Key-length is a more important parameter. Thanks to Adi Shamir's “Twinkle” paper (which describes a theoretical but plausible computer capable of brute-force-cracking RSA/DSA keys of 512 bits or less), I highly recommend you create 1024-bit keys; 768 is okay, but not noticeably faster to use than 1024. However, 2048 is definitely overkill: it isn't significantly more secure, and slows things down noticeably. The default key-length is 1024, but you can use the -b flag followed by a number to specify a different one.
The “comment” field is not used by any ssh process: it's strictly for your own convenience. I usually set it to my e-mail address on the local system. That way, if I encounter the key in authorized_keys files on my other systems, I know where it came from. To specify a comment, use the -C flag.
The passphrase and file names can, but needn't be provided in the command line (using -N and -f, respectively). If missing, you'll be prompted for them.
In Listing 1, I'm creating a DSA key pair with a key length of 1024 bits and a comment-string of firstname.lastname@example.org. I let ssh-keygen prompt me for the file to save the key in. This will be the name of the private key, and the public key will be this name with “.pub” appended to it.
In this example I've accepted the default filename of id_dsa (and therefore id_dsa.pub). I've also let ssh-keygen prompt me for the passphrase. The string of asteriks (“******************”) won't actually appear when you enter your passphrase—I inserted those into the example to indicate that I typed a long passphrase that was not echoed back on the screen.
By the way, passphrases are “all or nothing” propositions: your passphrase should either be empty (if you intend to use the new key as a host key or for scripts that use SSH) or should be a long string that includes some combination of upper- and lower case letters, digits and punctuation. This isn't as hard as it may sound; for example, a line from a song with deliberate but unpredictable mispellings can be easy to remember but difficult to guess. The more random the passphrase, the stronger it will be.
That's all that must be done on the client side. All that needs to be done at each remote machine you wish to access from this host is to add the new public key to $HOME/.ssh/authorized_keys2 (where “$HOME” is the path of your home directory). authorized_keys2 is a list of public keys (one per very long line) that may be used for login by the user whose home directory authorized_keys2 resides in.
To add your public key to a remote host you have an account on, simply transfer the file containing your public key (id_dsa.pub in the above example) to the remote host and concatenate it to your authorized_keys2 file. How you get the file there doesn't matter a whole lot. Remember, it's your public key, so if it were to be copied by an eavesdropper en route, there would be no need for concern. But if you want to be paranoid about it, simply do a scp ./id_dsa.pub remotehostname:/your/homedir--see last month's column for scp instructions. To then add it to authorized_keys2, log on to the remote host and enter:
cat id_dsa.pub >> .ssh/authorized_keys2 (assuming you're in your home directory)
That's it! Now whenever you log in to that remote host using SSH, the session will look something like what you see in Listing 2.
Notice that when I invoked ssh in the listing, I used the -2 flag: this instructs SSH to try SSH Protocol v.2 only. By default Protocol v.1 is used, but v.1 only supports RSA keys and we just copied over a DSA key. Note also that the key is referred to by its local path/filename: this is a reminder that when we use RSA or DSA authentication the passphrase we enter is only used locally to “unlock” our locally stored private key and is not sent over the network in any form.
There's one last thing I should mention about the simple example above. It makes two assumptions about the remote server: (1) that I have the same username as I do locally and (2) that the remote server recognizes SSH Protocol v.2. If the first assumption isn't true I need to use the -l flag to specify my username on the remote host. (Alternatively, I can skip -l and instead use scp-style username@hostname syntax, e.g., email@example.com.)
If Protocol v.2 isn't supported by the remote sshd dæmon I'll have to try again without the -2 flag and let SSH fall back to username/password authentication, unless I've got an RSA key pair whose public key is registered on the remote machine.
To do all this with RSA keys we follow the same steps but with different filenames:
Create an RSA user-key pair with ssh-keygen, for example:
ssh-keygen -b 1024 -C firstname.lastname@example.org
On each remote host you wish to connect to, copy your public key onto its own line in the file authorized_keys in your $HOME/.ssh directory. (The default filenames for RSA keys are identity and identity.pub.)
Again, if you run ssh without the -2 flag, it will try RSA authentication by default.
What happens if you forget your RSA or DSA key's passphrase? How will you get back into the remote machine to change the now-unusable-key's authorized_keys file? Not to worry: if you attempt RSA or DSA authentication and fail for any reason, SSH will revert to username/password authentication and prompt you for your password on the remote system.
If you wish to disable this “fallback” mechanism and maintain a strict policy of RSA/DSA logins only, change the parameter PasswordAuthentication to “no” in sshd_config on each remote host running sshd. As long as we're talking about the server-side of the equation, note that by default sshd allows both RSA and DSA authentication when requested by an ssh client process. The sshd_config parameters to explicitly allow or disallow these are RSAAuthentication and DSAAthentication, respectively.