Ssh keys

From SciNetWiki
Jump to: navigation, search

SSH has an alternative to passwords to authenticate your login; you can generate a key file on a trusted machine and tell a remote machine to trust logins from a machine that presents that key. This can be both convenient and secure, and may be necessary for some tasks (such as connecting directly to compute nodes to use some visualization packages). Here we describe how to setup keys for logging into SciNet.


SSH Keys and SciNet

SSH is a secure protocol for logging into or copying data to/from remote machines. In addition to using passwords to authenticate users, one can use cryptographically secure keys to guarantee that a login request is coming from a trusted account on a remote machine, and automatically allow such requests. Done properly, this is as secure as requiring a password, but can be more convenient, and is necessary for some operations.

On this page, we will assume you are using Linux, Mac OS X, or a similar environment such as Cygwin under Windows. If not, the steps will be the same, but how they are done (for instance, generating keys) may differ; look up the documentation for your ssh package for details.

Using SSH keys

How SSH keys work

SSH relies on public key cryptography for its encryption. These cryptosystems have a private key, which must be kept secret, and a public key, which may be disseminated freely. In these systems, anyone may use the public key to encode a message; but only the owner of the private key can decode the message. This can also be used to verify identities; if someone is claiming to be Alice, the owner of some private key, Bob can send Alice a message encoded with Alice's well-known public key. If the person claiming to be Alice can then tell Bob what the message really was, then that person at the very least has access to Alice's private key.

To use keys for authentication, we:

  • Generate a key pair (Private and Public)
  • Copy the public keys to remote sites we wish to be able to login to, and mark it as an authorized key for that system
  • Ensure permissions are set properly
  • Test.

Generating an SSH key pair

Note: This describes creating ssh key pairs on your machine, not on SciNet. On SciNet, you already have key pairs generated, sitting in ${HOME}/.ssh/, and modifying them is likely to cause problems.

The first stage is to create an SSH key pair. On most systems, this is done using the command


This will prompt you for two pieces of information: where to save the key, and a passphrase for the key. The passphrase is like a password, but rather than letting you in to some particular account, it allows you to use the key you've generated to log into other systems.

There are a series of possible options to ssh-keygen which allow increasingly cryptographically secure keys (by increasing the number of bits used in the key), or by choosing different encryption systems. The defaults are fine, and we won't discuss other options here.

The default location to save the private key is in ${HOME}/.ssh/id_rsa (for an RSA key); unless you have some specific reason for placing it elsewhere, use this option. The public key will be in the same directory.

Your passphrase can be any string, and of any length. It is best not to make it the same as any of your passwords.

