Linux notes

Using SSH with Public Key Authentication

Most people use SSH with a password. This is fine, but can become a problem if you have a weak password, someone gets hold of it somehow or you forget what it is. It also opens you up to a so-called dictionary attack, where many (automated) attempts are made to try and login by running through possible username/password combinations. I have a firewall machine at home that suffers this problem on a daily basis. Below is an extract from a log on that machine that records failed login attempts.
Nov 26 10:24:26 myserver sshd[2887]: Illegal user staff from ::ffff:200.75.46.140
Nov 26 10:24:30 myserver sshd[2889]: Illegal user sales from ::ffff:200.75.46.140
Nov 26 10:24:34 myserver sshd[2891]: Illegal user recruit from ::ffff:200.75.46.140
Nov 26 10:24:37 myserver sshd[2893]: Illegal user alias from ::ffff:200.75.46.140
Nov 26 10:24:44 myserver sshd[2895]: Illegal user office from ::ffff:200.75.46.140
Nov 26 10:24:49 myserver sshd[2897]: Illegal user samba from ::ffff:200.75.46.140
Nov 26 10:24:55 myserver sshd[2899]: Illegal user tomcat from ::ffff:200.75.46.140
Nov 26 10:24:58 myserver sshd[2901]: Illegal user webadmin from ::ffff:200.75.46.140
Nov 26 10:25:02 myserver sshd[2903]: Illegal user spam from ::ffff:200.75.46.140
Nov 26 10:25:06 myserver sshd[2905]: Illegal user virus from ::ffff:200.75.46.140
Nov 26 10:25:11 myserver sshd[2907]: Illegal user cyrus from ::ffff:200.75.46.140
Nov 26 10:25:14 myserver sshd[2909]: Illegal user oracle from ::ffff:200.75.46.140
Nov 26 10:25:18 myserver sshd[2911]: Illegal user michael from ::ffff:200.75.46.140
Nov 26 10:25:20 myserver sshd[2913]: Illegal user ftp from ::ffff:200.75.46.140
...
This particular attack made 142 separate attempts with various names and passwords. All failed, but it is annoying to keep seeing someone trying to break in, even if they don't succeed.

Authenticating by cryptographic key

Doing away with the login that relies on a password would be nice, and SSH allows for this by letting you use a cryptographic key. In a nutshell, such a key consists of two files - a public and a secret key. The secret key you keep very secure on the machine you want to use to connect to other SSH servers. The public key you distribute as widely as possible - specifically you must install it on the remote machine running SSH that you wish to connect to using this key-based authentication scheme.

The article will show you, step-by-step, how to set up such a system that will allow you to log in to remote SSH servers without a password. Because there are subtle differences between systems, I am going to give instructions for the following case.

Step 1: Generate a key pair

The first thing we need is a key pair - remember, these are the two files that are the 'public' and 'secret' keys. We will make them in Cygwin using the program ssh-keygen.

The 'strength' of a key is related to the numbers of bits in it, and the type of algorithm used to generate it. The number of bits in the key is specified with the -b switch and the algorithm type with the -t switch. We will generate a very secure 4096 bit key of the RSA type with the command:

ssh-keygen -b 4096 -t rsa
Issue this command in a Cygwin window. You'll get the following sequence in response.
Generating public/private rsa key pair. Enter file in which to save the key (/home/cyguser/.ssh/id_rsa):
If you hit enter above, the key (or the 'identity' as it is called) will be placed in a file called id_rsa in the directory /home/cyguser/.ssh on your machine. I chose to give the key a different name and location at this point, so I entered /home/cyguser/.ssh/mykey_id_rsa. Note that I had to specify the full path as well as the new name of the key file.
Enter passphrase (empty for no passphrase):
You need to enter a passphrase for your key. This - like a normal password - should be memorable for you but not easily guessable. The usual rules of good password choice apply.
Enter same passphrase again:
Enter the same passphrase again to make sure you haven't made a mistake typing it.
Your identification has been saved in /home/cyguser/.ssh/mykey_id_rsa. Your public key has been saved in /home/cyguser/.ssh/mykey_id_rsa.pub The key fingerprint is: 88:73:35:64:2b:99:a5:bb:4e:8e:32:8e:4e:ba:a0:74 cyguser@machinename
This tells you where your new keys are, as well as the fingerprint, which is a condensed code you can use to find or check a key. No need to worry about that at this stage.

If you look in the directory /home/cyguser/.ssh at this point you'll see two new files, mykey_id_rsa and mykey_id_rsa.pub. The one ending in .pub is your public key, and is the one you will distribute to other machines, etc. The mykey_id_rsa file with no extension is your secret key (or 'identity') and must be guarded carefully. Absolutely do not distribute it or allow anyone else access to it.

Step 2: Copy the public key to the remote server machine

The next step is to copy the public key file to the appropriate place on the remote machine - the one you want to connect to via SSH - so that its SSH server will know about it and can use it to authenticate you.

The public key file mykey_id_rsa.pub should be copied from your client machine to the .ssh directory of the user account you would like to access on the remote machine. For example, if you would like to use your key to access the account of user richard on the remote machine, copy the public key file to the directory /home/richard/.ssh.

