SSH 2FA Setup: Security with Google Authenticator
Set up two-factor authentication (2FA) for SSH access. Google Authenticator PAM module, TOTP setup for SSH, backup codes, testing, and troubleshooting guide.
Table of Contents
SSH 2FA Setup: Security with Google Authenticator
While using SSH keys improves security, two-factor authentication (2FA) provides an extra security layer. Even if someone obtains your SSH key, they cannot access the system without the 2FA code. This guide walks you through setting up TOTP-based 2FA for SSH using the Google Authenticator PAM module.
Why is 2FA Important?
- Stolen key protection: Even if SSH key is stolen, 2FA code is still required
- Brute-force resistance: Password + 2FA combination is much stronger
- Compliance: Standards like PCI-DSS and HIPAA require 2FA
- Easy setup: Can be activated in minutes
Requirements
- Linux server (Ubuntu/Debian/CentOS)
- Smartphone (Google Authenticator, Authy, or similar app)
- Existing SSH access
Don't close your existing SSH connection during 2FA setup. Test from a new terminal after each step. Incorrect configuration can completely block server access.
Installing Google Authenticator PAM Module
# Ubuntu/Debian
sudo apt update
sudo apt install libpam-google-authenticator -y
# CentOS/AlmaLinux
sudo dnf install epel-release -y
sudo dnf install google-authenticator -y
TOTP Setup
# Run as the user you want to enable 2FA for
google-authenticator
When the command runs, you'll be asked:
Do you want authentication tokens to be time-based (y/n) y
At this point, a QR code and secret key will be displayed. Scan the QR code with the Google Authenticator app.
Do you want me to update your "/home/user/.google_authenticator" file? (y/n) y
Do you want to disallow multiple uses of the same authentication token? (y/n) y
Do you want to increase the window size? (y/n) n
Do you want to enable rate-limiting? (y/n) y
Saving Backup Codes
During setup, 5 backup codes are displayed. Store these in a safe place:
Your emergency scratch codes are:
12345678
87654321
11223344
44332211
99887766
Store backup codes in a safe place (password manager, paper, etc.). If you lose your phone, these codes will be your only way in.
PAM Configuration
# Edit SSH PAM configuration
sudo nano /etc/pam.d/sshd
# Add at the beginning of /etc/pam.d/sshd:
auth required pam_google_authenticator.so
Adding the nullok option allows users without 2FA set up to log in with password only. Useful during transition:
auth required pam_google_authenticator.so nullok
SSH Configuration
sudo nano /etc/ssh/sshd_config
# Enable keyboard-interactive authentication
ChallengeResponseAuthentication yes
# Set authentication methods
# Option 1: 2FA only (password + TOTP)
AuthenticationMethods keyboard-interactive
# Option 2: SSH key OR 2FA
# AuthenticationMethods publickey keyboard-interactive
# Option 3: SSH key AND 2FA (most secure)
AuthenticationMethods publickey,keyboard-interactive
# UsePAM must be enabled
UsePAM yes
# Restart SSH service
sudo systemctl restart sshd
SSH Key + 2FA Combination (Recommended)
Most secure configuration: requires SSH key AND 2FA code.
sudo nano /etc/ssh/sshd_config
# SSH key + 2FA required
AuthenticationMethods publickey,keyboard-interactive
PasswordAuthentication no
ChallengeResponseAuthentication yes
UsePAM yes
# PAM configuration
sudo nano /etc/pam.d/sshd
# Comment out password authentication:
# @include common-auth
# Add 2FA
auth required pam_google_authenticator.so
Testing
# Open a new terminal and try to connect
ssh user@server_ip
# Expected output:
# Verification code: (enter code from Google Authenticator)
# Authenticated with partial success.
# (in SSH key + 2FA mode)
Troubleshooting
2FA Code Not Accepted
# Check server time
date
timedatectl
# NTP synchronization
sudo apt install ntp -y
sudo systemctl restart ntp
# Check timezone
timedatectl list-timezones | grep UTC
sudo timedatectl set-timezone UTC
Recovery When Locked Out
# Connect via console access
# Check Google Authenticator file
cat ~/.google_authenticator
# Temporarily disable 2FA
# Comment out pam_google_authenticator line in /etc/pam.d/sshd
sudo nano /etc/pam.d/sshd
# Add # before: auth required pam_google_authenticator.so
sudo systemctl restart sshd
Exempting Specific Users from 2FA
sudo nano /etc/pam.d/sshd
# Exempt specific groups
auth [success=1 default=ignore] pam_succeed_if.so user ingroup notp
auth required pam_google_authenticator.so
# Create notp group and add user
sudo groupadd notp
sudo usermod -aG notp deploy_user
Multi-Server Management
# Ansible playbook for bulk installation
- name: Install Google Authenticator
hosts: all
tasks:
- name: Install package
apt:
name: libpam-google-authenticator
state: present
- name: PAM configuration
lineinfile:
path: /etc/pam.d/sshd
line: 'auth required pam_google_authenticator.so'
insertbefore: BOF
Apps like Authy or 1Password offer cloud backup and multi-device support compared to Google Authenticator. Consider these alternatives for enterprise environments.
Conclusion
Setting up 2FA for SSH significantly improves server security. With the Google Authenticator PAM module, you can activate TOTP-based 2FA in minutes. The SSH key + 2FA combination forms one of the strongest authentication methods available.
Related Articles
Malware & Rootkit Scanning: rkhunter and ClamAV Guide
Protect your Linux server against malware and rootkits. rkhunter and ClamAV installation, scan configuration, result interpretation, scheduled scans, and incident response guide.
Fail2Ban Configuration: SSH Brute-Force Protection Guide
Protect your server against SSH brute-force attacks with Fail2Ban. Installation, jail.local configuration, Nginx/Apache jails, IP whitelisting, ban monitoring, and email alerts.
WireGuard VPN Server Setup: Step-by-Step Guide
Set up a WireGuard VPN server: key generation, server and client configuration, IP forwarding, firewall rules, and Windows/Linux/Android client setup guide.