Enhancing SSH Security: A Guide to Setting Up 2FA with Google Authenticator

Security tutorial - IT technology blog
Security tutorial - IT technology blog

Introduction: Adding Another Lock to the SSH Door

Imagine your server is a valuable house, and SSH is its front door. Usually, we only lock this door with a single layer: a password. But what happens if a thief gets that key (a leaked password), or worse, they are patient enough to try every possible key (a brute-force attack)? Clearly, your house is in danger.

Recently, while auditing the security of over 10 servers, I discovered an alarming commonality: SSH was only protected by a password. Even if it’s a super-complex password, it’s still just a single checkpoint. In reality, automated brute-force attacks on SSH happen daily, hourly, across the internet, silently probing for such vulnerable ‘doors’.

So, how do we reinforce this ‘door’? The answer is to add another lock, also known as Two-Factor Authentication (2FA). With 2FA, an attacker won’t be able to get in even if they know your password. They’ll need the second factor: a random authentication code from the phone you always carry. This article will guide you step-by-step to build that solid layer of protection.

Key Concepts

What is Two-Factor Authentication (2FA)?

2FA, or Two-Factor Authentication, is a security method that requires users to provide two different types of evidence to prove their identity. Simply put:

  • Factor 1: Something you know (e.g., a password, a PIN).
  • Factor 2: Something you have (e.g., a phone, a USB token).

When logging into SSH with 2FA, you first enter your password (factor 1), and then the system will ask for a 6-digit code from the Authenticator app on your phone (factor 2). You can only access the server when you provide both pieces of information correctly.

How Does Google Authenticator Work?

Google Authenticator uses an algorithm called Time-based One-Time Password (TOTP). Basically, it works like this:

  1. During setup, the server and the app on your phone agree on a shared “secret key”.
  2. Every 30 seconds, both the server and your app use this secret key along with the current time to generate a 6-digit code.
  3. Because they both use the same formula and secret key, the resulting 6-digit code is identical. When you enter the code from your phone, the server simply compares it with the code it generated itself. If they match, you’re allowed in.

A major plus is that after the initial setup, your phone doesn’t need an internet connection to generate codes.

Detailed Walkthrough: Setting Up 2FA for SSH on Ubuntu

Now for the most important part: the hands-on tutorial! This guide is demonstrated on Ubuntu 22.04, but you can easily adapt it for other Ubuntu versions or other Debian-based operating systems.

Step 1: Install the Google Authenticator Module

First, we need to install a special PAM (Pluggable Authentication Modules) module so that the system can ‘understand’ Google Authenticator’s method. This module is called libpam-google-authenticator.

Open your terminal and run the following commands:

sudo apt update
sudo apt install libpam-google-authenticator -y

Step 2: Generate a 2FA Code for Your User Account

Important note: run this command as the specific user you want to enable 2FA for, absolutely not with the root account.

google-authenticator

After running the command, the terminal will display a large QR code along with some extremely important information. Please read it very carefully:

Google Authenticator QR Code Setup

  • QR Code: Use the Google Authenticator app (or Authy, Microsoft Authenticator) on your phone to scan this code.
  • Your new secret key: This is the secret key in text form. You must back up this key and store it in an extremely secure place (e.g., a password manager like 1Password or Bitwarden). Losing this key and your phone could mean you get locked out of your server.
  • Your verification code is…: The first 6-digit code for you to verify the setup is correct.
  • Your emergency scratch codes: These are 5 ‘backup keys’, each for one-time use. Save them in your password manager or print them out and store them safely immediately.

Next, the program will ask you a few questions. You should answer according to the following suggestions for the most secure configuration:

Do you want me to update your "/home/your_user/.google_authenticator" file? (y/n) <strong>y</strong>

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30 seconds, but
it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) <strong>y</strong>

By default, tokens are good for 30 seconds... (y/n) <strong>n</strong>

Do you want to enable rate-limiting for the authentication module? (y/n) <strong>y</strong>

Step 3: Configure SSH to Use 2FA

Now it’s time to ‘teach’ the SSH service that it needs to ask for a 2FA code when someone tries to log in.

1. Configure PAM for SSH:

Use your favorite text editor (e.g., nano) to open the file:

sudo nano /etc/pam.d/sshd

Add the following line to the very top of the file. This ensures the 2FA prompt is triggered first.

auth required pam_google_authenticator.so

2. Configure the SSH Service:

Next, open the main SSH configuration file:

sudo nano /etc/ssh/sshd_config

Find the ChallengeResponseAuthentication and UsePAM lines, and make sure they are set to yes (instead of no or being commented out with a #).

ChallengeResponseAuthentication yes
UsePAM yes
  • ChallengeResponseAuthentication yes: Allows SSH to display challenge-response prompts like “Verification code:”.
  • UsePAM yes: Instructs the SSH daemon to adhere to the authentication rules defined in PAM.

Step 4: Apply the Changes

To apply all the changes, restart the sshd service:

sudo systemctl restart sshd

🛑 CRITICAL WARNING: Do not close your current terminal window yet! Open a new terminal window and try to SSH in again. If you’ve misconfigured something, your old session is your ‘lifeline’ to get back in and fix the error. If you close it, you risk being locked out of your server forever.

Step 5: Experience the 2FA Login

From a new terminal window, try to SSH into the server. The login process will now have an extra step:

$ ssh your_user@your_server_ip
(your_user@your_server_ip) Password: <strong>********</strong>
Verification code: <strong>123456</strong>
Welcome to Ubuntu ...
your_user@your_server:~$

After entering your password, the system will ask for a “Verification code”. Just open your Authenticator app and enter the 6-digit code currently displayed. If successful, congratulations on getting in!

Conclusion

Congratulations! With just a few simple steps, you’ve equipped your server with an incredibly strong layer of ‘armor’. This second layer of protection almost completely neutralizes automated brute-force attacks. Now, even if your password is leaked, malicious actors won’t be able to touch your server.

Consider enabling 2FA as one of the most effective investments in the security of your ‘digital assets’. Security is a journey without a destination, and today, you’ve taken a significant step forward on that path.

Share: