Adding 2FA For CentOS/Ubuntu Servers


This is a quick guide to set up two-factor authentication on CentOS/Ubuntu servers. By quick, I mean that I'm not going to explain much. I'm only writing this because I feel bad that I haven't made a post in over a month.

For this guide, we will be using the Google Authenticator app which you can download on your phone, although I think the PAM (Pluggable Authentication Module) also generates TOTPs compatible with Authy. So make sure you have one of those installed first.

Okay let's get started.

Install Google's PAM

On CentOS:

# Add the EPEL repo (if you haven't already)
$ sudo yum install
# Install PAM
$ sudo yum install google-authenticator

On Ubuntu:

$ sudo apt-get install libpam-google-authenticator

Now run the initialisation app:

$ google-authenticator

You'll be asked a few questions. I forgot what they where, so you're on your own with this, just read them and you'll probably be fine. After the first question a lot of output will scroll past, including a large QR code. At this point, use your authenticator app on your phone to scan the QR code or manually type in the secret key. Make sure you also record the secret key, verification code, and the recovery codes in a safe place.

Configuring SSH

Open /etc/pam.d/sshd in the only good editor:

$ sudo vim /etc/pam.d/sshd

And add this line to the bottom:

auth required

Now we need to configure SSH t support the authentication, open /etc/ssh/sshd_config:

$ sudo vim /etc/ssh/sshd_config

Look for the ChallengeResponseAuthentication line. Change it from no to yes:

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication no
ChallengeResponseAuthentication yes

Restart SSH:

$ sudo systemctl restart sshd.service

Now we can test if it works, open a new terminal session and attempt to SSH into it. If you don't use SSH keys, you're an idiot, but it should prompt for a verification code after you enter the password. If you're smart and previously created an SSH key, you'll notice you didn't have to type a verification code. This is because an SSH key overrides all other authentication options by default.

The Next Part will go through changing that to set up an SSH key as one factor and the verification code as a second.

The Next Part

Open the sshd config file again and add the following line to the bottom:

AuthenticationMethods publickey,password publickey,keyboard-interactive

Next, open the PAM sshd configuration file again. On CentOS, comment out this line:

#@include common-auth

On Ubuntu, comment out this line:

#auth substack password-auth

Now, restart the SSH service and test it again. If it all works, you should now call me your saviour who prevented you from getting hacked and losing millions of dollars because your developers have no idea what they're doing and setup their enterprise systems by following guides from shitty blogs.

You're welcome.

Update 2019-01-22: My TravisCI deployment script was messed up because of this. But it was an easy fix, just disable PAM for the user group TravisCI used.