Secure SSH using Google Authenticator

If you already own a server with SSH, you probably already came across it: Hacked webservers that try to brute force (repeated attempts to login using different users and passwords) your SSH. A whole range of different users and passwords are tried, hoping to get access to your webserver.

There are loads of solutions available to prevent this or make it harder to do. For example, you can deny access from all IP's except your own, you can disallow direct root login, block IP's after a number of failed attempts, or let SSH listen on a different port. Although we strongly recommend using (all) these solutions, there is also an even safer solution: Two factor authentication (2FA).

By using Google Authenticator and your smartphone, you can generate unique codes that only last for 30 seconds. That way, an extra code is required next to your username and password, and that code changes every 30 seconds. The chance of someone guessing the 6 figures of the unique code, is very small. And then they still need your SSH username and password as well.

The tutorial below will show you how to secure your server this way. It is written for Redhat / Fedora /  CentOS servers and requires some SSH knowledge. Ofcourse, it is also possible on other Linux distributions but the commands will differ. We assume that nano is installed but ofcourse you can use any texteditor, like vi.

Require help with this? Contact us.Genereer logincodes voor uw server met uw smartphone


Installation

Make sure you are connected to your server via SSH, as root.

Execute the following commands:
yum -y install ntp chkconfig ntpd on (CentOS 7: systemctl enable ntpd)
ntpdate pool.ntp.org
/etc/init.d/ntpd start (CentOS 7: systemctl start ntpd)
(Because the codes are time related, it is required to set the corect time. ntp will take care of this).

Download and installeer the latest EPEL repository:

CentOS 5:
rpm -Uvh http://ftp.astral.ro/mirrors/fedora/pub/epel/epel-release-latest-5.noarch.rpm
CentOS 6:
rpm -Uvh http://ftp.astral.ro/mirrors/fedora/pub/epel/epel-release-latest-6.noarch.rpm
CentOS 7:
rpm -Uvh http://ftp.astral.ro/mirrors/fedora/pub/epel/epel-release-latest-7.noarch.rpm
Install the required parts:
yum --enablerepo=epel install gcc gcc++ pam-devel subversion python-devel git
Copy the code of google-authenticator:
mkdir /root/google-authenticator; cd /root/google-authenticator
git clone https://code.google.com/p/google-authenticator/cd google-authenticator/libpam/
make && make install

nano /etc/pam.d/sshd
Add this line, above the first auth line:
auth required pam_google_authenticator.so nullok
(nullok will make sure users that didn't setup google authenticator yet, can login without code. This ofcourse is optional but recommended).
nano /etc/ssh/sshd_config
Set:
ChallengeResponseAuthentication yes
Doublethat that UsePAM is set to 'yes'.

You might want to set PubkeyAuthentication to 'no', this means that 'trusted PC's' can no longer login.

To make sure not to lock yourself out if you did something wrong, please set up a second SSH window.
/etc/init.d/sshd restart (CentOS 7: systemctl restart sshd)
Check to see if you can login.

Setup per user

Please log in as the user. Run the command: google-authenticator

Answer yes (y) to every question except the 'increase window time'. You get to see the next data:
https://www.google.com/{linktogoogle}Your new secret key is: {YOUR KEY}
Your verification code is: {YOUR CODE}
Your emergency scratch codes are: {EMERGENCY CODES}
Copy the first line (the link) to the addressbar of your internet browser to generate a QR-code. You can scan that with your phone using the de app 'Google Authenticator'.

Check if you can login with the generated code on your phone.