Securing Our Linux Servers with SSH Two-Factor Authentication
In my role as a systems administrator at our company, I recently observed numerous automated login attempts against our Linux servers. Handling sensitive customer data demands robust security measures, so I decided to implement two-factor authentication (2FA) for all SSH access. Below is the scenario that prompted this change and a detailed walkthrough of how I set it up using Google Authenticator.
The Scenario: Why We Needed SSH 2FA
Our production environment runs on Debian 12.5 and Ubuntu 24.04 servers hosting web applications and internal tools. After receiving alerts about repeated failed SSH logins, I knew it was only a matter of time before a breach occurred. To mitigate this risk quickly and effectively, we opted to require a time-based one-time password (TOTP) in addition to the standard SSH password.
Step 1: Install the Google Authenticator PAM Module
I began by installing the PAM module that enables TOTP support on each server:
sudo apt update sudo apt install libpam-google-authenticator -y
This package provides pam_google_authenticator.so
, which integrates with SSH’s PAM stack to enforce TOTP checks.
Step 2: Generate TOTP Secret for Each User
For every user requiring SSH access, I ran:
google-authenticator
The interactive prompt accepted the default answers (y
), generated a secret key and QR code, and printed several emergency scratch codes. I scanned the QR code with Google Authenticator on my phone and securely stored the scratch codes offline.
Step 3: Configure PAM to Require TOTP
I edited the SSH PAM configuration to enforce the new authentication factor. In /etc/pam.d/sshd
, I added:
auth required pam_google_authenticator.so nullok
The nullok
option allows users without a configured authenticator to log in; removing it forces 2FA for all users.
Step 4: Update SSH Daemon Settings
Next, I modified /etc/ssh/sshd_config
to enable challenge-response and PAM:
sudo vim /etc/ssh/sshd_config ChallengeResponseAuthentication yes UsePAM yes PasswordAuthentication yes KbdInteractiveAuthentication yes
Enabling KbdInteractiveAuthentication
ensures compatibility with popular SSH clients like Xshell and Termius.
Step 5: Restart SSH and Verify
To apply the changes, I restarted SSH:
sudo systemctl restart ssh
During my next login attempt, SSH prompted first for the six-digit TOTP code from my Authenticator app, then for my account password. Successful access confirmed the two-factor setup was working.
Conclusion
Implementing SSH two-factor authentication with Google Authenticator significantly strengthened our server security with minimal overhead. By requiring both a password and a time-based code, we greatly reduce the risk of unauthorized access—even if passwords are compromised. I recommend this straightforward approach for any organization running Linux servers exposed to SSH.