Secure Shell with Keys

Secure Shell, or SSH, is a way to log into a text terminal session over a network. It's similar to the ancient Telnet system except that it supports strong encryption. But thats not all - SSH goes way beyond just a terminal. Many other programs can leverage its strong encryption, and it provides all kinds of advanced tunnelling services too.

The basic advantage of using SSH over Telnet is that it won't send your login and password in plain text over the network. So your credentials can't be sniffed by someone who has access to the hardware between you and the destination comptuer. In fact, SSH won't send your password over at all - it will send the target machine a random number and ask it to encrypt that number with your password. Then it will encypt that number itself and compare its results with what the target machine sent back. In this way it can verify that the destination knows your password.

The encryption is done using hashing algorithms. A hashing algorithm is a bit of maths that converts one number into another in a way that's pretty much impossible to reverse.

You can set up an SSH server on a remote machine and then use a local SSH client to log into it. This is the basic and most common way to use SSH. Note that instructions below work without changes on Ubuntu 10.04 and probably many other versions and systems, but your mileage may vary.

Basic SSH Setup

On the server machine:

sudo apt-get install openssh-server openssh-client

That's it! Now, just to test, stay on the server machine and log in with SSH locally:

ssh localhost -l [username]

You should be able to use your current username and password and get a new terminal session. CTRL-D, or use 'exit' to exit.

Now, on the client machine:

sudo apt-get install openssh-client
ssh [server ip] -l [username]

Done! Now you should be able to get a secure terminal session on a remote machine from anywhere with network access. Even over a public network your password will not be sent in the clear, and this is an easy and secure way to do things... as long as you have a good password.

Dictionary Attacks

You'll notice that if you have an SSH server which can be accessed over the Internet (ie. port 22 is open to the outside world), your logs will start filling up with people trying to log in using random usernames. This is called a 'dictionary attack' - where people have programs that just try random logins. If you have a common username and your password is 'password' or '12345', you will likely have a visitor in the first three weeks. There are many more local security exploits than remote ones, so once someone gets access as a normal user, they are well on their way to fully owning your computer.

On my own servers the majority of these scumbags have been from other countries, so one technique is to use a firewall to restrict foreign IP address blocks. But a much more automatic solution is to install fail2ban, which will block people who fail the login process too many times.

Another solution is to not use passwords at all...

Using Keys

SSH can use public keys instead of, or in addition to, passwords. A key is like a very long random password, saved in a file, optionally encrypted itself. It goes without saying that a dictionary attack is not going to guess your key. Also, if your harddrive is relatively secure, you can have a passwordless login to all your servers by loading your key into memory. There's a caveat though: unlike passwords, keys come in pairs.

Using keys to log in is called 'public key authentication'. When you make yourself a key, a pair gets generated - a public key and a private key. The private one is yours and you should protect it, particularly if its not encrypted with a password. Nobody should have a copy of your private key except you. The public one can be known by anyone, and is used to encrypt data that can only be decrypted by you, using your private key. The public key needs to go on all the servers you want to access.

If you already have password-based SSH access, you can use that access to copy your public key to the server.

Public Key Steps

First you need to create a key pair for yourself:

ssh-keygen -f [filename]

Enter a password, unless you are satisfied that nobody else will get a copy of your key. In that case, the private key IS your password and has to be protected. If someone breaks into your system and gets hold of your key without a password, they will probably have access to many more systems.

Now put the public key on the remote server, using your password access:

scp [filename].pub [server ip]:/home/[username]

Log in and move the key file to the right place. If .ssh already exists, be careful not to overwrite an existing authorized_keys file.

ssh [server ip]
cd ~
mkdir .ssh
mv [filename].pub .ssh/authorized_keys    # file exists?
chmod 600 .ssh/authorized_keys            # file must not be public

The authorized_keys file is the default, it can be changed in the server's /etc/ssh/sshdconfig. You can add other public keys to this file and everyone with a corresponding private key will be able to log in to the server with your login name. Also, you can automate these steps to copy your local key to a remote authorizedkeys file with a script that comes with SSH called ssh-copy-id. To duplicate the steps above:

ssh-copy-id -i [filename].pub [username]@[server_ip]

Now, back on the client machine you should be able to log in with your private key:

ssh [server ip] -i [filename]

You should be asked for your key password. If you are asked for your user password, there's something wrong. In that case log in to the server with your user password again and monitor the log file:

ssh [server ip]
sudo tail -f /var/log/auth.log    # default log specified in /etc/ssh/sshd_config

Then open a second terminal on the local client machine and try again to log in with the key, this time turning on some verbose info:

ssh [server ip] -i filename -v

Watch both terminals as you log in again with the key and you should get messages explaining the problem. My most common errors have been permissions problems. Both the authorized keys file and the private key on the client side must not be world readable, so if you have problems the first thing to do is:

chmod 600 [filename]                   # client
chmod 600 ~/.ssh/authorized_keys       # server

Turning Off Password Access

Once your key access works, you may want to turn off password access on your server so that you are no longer vulnerable to dictionary attacks, no matter what your username and password are. To do this, log into the server and edit the /etc/ssh/sshd_config file:

ssh [server ip] -i [filename]
sudo vi /etc/ssh/sshd_config

In the file, set these to 'no':

ChallengeResponseAuthentication no
PasswordAuthentication no

Public key authentication needs to be on, but it probably is already:

PubkeyAuthentication yes

Then save and exit, and reload the SSH server:

sudo /etc/init.d/ssh reload

Now, when you try to login without specifying your key, the login will fail:

$ ssh [server ip]
Permission denied (publickey).

The (publickey) means that the last authentication method that was tried and failed was public key. If you get this error unexpectedly and need an explanation, use the trick above where you tail the auth.log file on the server and use -v with the client.

Memorizing the Private Key

Ubuntu nowadays automatically runs ssh-agent if you have it installed, so you can use ssh-add to get it to remember your key:

ssh-add [filename]

With that done, you will be able to put in your key password once and thereafter ssh-agent will provide your key to any ssh session that needs it. If your key has no password, you then have secure, no-password access to all the servers which have your public key in authorized_keys. But since you only have to enter your key password once, its a good idea to make use of the extra security provided by a key password.

If the ssh-add command failed, ssh-agent may not be in memory. You'll get an error like this:

Could not open a connection to your authentication agent.

I have seen some environments which do not load it automatically for you. In that case, you can start an ssh-agent terminal session manually:

ssh-agent bash

Then your new bash session will have ssh-agent loaded and you can use ssh-add.

Last Words

I hope this article was as simple as possible but no simpler. Please find my contact details on the main page and let me know of any errors, or if anything is unclear.





This is the website of Leslie Viljoen. More info

log in