Skip to content

Securing SSH

Public Key Authentication

To further secure ssh, we can create a keypair consisting of a public and private key. Setting this up makes the system much more secure as it will only accept ssh connections from clients that hold the private key. We’ll create the keypair on our own client machine (in my case, Linux Mint 17) and then transfer the private key to our server. If your client is Linux Mint or any other recent distro, then the following should work. Open your favourite console app and type:

Creating the Key

ssh-keygen -o -a 100 -t ed25519

This will generate a keypair using the recommended ed25519 public key algorithm, and using 100 rounds to strengthen it against brute force attacks.

You’ll be presented with the following questions:

Enter file in which to save the key (/home/ronald/.ssh/id_rsa):

Just press Enter here.

Enter passphrase (empty for no passphrase):

A passphrase makes for stronger security, but it does mean typing in a password each time you connect. If no password is used then its still more secure than not using a keypair at all.

Your identification has been saved in /your_home/.ssh/id_rsa.
Your public key has been saved in /your_home/.ssh/id_rsa.pub.

We now copy the private key to the remote server with:

ssh-copy-id -p 371 ronald@server_IP_Address

If you have multiple keys in your .ssh folder, you may want to specify the key with the -i switch, eg:

ssh-copy-id -i ~/.ssh/mykey -p 371 ronald@server_IP_Address

Test and Configure

Now ssh to the server from your client device to test the keys.

ssh -p 371 ronald@server_IP_Address

It should ask for a passphrase for the key if you set one, otherwise it should log you straight in.

Next we’ll disable logging in without a key, and completely disable root access via ssh. Do not do this until you are satisfied that the above steps have been done correctly and the key is being used to log in as the user you created earlier:

sudo nano /etc/ssh/sshd_config

Find the following entries and change them to the following:

PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
PermitRootLogin no
Protocol 2

Restart the ssh service so that the new settings take effect:

sudo systemctl reload sshd

Two Factor Authentication for SSH

This is an optional step to strengthen SSH further with two factor authentication. The following assumes that you have already set up your public key SSH authentication. For this, we will utilise the libpam-google-authenticator, and use it in conjunction with a 2FA phone app. I have an Android phone and use the app 'FreeOTP+' for all my 2FA authentications. It's available from the Google Play Store and also the F-Droid store.

Installing Google Authenticator

Firstly we install:

sudo apt install libpam-google-authenticator

and then run Google Authenticator to start setting it up:

google-authenticator

Answer 'yes' to the question about time based authentication tokens.

A QR code will then appear on the screen which you scan using your phone app. You may need to enlarge your terminal window in order to see the entire QR code.

The screen will then display a secret key, a verification code, and a list of emergency scratch codes. Make a note of these and keep them in a very safe place. Each emergency scratch code can be used only once and they enable you to log in successfully in the event that you lose your phone.

Answer 'y' to all remaining questions.

Configuring SSH

Now we need to edit the SSH server configuration file:

sudo nano /etc/ssh/sshd_config

Find the following three lines and ensure they are set to yes.

UsePAM yes
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

PAM stands for pluggable authentication module, and provides an easy way to plug different authentication method into your Linux system.

Now we must restart the SSH daemon to apply the changes.

sudo systemctl restart ssh

Now we need to edit the PAM rule file for SSH daemon as, by default, it asks for a user password to login.

sudo nano /etc/pam.d/sshd

At the beginning of this file, comment out the following line to disable user password authentication. We are not using password authentication as we're using public keys instead.

#@include common-auth

This enables password authentication when ChallengeResponseAuthentication is set to yes.

To also enable one-time password authentication, add the following two lines.

#One-time password authentication via Google Authenticator
auth required pam_google_authenticator.so