A Beginner's Guide to using keys with SSH

SSH and related tools such as scp and sftp are essential for modern, secure communications between computing systems. Often the weak link in the security chain is the reliance on a username and password for authentication. While these can suffice if suitably strong and well protected it is better yet to use a system of private and public keys which takes much of the security burden off the user in the first place.

How to generate a key pair

Generating a key pair is a simple, cost-free process. Before you start, however, you should choose a suitably secure passphrase in advance. A good passphrase is long (30 characters is a good minimum length) but easy to type (separate words with spaces or other punctuation) and be memorable to the user without being easily guessed. Once you have decided on such a passphrase you can proceed to generate the key pair.

SSH keys are normally stored in ~/.ssh/ so it would be wise to create this directory in advance if it does not already exist and then to change to it.

$ mkdir -m 0700 ~/.ssh
$ cd ~/.ssh
$ ssh-keygen -b 2048 -t rsa -f foo
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in foo.
Your public key has been saved in foo.pub.
The key fingerprint is:
SHA256:QiXbjMCzO3xVJuiWvJz67IB+Dn4jpmq8rsa+PS8DnAg you@yourhost.example.com
The key's randomart image is:
+---[RSA 2048]----+
|   .. ...        |
|    o..B. o      |
|     =+.o+       |
|E   ..= .        |
|+ .. +.+S        |
|.+ .+ =.         |
|o + .+           |
| B+==o           |
|@B=**=+          |
$ ls
foo     foo.pub

In this sequence of commands, the 2048 refers to the bit length of the keys and should be considered a minimum for modern use, the rsa is the encryption algorithm to use (and is probably the most widely supported) and foo is simply the basename of the files to use. You should type in your chosen passphrase (twice) when prompted; the keystrokes are not echoed to the screen. You will see afterwards the two new files in the .ssh directory. foo is the private key - look after this well and do not divulge it to anyone. foo.pub is the public key and may be shared widely with those to whom you wish to connect. Do not confuse the two keys.

How to use a key pair

You can now distribute your public key among the providers hosting the accounts you wish to connect to. Only send the public key. This may be done in the clear. Your providers can then install the key on the server side for you.

To access your remote account using the key, you can invoke ssh like this:

$ ssh -i ~/.ssh/foo -l username www.example.com
Enter passphrase for key '/home/username/.ssh/foo':

Here -l username sets the user on the remote server and can be omitted if this is the same as the local username.

Using an agent

If you connect frequently over ssh/sftp/scp it can become laborious to have to re-type a long passphrase and to specify your key on the command line every time. This can be avoided by using an ssh agent.

The agent is typically run as part of your login session on your local machine. Test $SSH_AGENT_PID or run ps xw | grep ssh-agent to see if you have one running and if not consult the documentation for your session manager to determine how to set it up.

Once you have a running agent, simply use the ssh-add command to add a key to it:

$ ssh-add ~/.ssh/foo
Enter passphrase for key '/home/username/.ssh/foo':
$ ssh -l username www.example.com

Now when you connect you no longer have to specify the key or type in the passphrase as the agent takes care of that for you.

Mounting remote filesystems

SSH can be used to mount remote filesystems through FUSE so that they become accessible via the local filesystem. You will need to have both sshfs and fuse installed but they are available in most distros via the fuse-sshfs package.

To mount a remote filesystem you must have a ready mount point and have set up your ssh access to the remote host. Then it is a simple matter of running sshfs to set up the mount.

$ mkdir mnt
$ sshfs username@www.example.com: mnt
$ ls -1 mnt
$ cat mnt/foo.txt
This is a test file only.
$ df mnt
Filesystem     1K-blocks    Used Available Use% Mounted on
mnt:            50264772 8771608  38933164  19% /home/you/mnt

Here the user creates a directory mnt which will act as the mount point and then mounts their remote home directory from the www.example.com host onto this point. From then on the files on the remote host such as foo.txt and bar.txt can be accessed as if they were on the local machine's drive as shown in the cat command. The df command shows the details of the remote mounted system.

When you are finished you can simply unmount the remote system:

$ fusermount -u mnt
$ df mnt
Filesystem     1K-blocks   Used Available Use% Mounted on
/dev/sda3       10321208 205012  9591908    3% /home
$ ls mnt

The ls and df commands show that the remote system is no longer mounted here.