How to Set Up Two-Factor Authentication for SSH on Linux
Even with key-based authentication and a hardened configuration, adding two-factor authentication for SSH provides an extra layer of protection that ensures a stolen key or compromised credential alone isn’t enough to gain access to your server. It’s one of the last remaining gaps in a fully hardened SSH setup, and it’s easier to configure than most people expect.
Why Add 2FA on Top of SSH Keys?
SSH key-based authentication is already far stronger than passwords, but it isn’t foolproof — a private key could be copied from a compromised laptop, accidentally committed to a public repository, or extracted from an unencrypted backup. Two-factor authentication means that even if your key is stolen, an attacker still needs a time-based code from your phone to actually log in.
Installing Google Authenticator PAM Module
On Debian or Ubuntu-based systems:
sudo apt update
sudo apt install libpam-google-authenticator -y
Configuring 2FA for Your User Account
Run the setup tool as the user who will log in via SSH:
google-authenticator
This generates a QR code you can scan with an authenticator app (Google Authenticator, Authy, or any TOTP-compatible app), along with a secret key and a set of emergency backup codes — save these backup codes somewhere safe in case you lose access to your authenticator app.
During setup, you’ll be asked several configuration questions:
- Update the .google_authenticator file? – Yes
- Disallow multiple uses of the same code? – Yes (prevents replay attacks)
- Increase time window for codes? – No, unless you have significant clock drift issues
- Enable rate limiting? – Yes (protects against brute-force code guessing)
Enabling PAM Integration
Edit the PAM configuration for SSH:
sudo nano /etc/pam.d/sshd
Add this line:
auth required pam_google_authenticator.so
Configuring SSH to Require Both Key and Code
Edit the SSH daemon configuration:
sudo nano /etc/ssh/sshd_config
Ensure these settings are present:
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
This configuration requires both a valid SSH key and a valid authenticator code — neither alone is sufficient to log in.
Restarting SSH
Apply the changes:
sudo systemctl restart sshd
Testing Before You Log Out
Before closing your current session, open a new terminal window and attempt to SSH in to confirm the setup works correctly. This is critical — if the configuration has an error, you want to discover it while your original session is still open, not after you’ve already been locked out.
Handling Lost Authenticator Access
Keep the backup codes generated during setup in a secure location (a password manager, for instance). If you lose your phone and have no backup codes, you’ll need physical or console access to the server to disable the PAM requirement temporarily.
Final Thoughts
Setting up two-factor authentication for SSH closes one of the last remaining gaps in an otherwise well-hardened server, ensuring that a compromised key alone can’t grant an attacker access. Combined with key-based authentication, Fail2Ban, and general SSH hardening, this creates a genuinely difficult target for anyone attempting unauthorized access to your homelab or server.