The copied file has to be renamed at the remote machine. Instead of mykey_id_rsa.pub it has to be called authorized_keys2. If the authorized_keys2 file does not already exist in the remote directory, simply copy the file and rename it. If there is already an authorized_keys2 file, you need to append the new key information to it rather than overwriting it.

Step 3: Configure the remote server properly

Now the SSH server on the remote machine has to be correctly configured. Do this by editing the sshd_config file, normally found in /etc/ssh, so that the following keywords are set as shown.
RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile %h/.ssh/authorized_keys ChallengeResponseAuthentication no
The AuthorizedKeysFile line tells SSH where to look for the public keys it needs, and ChallengeResponseAuthentication tells it to no longer allow authentication with a password (also known as 'challenge-response').

After you have modified the sshd_config file, be sure to restart the SSH server with /etc/init.d/ssh restart.

Step 4: Test key-based login from the command line

Now it's time to try and log in to the remote system and see if you are able to authenticate using the key rather than the password.

Here's the conventional prompt you will see if you are authenticating using a password (the normal method, in other words).

ssh -l richard myremote.machine.net Password:
Try the same command again, but now your attempt should be rejected.
ssh -l richard myremote.machine.net Permission denied (publickey).
If you don't see this, but instead are still allowed to log in using the password as before, it is likely you forgot to set ChallengeResponseAuthentication to 'no' in sshd_config, and/or restart SSH after making the change to the configuration.

Non-default identity

There's one other thing you need to know before you can log in with your new key. You'll recall we renamed our key from the default (id_rsa) to something else (mykey_id_rsa). By doing this we changed our default identity, so now we have to explicitly tell SSH what identity file (aka key file) to use when we log in. We do this with the -i option.

Our new login command is:

ssh -i ~/.ssh/mykey_id_rsa -l richard myremote.machine.net
and now we will be asked to authenticate using the password we chose earlier when we generated the key.
ssh -i ~/.ssh/mykey_id_rsa -l richard myremote.machine.net Enter passphrase for key '/home/cyguser/.ssh/mykey_id_rsa':
If you enter the passphrase, you'll be logged in as normal.

Step 5: Import your private key into WinSCP

So far, we have key-based authentication working from the Linux or Cygwin command line, but what about when we want to use WinSCP as a file-transfer tool?

It turns out we can use WinSCP with keys just as well as with passwords, although there is a little more work to do because the format WinSCP uses for its keys is different from that used by OpenSSH. In fact, this is more a problem with SSH Version 2 than anything else, and has to do with the lack of a standard for the way keys can be stored.

WinSCP stores its keys in a different format to that used by OpenSSH. Because of this, we have to import our SSH keys into WinSCP and then export them again in 'WinSCP' format. This is done using the PuTTY Key Generator, PuTTYgen, which will have been installed along with WinSCP if you performed a full install using an installation package.

To convert a key to WinSCP's format, start PuTTYgen and select Import key from the Conversions menu. Locate the file containing your private key: in our example this is the file mykey_id_rsa in the directory /home/cyguser/.ssh. PuTTYgen will then ask you for the passphrase for the key. If you give it correctly, the key will be imported and you will it displayed in the main PuTTYgen window. At this point it is a good idea to change the 'Key comment' field to something a little more meaningful than 'imported-openssh-key'. I give a short hint about the key and its purpose, for example, 'My work key' or something equally descriptive.

To write out the new key in WinSCP/PuTTY format, press the Save private key button. Although you can choose any name for the new file at this point, I usually give it the same one as the original key, since PuTTY will give it a different extension anyway (.ppk). Once this is done you can close the PuTTYgen program.

If you now look at the contents of the /home/cyguser/.ssh directory you will see a new file, mykey_id_rsa.ppk, which is the WinSCP-compatible private key file.

Step 6: Configure your 'key agent'

One likely difference between the old password you used to use and the passphrase you chose for your new key is (hopefully) the length. Your passphrase is hopefully longer and more complicated but less easy to remember and a pain to type in repetitively. WinSCP can use a program called a key agent to keep your key password ready for use at any time, by having you tell it what the password is just once. This can be very convenient when you are making numerous connections.

The key agent program is called Pageant, and we will want to add our newly-converted key, mykey_id_rsa.ppk, to it.

If Pageant is not running, start it. If it is running, there should be a little 'computer with a hat' icon in your tray. Double-click it to open the Pageant Key List window. In this window will be shown the other keys you may have added previously, if any. To add your new key, press the Add Key button, navigate to and select the key file mykey_id_rsa.ppk, You will once again be asked for the passphrase associated with the key. If entered correctly, the key will be added to the list, with its comment visible at the end. You can see why changing the comment from the default is a good idea, as it helps you easily see if Pageant has the right key(s) available for use.

Step 7: Test key-based login from WinSCP

If you don't already have a WinSCP session stored for the connection to your remote machine, you should make one. You will need to enter the host name of the machine, the port number (if different from the normal port 22) and the user name of the remote account you want to connect to (and the one to which you added your public key). You can leave the password field blank - we're not using them any more! The Private key file field can also be left blank as WinSCP will automatically ask Pageant for the appropriate key.

Once you have made and saved your profile, try and use it to login. It should be successful, and if so, welcome to a new level of security and convenience for your SSH connections!