Wednesday, 14 May 2014

Set Up SSH Agent Forwarding on a Server

This is part of a series of articles on Red Hat Server Hardening.

SSH is the Secure Shell protocol which can be used for command line access, file transfer and application tunnelling.


Password free access requires a public/private key pair. The server (sshd) has access to the public key, while only you and your SSH client have access to the private key. To authenticate the client convinces the server that it is in possession of the private key without actually sending it.

Private keys are protected by a pass phrase. This pass phrase is required each time the key is used. To allow repeated access without re-keying of the pass phrase, agent forwarding is used.

The SSH agent allows the pass phrase to be entered once only, e.g. at system start-up or in the originating shell and then caches the keys in memory, eliminating the need for the phrase to be entered for each access. Because the agent is forwarded the pass phrase is available for all sessions that can access the keys in the home directory, including chains of sessions.


The steps required to set up password free access are:
  1. Generate a key pair using OpenSSH
  2. Distribute public keys
  3. Configure agent forwarding

Generate SSH key pair

ssh-keygen is a program in the OpenSSH package that can be used to create key pairs. RSA is the current SSH key standard; DSA and RSA1 keys can be generated for compatibility with older systems.

Use the full path to ssh-keygen to ensure the correct OpenSSH binary is used, key in a pass phrase when prompted and accept the default file locations. 

> /usr/bin/ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/milned/.ssh/id_rsa):
Created directory '/home/milned/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/milned/.ssh/id_rsa.
Your public key has been saved in /home/milned/.ssh/
The key fingerprint is:
77:3f:47:01:92:5f:d0:fe:3e:6a:03:a4:9a:0a:18:26 milned@nyssa

Similarly DSA and RSA1 keys can be generated. Again enter a pass phrase and accept the default file locations as prompted. Using the same pass phrase for all keys will simplify operation of the SSH agent. 

> /usr/bin/ssh-keygen -t dsa
> /usr/bin/ssh-keygen -t rsa1

Distribute SSH Public Keys

The public keys must be distributed to the user's authorized_keys file so that any SSH daemon with access to the user's home directory can use them.

> cd ~/.ssh
> cat *.pub > authorized_keys

Change the permissions on this file so it is not writable by other users.

> chmod go-w authorized_keys

Now check that key authentication is working, by using ssh to connect to the host you are currently logged in to using its hostname. You should be prompted for the pass phrase for one of your keys. If this is the first time you've talked to the machine you will also be asked to accept the host key, which you should do.

> ssh nyssa
The authenticity of host 'nyssa (' can't be established.
RSA key fingerprint is 85:4b:2a:53:48:52:9f:61:ed:0a:33:4a:9d:5e:d3:1a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'nyssa' (RSA) to the list of known hosts.
Enter passphrase for key '/home/milned/.ssh/id_rsa':
Last login: Thu Nov 21 17:27:35 2013 from tegan

SSH access is now configured to use keys rather than a password to grant access. Access to the key is controlled by a pass phrase. In the next step agent forwarding is set up so that this pass phrase only needs to be entered once.

Configure SSH Agent Forwarding

To check if there is already an agent running use ssh-add.

> /usr/bin/ssh-add -l
Could not open a connection to your authentication agent

If this command reports anything else, then there is an agent running. Otherwise, start an agent using the command:

> exec ssh-agent $SHELL This creates a new shell process as a child of the agent with suitable environment variables set. This agent will live until you exit from this shell, and is only accessible from it.

Running ssh-add should now show the agent is present, but with no identities.
> /usr/bin/ssh-add -l
The agent has no identities
The next step is to add the keys using ssh-add. This will prompt you for the pass phrase for one of your keys, and then assuming they all have the same pass phrase, add them all to the agent:

> /usr/bin/ssh-add
Enter passphrase for /home/milned/.ssh/id_rsa:
Identity added: /home/milned/.ssh/id_rsa (/home/milned/.ssh/id_rsa)
Identity added: /home/milned/.ssh/id_dsa (/home/milned/.ssh/id_dsa)
Identity added: /home/milned/.ssh/identity (milned@nyssa)
Check the keys are available with ssh-add again, which should now report a list of key signatures.
> /usr/bin/ssh-add -l
1024 90:d1:83:5c:2a:33:9b:c7:ba:85:8e:ef:b7:c0:32:05 milned@nyssa (RSA1)
1024 9f:c0:e4:ed:f1:c4:ec:de:6e:af:4c:91:13:8d:58:45 /home/milned/.ssh/id_rsa (RSA)
1024 ab:a1:89:d7:d5:06:d2:d5:c4:18:e6:bc:65:37:96:dc /home/milned/.ssh/id_dsa (DSA)
You should now be able to use ssh to connect to any other machine which is running OpenSSH and has your home directory mounted, and not be prompted for a password. Chaining SSH connections (ssh from a to b and then from b to c) should work via agent forwarding.

Automating SSH Agent Forwarding

Rather than running the above manually, it can be built into the .bashrc file so that it starts automatically when bash is started.

> cd
> cat .bashrc
export PS1="\u@\H \w> "

Amend .bashrc as follows:
export PS1="\u@\H \w> "
ssh-agent > $HOME/
if [ -f $ssh_agent ]
  source $ssh_agent > /dev/null
alias stat="perl -e'print "%o\n",(stat shift)[2] & 07777' $1"
export EDITOR=vi