Two Factor Authentication


This page covers how to install and set up two-factor authentication, using Google Authenticator and SSH.


  • An Ubuntu 14.04 server (or newer).
  • A smart phone or tablet with the Google Authenticator App installed.
  • Google Authenticator Library (see below)


To install the Google Authenticator Library module run the following command.
sudo apt-get install libpam-google-authenticator


To enable two-factor authentication, you first need to run the google authenticator setup program.
Complete the setup by answering the following questions:
Do you want authentication tokens to be time-based (y/n) y
You will now see a QR code, secret key, verification code, and emergency backup codes presented to you.

On your mobile device, launch the Google Authenticator app and either scan the barcode (if you have a barcode reader installed) or enter the secret key.

Note: You should make a copy of the provided backup codes and store them safely for recovery.

Answer the remaining questions choosing (y/n) as appropriate and be sure to enter 'y' when asked to update the .google_authenticator file as this will store a backup copy of the key, etc. on the server under your home directory (unless you have made an external copy for greater security).

Repeat the above process for all users who will be connecting via SSH to this server.

Next, you need to configure SSH to use two-factor authentication by updating PAM and SSH configuration.

Enter the following command to edit the sshd file in PAM.
sudo nano /etc/pam.d/sshd
Locate the line @include common-auth and comment it out as per below below.
# Standard Un*x authentication.
#@include common-auth
Now add the following lines anywhere in the file (at the bottom will work fine).
# Enable Google Two-Factor Authentication
auth required
Now we need to update the global SSH config file.
sudo nano /etc/ssh/sshd_config
Find the term ChallengeResponseAuthentication and change it from 'no' to 'yes'.
ChallengeResponseAuthentication yes
Then find the term PasswordAuthentication and enable it by removing the comment ('#') and set it to 'no'
# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no 
Finally add the following lines at the bottom, for example.
# Enable Google Two-Factor Authentication
AuthenticationMethods keyboard-interactive
If you want to add in a public key, then change the line avobe to this instead. You will need to generate your public key and transfer it to the server in order to enable the public key authentication to work. Ill cover setting up SSH and public keys in another post.
# Enable Google Two-Factor Authentication
AuthenticationMethods publickey,keyboard-interactive
With the above changes made to PAM and SSH, we can restart the server and test things out.
sudo service ssh restart


From another machine, try and connect to the server.
If all is configured correctly, you should be asked for a verification code.
Verification code:
If you enabled publickey authentication, then you will get a similar message to below instead.
Authenticated with partial success.
Verification code:
Enter the password and verification code that your app generates and you will be logged in successfully.


If you have an encrypted home directory, the above will not work as expected. There is a work-around involving moving your authorized_keys outside the encrypted home. This will allow the authentication to read your key. You also need to make the .google_authenticator file accessible in a similar way.

To solve this, create a folder outside your home named /etc/ssh/public_keys/ (replace "" with your actual username). This directory should have 750 permissions and be owned by the user. Move the authorized_keys file into it. The authorized_keys file should have 640 permissions and be owned by the user. 

Then edit your /etc/ssh/sshd_config and add:

AuthorizedKeysFile    /etc/ssh/public_keys/%u/authorized_keys

Finally, restart ssh with:

sudo service ssh restart

The next time you connect with SSH you should not have to enter your password.

Unfortunately, your encrypted drive will now also not automatically decrypt. So we can fix this by modifying .profile to run the decryption.

Finish this doc.