In today's threat landscape, password-only authentication for SSH access is simply not enough. This guide will walk you through implementing two-factor authentication (2FA) for SSH using Google Authenticator on an Ubuntu VM, adding an extra layer of security to your server.
Why SSH 2FA Matters
Two-factor authentication significantly reduces the risk of unauthorized access, even if your password is compromised. By requiring both something you know (password) and something you have (TOTP code from your phone), you create a much stronger security posture.
Prerequisites
Before we begin, ensure you have:
- Ubuntu VM (20.04 or later recommended)
- SSH access with sudo privileges
- SSH server installed and running
- A smartphone with Google Authenticator or Authy app
Setting Up Your Ubuntu VM
If you're starting from scratch, download the Ubuntu Server ISO:
- Download Link: Ubuntu 24.04.2 Server
- Use the live server edition as it comes with the SSH daemon pre-installed
Important: Verify that SSH service is active before proceeding:
sudo systemctl status ssh
You should see active (running) in the output.
Implementation Steps
Step 1: Install Google Authenticator PAM Module
The Pluggable Authentication Module (PAM) for Google Authenticator allows integration with the system authentication stack.
sudo apt update
sudo apt install libpam-google-authenticator
Step 2: Configure Google Authenticator for Your User
Important: Install Google Authenticator on your smartphone before this step. It's available on both iOS and Android app stores.
Run the configuration wizard:
google-authenticator
You'll be presented with several prompts:
- "Do you want authentication tokens to be time-based?" → Answer yes
- A QR code will appear in your terminal
- Scan the QR code using your authenticator app
- Save the emergency scratch codes displayed (store them securely offline)
- "Do you want me to update your ~/.google_authenticator file?" → Answer yes
- "Do you want to disallow multiple uses of the same authentication token?" → Answer yes
- "Do you want to increase the time window?" → Answer no (unless you have clock sync issues)
- "Do you want to enable rate-limiting?" → Answer yes
Step 3: Configure PAM for SSH
Edit the PAM configuration file:
sudo nano /etc/pam.d/sshd
Add this line near the top of the file (before other auth directives):
auth required pam_google_authenticator.so
Optional: To make 2FA optional and fall back to password-only if not configured:
auth required pam_google_authenticator.so nullok
Save and exit (Ctrl+X, then Y, then Enter).
Step 4: Configure SSH Daemon
Edit the SSH daemon configuration:
sudo nano /etc/ssh/sshd_config
Locate and modify the following lines (or add them if they don't exist):
For password authentication with 2FA:
ChallengeResponseAuthentication yes
UsePAM yes
AuthenticationMethods password,keyboard-interactive
For SSH key authentication with 2FA:
ChallengeResponseAuthentication yes
UsePAM yes
AuthenticationMethods publickey,keyboard-interactive
Pro Tip: Using public key + 2FA provides the strongest security posture.
Save and exit.
Step 5: Restart SSH Service
Apply the configuration changes:
sudo systemctl restart ssh
Step 6: Test the Setup
Critical: Before closing your current SSH session, open a new terminal and test the connection:
ssh username@your-server-ip
You should now be prompted for:
- Your account password (or key passphrase)
- Your TOTP verification code from Google Authenticator
If everything works correctly, you'll see something like:
Password:
Verification code:
Troubleshooting
Can't Login After Setup?
- Keep your original SSH session open while testing
- Check SSH logs:
sudo journalctl -u ssh -n 50 - Verify PAM configuration:
sudo nano /etc/pam.d/sshd - Ensure time synchronization:
timedatectl status
Emergency Access
If you get locked out:
- Use the emergency scratch codes you saved during setup
- Access via console (if VM) or physical access
- Each scratch code can only be used once
Clock Sync Issues
TOTP requires synchronized clocks. If codes aren't working:
sudo timedatectl set-ntp true
Quick Reference
| Step | Action | Command |
|---|---|---|
| 1 | Install PAM module | sudo apt install libpam-google-authenticator |
| 2 | Configure per user | google-authenticator |
| 3 | Update PAM | Edit /etc/pam.d/sshd
|
| 4 | Update SSH config | Edit /etc/ssh/sshd_config
|
| 5 | Restart SSH | sudo systemctl restart ssh |
| 6 | Test connection | Open new SSH session |
Security Best Practices
- Test before closing your session: Always verify the setup works before disconnecting
- Store emergency codes securely: Keep them offline in a safe location
- Enable 2FA for all admin users: Apply this to every account with sudo access
-
Regular backups: Back up
~/.google_authenticatorfile securely -
Monitor logs: Regularly check
/var/log/auth.logfor suspicious activity - Consider fail2ban: Combine with fail2ban for additional brute-force protection
Conclusion
You've successfully implemented SSH two-factor authentication on your Ubuntu server! This significantly hardens your server security by requiring both password and time-based codes for access.
Remember to:
- Keep your emergency codes safe
- Enable 2FA for all users with SSH access
- Regularly audit your authentication logs
Have questions or run into issues? Drop a comment below!
Found this helpful? Follow me for more cybersecurity and Linux administration guides!
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.