How to protect the server from hacking: Setting up 2FA via Google Authenticator PAM

Giteqa

Greetings, friends!

In modern realities, classical password protection or SSH key authorization is no longer enough if an administrator's account becomes compromised. Implementing Two-Factor Authentication (2FA) based on Time-based One-Time Passwords (TOTP) creates an additional line of defense: even if an attacker intercepts your private key or password, they will not be able to log in to the server without physical access to your code generator.

As an example, Steam Guard immediately comes to mind, thanks to which no one was able to hack Gabe Newell's account even though he shared his account email and password with the entire world. Thus, enabling two-factor authentication provides maximum security for your account.

In this step-by-step guide, we will configure 2FA for SSH connections using the Google Authenticator PAM module for Ubuntu / Debian and CentOS / AlmaLinux operating systems. By the way, many websites have started integrating Google Authenticator for login to prevent users from losing their accounts.

Key Takeaways: Main Conclusions

  • 2FA protects against key leaks and brute-force attacks: Even if a private SSH key is compromised, access to the server remains locked without the 6-digit temporary TOTP code.

  • Flexible authorization policy: The PAM module allows you to configure both a "Password + 2FA" pair and a highly secure "SSH Key + 2FA" combination.

  • Importance of backup codes: Before restarting the SSH daemon, always save your emergency recovery codes to avoid losing access to your infrastructure if you lose your smartphone.

TOTP 2FA Architecture in Linux

Two-factor authentication in Linux is implemented via the PAM (Pluggable Authentication Modules) subsystem. When a client initiates a connection via sshd, the PAM subsystem intercepts the request and queries the pam_google_authenticator.so module.

The module reads the secret key from the user's home directory (~/.google_authenticator), compares the code generated by your smartphone with the server's current time, and decides whether to grant access.

Is Two-Factor Authentication Really Reliable?

Yes. Personally, I have repeatedly been targeted by scammers related to Steam accounts, and I even entered my login and password on scam sites, but I never entered the code from Steam Guard itself. It is thanks to 2FA that I still own my account, and I recommend everyone use two-factor authentication.

Step-by-Step Setup Guide

Step 1: Installing the PAM Module Log in to the server under the user for whom 2FA is being configured (with sudo privileges).

For Ubuntu / Debian:

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

For RHEL / AlmaLinux / Rocky Linux:

Bash
sudo dnf install epel-release -y
sudo dnf install google-authenticator -y

Step 2: Generating the Secret Key and QR Code Run the generation command on behalf of the target user:

Bash
google-authenticator

The setup wizard will ask you several questions. Recommended answers:

  • Do you want authentication tokens to be time-based? (y) — activates time-based code generation (TOTP). It is correct to select yes because with time-based generation, the code will be random every time.

  • A large QR code and secret key will appear. Scan the QR code using your 2FA app (Google Authenticator, Bitwarden, 2FA LassPass, Aegis).

  • MUST-DO: Copy and save the emergency recovery codes in a safe place.

  • Do you want me to update your "~/.google_authenticator" file? (y) — saves settings to the profile.

  • Disallow multiple uses of the same authentication token? (y) — protects against Replay Attacks.

  • Increase window size? (n) — leaves a 30-second validity window (select y if clocks on the server and smartphone frequently desynchronize).

  • Enable rate-limiting? (y) — protects against brute-force (limits to 3 attempts every 30 seconds).

Step 3: Configuring the PAM Subsystem for SSH Edit the SSH service configuration file in PAM:

Bash
sudo nano /etc/pam.d/sshd

Add the following line to the end of the file:

Plaintext
auth required pam_google_authenticator.so nullok

Important: The nullok parameter allows users who have not yet configured google-authenticator to log in using a standard password or key. Once all administrators have configured 2FA, remove nullok to make 2FA strictly mandatory for everyone.

Step 4: OpenSSH Daemon Configuration (sshd_config) Now you need to instruct the SSH daemon to request interactive two-factor code input.

Edit the /etc/ssh/sshd_config file:

Bash
sudo nano /etc/ssh/sshd_config

Find and set the following directive values:

Plaintext
KbdInteractiveAuthentication yes
UsePAM yes

Scenario A: SSH Keys + 2FA Authorization (Recommended Standard) If you want the server to prompt for an SSH key followed by a TOTP code (without entering a system password), add to the end of the file:

Plaintext
AuthenticationMethods publickey,keyboard-interactive

Restart the SSH service to apply settings:

Bash
# For Ubuntu / Debian
sudo systemctl restart ssh

# For AlmaLinux / Rocky Linux / RHEL
sudo systemctl restart sshd

Access Verification Checklist (Important!)

DO NOT CLOSE your current SSH session. Open a new terminal window and test the connection:

Bash
ssh -i ~/.ssh/id_rsa user@your_server_ip

You should see the prompt:

Plaintext
Authenticated with partial success.
Verification code:

Enter the 6-digit code from your mobile app. Upon successful entry, you will enter the server console.

REMEMBER: You may only disconnect the terminal after a successful check; otherwise, you risk losing server access for this user and having to contact a system administrator or internet provider for help.

FAQ: Frequently Asked Questions

  • What should I do if I lose my phone with Google Authenticator? Use one of your saved single-use emergency recovery codes instead of the 6-digit temporary code. If you have access to the root console (via MivoCloud's VNC/IPMI panel), you can temporarily disable 2FA for the user by deleting the ~/.google_authenticator file.

  • Why do codes desynchronize and the server output "Invalid code"? TOTP relies on precise system time. Ensure the chrony or systemd-timesyncd time synchronization service is enabled and working on the server:

    Bash
    sudo timedatectl status
    
  • Can 2FA be configured for the root user? Yes, by running google-authenticator directly under the root account. However, from a security standpoint, it is recommended to completely disable direct root login (PermitRootLogin no) and use authorization via a standard user with sudo.

Conclusion

Configuring two-factor authentication is one of the most effective and affordable ways to protect your server infrastructure from unauthorized access. By spending just 10 minutes integrating the Google Authenticator PAM module, you minimize the risk of compromising your services.

However, network security requires an integrated approach. High-level SSH protection must be supported by a reliable hardware base, DDoS protection, and an isolated network.

If you are looking for a fault-tolerant platform to deploy critical projects, consider NVMe VPS and Dedicated Servers from MivoCloud. We offer pure KVM virtualization with hardware resource isolation, instant snapshots for safe system configuration, and high-speed connectivity.


Article Author: Anatolie Cohaniuc