Skip to main content
To add two-factor authentication to SSH, install libpam-google-authenticator, run google-authenticator as your user and scan the QR code, add auth required pam_google_authenticator.so to /etc/pam.d/sshd, then set KbdInteractiveAuthentication yes and AuthenticationMethods publickey,keyboard-interactive in your SSH config. After a restart, each login needs your SSH key and a 6-digit code. Two-factor authentication (2FA) means you need two things to log in: something you have (your SSH key) and a time-based one-time code (TOTP) from an app such as Google Authenticator, Microsoft Authenticator or any other TOTP app.

Before you start

  • Log in with an SSH key as a sudo user. Root users can leave out sudo.
  • Check the server clock is synchronised, because codes depend on the time: timedatectl should show System clock synchronized: yes. See set the timezone and time sync.
  • Keep your current SSH session open until you have tested a new login.
  • If you get locked out, use the VNC console. It logs in on the local console, which this setup does not change. On a dedicated server, open a ticket if you need console access.
A mistake in /etc/pam.d/sshd or the SSH config can block every SSH login. Make each change, test it from a second terminal, and only then close your first session.

How to set up SSH 2FA

1

Install the PAM module

2

Create your secret as your normal user

Run this as the user who will log in, without sudo:
-t makes time-based codes, -d stops a code being used twice, -r 3 -R 30 allows 3 logins every 30 seconds and -w 3 accepts the previous, current and next code. Scan the QR code with your app (or type in the secret key it prints if no QR code appears) and enter the code the app shows. The tool saves your secret in ~/.google_authenticator.
3

Save the emergency codes

The tool prints five emergency scratch codes. Each works once if you lose your phone. Store them in your password manager, not on the server.
4

Add the module to PAM

Comment out the password line near the top and add the module below it:
Commenting out the password line means PAM asks only for the code. Your SSH key is checked by SSH itself.
5

Tell SSH to ask for key and code

Older guides use ChallengeResponseAuthentication yes. That is the deprecated name for KbdInteractiveAuthentication and does the same thing.
6

Test the config and restart SSH

How to check it worked

Open a new terminal and connect:
After your key is accepted, SSH asks for Verification code:. Type the 6-digit code from your app. If you are let in, 2FA works and you can close the old session. Check what SSH now enforces with:

How to roll out 2FA when several users share the server

Add nullok to the PAM line (auth required pam_google_authenticator.so nullok). Users who have not yet run google-authenticator can then log in without a code. Remove nullok once every user has set it up, or those users can skip 2FA.

How to turn 2FA off again

Remove /etc/ssh/sshd_config.d/20-2fa.conf, restore the original line in /etc/pam.d/sshd, run sudo sshd -t and restart SSH.

Frequently asked questions

My code is always rejected. What is wrong?

Usually the server clock is wrong. Run timedatectl and enable time sync. Also check you scanned the code for the right user: the secret is stored per user in ~/.google_authenticator.

Does SSH 2FA work with SFTP clients like FileZilla or WinSCP?

Yes, if the client supports keyboard-interactive login. It shows a prompt for the code. Automated scripts that cannot answer a prompt will stop working, so give them a separate user that is excluded with a Match User block.

What if I lose my phone?

Log in with one of the emergency scratch codes instead of a TOTP code, then run google-authenticator again to create a new secret. Without codes, use the VNC console.

On AlmaLinux the code prompt never appears. Why?

Check SELinux denials with sudo ausearch -m AVC -ts recent. See use SELinux on AlmaLinux and Rocky to read and fix them.

VPS and dedicated server guides

Every guide in this section.

Create and use SSH keys

The first factor for 2FA.

Disable root login

Stop direct root logins.

Set up Fail2Ban

Block brute-force attempts.

Security checklist

Harden the rest of your server.

Checked against the official google-authenticator-libpam project, Ubuntu SSH 2FA tutorial and sshd_config manual on 4 November 2026; package installation, the google-authenticator options and the SSH configuration (sshd -t, sshd -T) were tested on Ubuntu 24.04 LTS. Commands can differ on other distributions or releases.

Need Extra Help?

If you encounter any issues, our support team is ready to assist:

Save on Your Hosting

Ready to upgrade your hosting? Use code KB20 at checkout for 20% off your first order!

Last Updated: November 2026