Actions: | Security

Navigation: Home | Services | Tools | Articles | Other

Getting Started with ssh keys

One of the first steps on the path to security is making it easy for permitted individuals to login and all others are rejected. There are many online and offline discussions of how to do this, the merits and flaws of each method. This article will demonstrate the methods that I recommend for using OpenSSH for granting or denying login to remote unixlike systems. OpenSSH is a suite of tools from the OpenBSD project which is the overwhelmingly toolset for secure network communications.

The basic idea is to create a public key which you can give to anyone who wants to grant you access to their system and a private key which you clutch tight and never reveal to anyone. Then you need to get that public key to where the server, sshd(8), can use it. These next two sections on generating and placing ssh keys assume that your environment and tools use the defaults as provided by many current linux and unixlike systems. Then I'll demonstrate the convenience of ssh-agent.

In this article, the hostname 'here' refers to the originating, local system and the hostname 'there' refers to the remote system, to which we are granting access.

Generate a keypair

here$ mkdir ~/.ssh
here$ chmod 700 ~/.ssh
here$ ssh-keygen -f ~/.ssh/dh_agbc_rsa -t rsa -b 2048 -C "Duncan Hutty, AllGoodBits"
Generating public/private dsa key pair
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in .ssh/dh_agbc_rsa.
Your public key has been saved in .ssh/
The key fingerprint is:
75:6a:89:70:54:65:06:2d:8e:d5:02:ca:96:55:ea:9b Duncan Hutty, AllGoodBits
-f specifies the output file for the private key, call it whatever you want.
-t specifies a keytype of rsa
-b specifies the number of bits in the key
-C specifies a comment string to help you identify it, but is not used by the software

Put the key where the openssh server will find it

here$ ssh 'if [ -d ~/.ssh ]; then mkdir ~/.ssh; fi \
&& cat - >> ~/.ssh/authorized_keys \
&& chmod 700 ~/.ssh \
&& chmod 600 ~/.ssh/authorized_keys' \
< ~/.ssh/

Make sure you use >> in the cat command so you don't clobber any existing authorized_keys file.

ssh-copy-id is another method of installing an ssh key onto a remote machine, but is not available on all unixlike systems:

ssh-copy-id [-i [identity_file]] [user@]remotemachine


You should now be able to access the second machine from the first:

here$ ssh -i ~/.ssh/dh_agbc_rsa
Enter passphrase for key '/home/dhutty/.ssh/dh_agbc_rsa':
[dhutty@there] ~$

SSH key only, denying password based access

Once you have set up public key authentication using ssh, you might want to consider turning off password based authentication. In /etc/ssh/sshd_config on the server, set:

PasswordAuthentication no
ChallengeResponseAuthentication no

This can be done on a per user basis in sshd_config(5) if you prefer using:

Match User <username>

Using ssh-agent

For extra convenience we can use ssh-agent(1) so that we only need to enter the passphrase once per session.

Start ssh-agent and set necessary environment variables:

here$ eval `ssh-agent -s`

-s  specifies that we want sh(1) style output, although it will attempt to guess correctly.

Add our private key:

here$ ssh-add -t 86400 ~/.ssh/dh_agbc_rsa
Enter passphrase for /root/.ssh/dh_agbc_rsa:
Identity added: /root/.ssh/id_dsa (/home/dhutty/.ssh/dh_agbc_rsa)

-t  86400 specifies the maximum lifespan of this key in this agent in seconds.

Other keys can be added to ssh-agent similarly. Keys can be deleted with ssh-add -D.

Agent Forwarding

When I'm using ssh keys to access a machine that I control, I might enable Agent Forwarding, which enables a tunnel from the remote machine back to the original so that the agent is available to enable me to reach further machines. Because of the security implications of this, I don't automatically do this by default:

ssh -A

Extra SSH happiness


When I'm using ssh to connect to a server from multiple sessions or to the same server repeatedly, then I use the multiplex functionality. This allows each subsequent session to use the same TCP connection to the server, which makes login on subsequent sessions faster. There is a minor side-effect of reducing the chance that the original session will timeout in the event that it idles for a while because my focus is elsewhere.

In ~/.ssh/config:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/master-%r@%h:%p


On a untrusted network (which is almost everything, really, no?), it might be nice to send all HTTP traffic over an SSH connection to a trusted destination (that I control), and then on to the destination from there.

This is easy. Just ssh to the trusted destination with Dynamic Forwarding:

ssh -D <pick a highnumbered port>

Then tell the browser to use the port that specified above as the SOCKS proxy. In current Mozilla Firefox, for example, that configuration lives under Advanced>Network>Settings, entering localhost as the SOCKS host and the port specified.

In about:config, set network.proxy.socks_remote_dns = true and Firefox will send DNS requests over the secure proxy as well, so those will not be available to be seen on the local network.