A sample session of generating a key would go like this:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (${HOME}/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in ${HOME}/.ssh/id_rsa.
Your public key has been saved in ${HOME}/.ssh/
The key fingerprint is:
79:8e:36:6a:78:7d:cf:80:94:90:92:0e:74:0b:f1:b7 USERNAME@YOURMACHINE

Don't Use Passphraseless Keys!

If you do not specify a passphrase, you will have a completely "exposed" private key. This is a terrible idea. If you then use this key for anything it means that anyone who sits down at your desk, or anyone who borrows or steals your laptop, can login to anywhere you use that key (good guesses could come from just looking at your history) without needing any password, and could do anything they wanted with your account or data. Don't use passphraseless keys.

We should note that we do, in fact, have one necessary and reasonable exception here -- the keys used within SciNet itself. The SciNet key used for within-scinet operations (you already have one in your account in ~/.ssh/id_rsa) is passphraseless, for two good reasons. One is that, once you are on one SciNet machine (like the login node), you already have read/write access to all your data; all the nodes mount the same file systems. So there is little to be gained in protecting the SciNet nodes from each other. The second is practical; ssh is used to login to compute nodes to start your compute jobs. You obviously can't be asked to type in a passphrase every time one of your jobs starts; you may not be at your computer at that moment. So passphraseless keys are ok within a controlled environment; but don't use them for remote access.

Copying the Public Key to SciNet (and elsewhere)

Now that you have this SSH "identity", you use the public (not the private) key for access to remote machines. The public key must be put as one line in the file /home/USERNAME/.ssh/authorized_keys. Do not delete the lines already there, or you may end up with strange problems using SciNet machines.

You can copy your new public key to the SciNet systems

scp /home/LOCAL_USERNAME/.ssh/

Then login to SciNet and copy&paste the contents from ~/newkey into ~/.ssh/authorized_keys.

cat ~/newkey >> ~/.ssh/authorized_keys

.ssh Permissions

Note that SSH is very fussy about file permissions; your ~/.ssh directory must only be accessible by you, and your various key files must not be writable (or in some cases, readable) by anyone else. Sometimes users accidentally reset file permissions while editing these files, and problems happen. If you look at the ~/.ssh directory itself, it should not be readable at all by anyone else:

ls -ld ~/.ssh
drwx------ 2 USERNAME GROUPNAME 7 Aug  9 15:43 /home/USERNAME/.ssh

and authorized_keys must not be writable:

$ ls -l ~/.ssh/authorized_keys 
-rw-r--r-- 1 USERNAME GROUPNAME 1213 May 29  2009 /home/USERNAME/.ssh/authorized_keys

Testing Your Key

Now you should be able to login to the remote system (say, SciNet):

$ ssh
Enter passphrase for key '/home/USERNAME/.ssh/id_rsa': 
Last login: Tue Aug 17 11:24:48 2010 from HOMEMACHINE


This SciNet login node is to be used only as a
gateway to the GPC and TCS.


If this doesn't work, you should be able to login using your password, and investigate the problem. For example, if during a login session you get an message similar to the one below, just follow the instruction and delete the offending key on line 3 (you can use vi to jump to that line with ESC plus : plus 3). That only means that you may have logged in from your home computer to SciNet in the past, and that key is obsolete.

$ ssh

Someone could be eavesdropping on you right now (man-in-the-middle
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
Please contact your system administrator.
Add correct host key in /home/<user>/.ssh/known_hosts to get rid of
this message.
Offending key in /home/<user>/.ssh/known_hosts:3
RSA host key for 
< <>> has
changed and you have requested
  • If you get the message below you may need to logout of your gnome session and log back in since the ssh-agent needs to be

restarted with the new passphrase ssh key.

$ ssh

Agent admitted failure to sign using the key.

(Optional) Using ssh-agent to Remember Your Passphrase

But now you've just replaced having to type a password for login with having to type a passphrase for your key; what have you gained?

It turns out that there's an automated way to manage ssh "identities", using the ssh-agent command, which should automatically be running on newer Linux or Mac OS X machines. You can add keys to this agent for the duration of your login using the ssh-add command:

$ ssh-add
Enter passphrase for /home/USERNAME/.ssh/id_rsa: 
Identity added: /home/USERNAME/.ssh/id_rsa (/home/USERNAME/.ssh/id_rsa)

and then logins will not require the passphrase, as ssh-agent will provide access to the key.

When you log out of your home computer, the ssh agent will close, and next time you log in, you will have to ssh-add your key. You can also set a timeout of (say) an hour by using ssh-add -t 3600. This minimizes the number of times you have to type your passphrase, while still maintaining some degree of key security.

Multiple ssh private keys

In quite a few situations its preferred to have ssh keys dedicated to each service, specific role or domain.

ssh-keygen -t rsa -f ~/.ssh/id_rsa.SciNet   -C "Key for SciNet"
ssh-keygen -t rsa -f ~/.ssh/id_rsa.SHARCNET -C "Key for SHARCNET"
ssh-keygen -t rsa -f ~/.ssh/id_rsa.DCS      -C "Key for Dept. Of Computer Science"
ssh-keygen -t rsa -f ~/.ssh/id_rsa.CITA     -C "Key for CITA"

Use different file names for each key. Lets assume that there are 2 keys, ~/.ssh/id_rsa.SciNet and ~/.ssh/id_rsa.SHARCNET. The simple way of making sure each of the keys works all the time is to now create config file for ssh:

touch ~/.ssh/config
chmod 600 ~/.ssh/config
echo "IdentityFile ~/.ssh/id_rsa.SciNet"   >> ~/.ssh/config
echo "IdentityFile ~/.ssh/id_rsa.SHARCNET" >> ~/.ssh/config

This would make sure that both keys are always used whenever ssh makes a connection. However, ssh config lets you get down to a much finer level of control on keys and other per-connection setups. The recommendation is to use a key selection based on the Hostname. For example, a ~/.ssh/config that looks like this :

Host SciNet
  IdentityFile ~/.ssh/id_dsa.SciNet
  User pinto

  IdentityFile ~/.ssh/id_rsa.SHARCNET
  User jchong
  Port 44787

And just login with the shortcut:

$ ssh SciNet

SSH tunnel

A more obscure use of ssh is to generate a communication tunnel. As an example, assume you want to access a website running on a remotehost using your localhost, but there is a firewall between the 2 systems blocking every port, except incoming ssh.

The basic syntax of the ssh command for such a purpose is:

ssh -f -N -L localport:localhost:remoteport user@remotehost
# -f puts ssh in background
# -N makes it not execute a remote command

If the remote website broadcasts on the default port 80, you could do the following:

ssh -L 8080:localhost:remotehost:80 tunneluser@remotehost

... and point your local browser to http://localhost:8080

If you don't want to remember the above sequence of flags all the time, you can add an entry to your ~/.ssh/config:

Host tunnel
    HostName remotehost
    IdentityFile ~/.ssh/id_rsa.tunnel
    LocalForward 8080
    User tunneluser

To open the tunnel just issue the command:

$ ssh -f -N tunnel
Personal tools
Knowledge Base