Monday, April 6, 2026
LinuxSecurity

How to Setup Two-Factor Authentication For SSH In Linux

16views

Password-only SSH authentication is one of the most common — and most dangerous — security gaps in Linux server management. Attackers armed with credential lists and automated scripts can hammer your SSH port indefinitely. If your password is the only thing standing between them and root access, your environment is one breach away from a serious incident.

Two-factor authentication (2FA) via Google Authenticator eliminates that single point of failure. Even if an attacker gets your password, they still need the time-based one-time code from your phone — a six-digit number that expires every 30 seconds. No code, no access.

In this guide, we walk through every step needed to configure SSH 2FA on both Debian-based systems (Ubuntu, Linux Mint) and RHEL-based systems (Rocky Linux, AlmaLinux, Fedora, CentOS Stream) — no third-party services, no subscriptions, no reboots required.

Why Restricting SSH to Password-Only Login Is a Risk

Before jumping into the configuration, it is worth understanding what is actually at stake when SSH runs without 2FA enabled:

  • Brute-Force Exposure — Any internet-facing SSH port is constantly targeted by automated credential-stuffing tools that run 24/7.
  • Credential Leak Risk — Passwords get reused, phished, or exposed in data breaches. One leaked credential can compromise your entire server.
  • Lateral Movement — Once an attacker gains SSH access, they have a foothold for privilege escalation and moving deeper into your network.
  • Compliance Gaps — Many frameworks (HIPAA, PCI-DSS, ISO 27001) explicitly require multi-factor authentication for remote access to sensitive systems.
  • Insider Threat Reduction — 2FA limits the blast radius if an employee account is compromised or misused, since physical device access is also required.
  • Audit Trail Improvement — Enforcing 2FA strengthens access controls and supports the principle of least-privilege access logging.

Key Highlights

What This Setup Does

  • Adds a time-based one-time password (TOTP) layer on top of your SSH password login
  • Works on all major Linux distributions — both Debian-based and RHEL-based systems
  • Tokens refresh every 30 seconds, rendering intercepted codes useless almost instantly
  • Applies per-user — you can roll this out selectively without affecting all accounts at once
  • Compatible with Android, iOS, and desktop TOTP apps (no hardware token required)
  • No reboot needed — a single service restart applies the changes immediately
  • Emergency scratch codes provide offline backup access if your phone is unavailable

Step-by-Step: Configuring SSH Two-Factor Authentication

Step 1 — Install the Google Authenticator PAM Module

Open your Linux server and install the required PAM library. The package name differs by distribution family.

On Ubuntu / Debian / Linux Mint:

On RHEL / Rocky Linux / AlmaLinux / Fedora (EPEL required):

Step 2 — Generate Your Secret Key

Run the setup command as the user you want to protect — not as root, unless you are specifically securing the root account:

You will be walked through a short series of interactive prompts. Answer y (yes) to each question. When complete, you will receive:

  • A secret key — this links your server to your authenticator app
  • A set of emergency scratch codes — single-use backup codes if your phone is unavailable
  • A QR code URL — you can paste this into a browser to scan it with your phone

Example output (your keys will be unique):

Step 3 — Configure PAM to Require 2FA for SSH

Open the SSH PAM configuration file:

Add the following line at the top of the file, before any other auth lines:

SELinux Users: If SELinux is enforcing on your system (common on RHEL/Rocky), move the authenticator file to your ~/.ssh/ directory and update the PAM line with the full path:

Step 4 — Update the SSH Daemon Configuration

Open the SSH server configuration file:

Ensure the following two settings are present and enabled:

For maximum security — requiring both an SSH key and a 2FA code — add this optional line:

Save the file, then restart the SSH service to apply your changes:

Step 5 — Link Your Authenticator App

On your smartphone, open Google Authenticator (or any TOTP-compatible app such as Authy, KeePassXC, or the Firefox Authenticator add-on). Tap + and choose Enter a setup key. Type in the secret key generated in Step 2, and give the account a recognizable name.

Your app will now display a rolling 6-digit verification code that refreshes every 30 seconds. The next time you connect via SSH, you will be prompted for this code before your password is accepted:

Verifying the Policy is Applied

After configuring 2FA, confirm it is working before assuming everything is fine. Here are three reliable verification methods:

  • Direct SSH Test — Open a new terminal session (do not close your current one) and SSH into your server. You should be prompted for a verification code before your password.
  • gpresult Equivalent — On the server, check /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL) for entries confirming PAM google_authenticator is being invoked.
  • Refused Code Test — Deliberately enter a wrong verification code. The login should fail immediately without proceeding to the password prompt.

Conclusion

Enabling two-factor authentication for SSH is one of the highest-value security improvements you can make to a Linux server — and it requires no special hardware, no paid services, and no significant downtime. By installing the Google Authenticator PAM module, generating a per-user secret key, and making two small changes to your SSH and PAM configuration files, you have effectively made brute-force and credential-stuffing attacks against your SSH port close to useless.

The Google Authenticator PAM module, combined with proper SSH daemon configuration, means that even a fully compromised password gives an attacker nothing. That rolling 30-second code is the second factor that keeps your server protected even when passwords fail.

Leave a Response

Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

Powered By
Best Wordpress Adblock Detecting Plugin | CHP Adblock