By default, SSH relies on passwords for authentication, though most security guidelines recommend switching to SSH keys for stronger protection. However, despite being more secure, SSH keys still represent only a single factor of authentication. The SSH session involves your computer’s terminal sending data through an encrypted tunnel to the remote server.
Just as hackers can guess passwords, they can also steal SSH keys, and with that single credential, they can potentially gain unauthorized access to your remote systems.
Prerequisites
Linux Machine (For this demonstration, we will use Raspberry Pi OS, which is based on Debian.)
A smartphone or tablet with any OATH-TOTP app like Google Authenticator(iOS/Android), Microsoft Authenticator(iOS/Android),etc
Step 1 — Installing Google’s PAM
In this step, we will install and configure Google’s PAM module which stands for Pluggable Authentication Module. It is an authentication framework used on Linux systems to verify users’ identities.
Google has developed a PAM module that generates time-based one-time passwords (TOTP), fully compatible with any OATH-TOTP app, such as Google Authenticator(iOS/Android), Microsoft Authenticator(iOS/Android),etc . Before proceeding with the installation, make sure your system is up to date. Use the following commands based on your Linux distribution:
For Ubuntu/Debian:
sudo apt-get update
Next, install the PAM:
sudo apt-get install libpam-google-authenticator
For RHEL/CentOS 8/Fedora (using dnf
):
sudo dnf update -y
Next, install the PAM:
sudo dnf install google-authenticator qrencode-libs -y
For RHEL/CentOS 7 (using yum
):
sudo yum update -y
Next, install the PAM:
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo yum install google-authenticator
Step 2 — Configure Google Authenticator to generate OTP codes
Execute the following command to start the configuration process:
google-authenticator
After you run the command, it will prompt a series of questions. For most, simply answer “y” (yes), unless you require a different setting.
This PAM supports both time-based and counter-based tokens. Counter-based tokens increment with each use, while time-based tokens change after a set interval. Since apps like Google Authenticator expect time-based tokens, select “y” for yes.
Afterward, a lot of output will appear, including a large QR code. Use your authenticator app to scan the QR code or manually enter the secret key. If the QR code is too large to scan, you can use the URL above the QR code to view a smaller version.
Once added, you’ll see a six-digit code in your app that refreshes every 30 seconds. Enter that code in the terminal and press Enter.
Note: Be sure to save the secret key, verification code, and recovery codes in a secure location, such as a password manager. The recovery codes are your only way to regain access if you lose access to your TOTP app.
The remaining questions inform the PAM on how to function. Simply answer “yes” (y), unless you require a different setting.
Step 3 — Configuring OpenSSH for MFA
When making ssh changes, don’t close the your original SSH session.Instead, open a second session to test, this will help in preventing accidental lockout.
Start by backing up the sshd configuration file, so that in case anything goes wrong , you can revert back to the original config.
sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
Now open the sshd configuration file using nano or any edior of your choice.
sudo nano /etc/pam.d/sshd
Append the following line to the end of the file,save and close the file.
auth required pam_google_authenticator.so nullok
auth required pam_permit.so
Next, we will configure SSH to support this type of authentication.
Similarly like what we did for /etc/pam.d/sshd, create a backup of the file:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
Now, open the SSH configuration file for editing
sudo nano /etc/ssh/sshd_config
Locate the ChallengeResponseAuthentication
option and set its value to "yes." If you're using OpenSSH 8.7p1 or later , then look for KbdInteractiveAuthentication
instead and set that to "yes." as ChallengeResponseAuthentication
option is deprecated in OpenSSH 8.7p1 and above.
In OpenSSH 8.7p1 and above, ChallengeResponseAuthentication has been replaced with KbdInteractiveAuthentication.
In OpenSSH < 8.7p1
Save and close the file, then restart SSH to reload the configuration file
sudo systemctl restart sshd.service
Step 4— Enabling SSH Support for MFA
Warning: If you haven’t set up SSH keys, skip Step — 4. Enabling the following setting will block your access to your linux machine through SSH, as it requires public key authentication.
MFA won’t function if you’re using an SSH key. To enable SSH support for MFA, reopen the sshd
configuration file:
sudo nano /etc/ssh/sshd_config
Add the following line at the end of the file. This specifies the required authentication methods for SSH. We indicate that users must provide an SSH key and either a password or a verification code (or all three):
AuthenticationMethods publickey,password publickey,keyboard-interactive
This setup ensures that:
publickey,password: The user must provide their SSH key followed by their password.
publickey,keyboard-interactive: Alternatively, the user must provide their SSH key followed by MFA (such as Google Authenticator).
Moment of Truth: Logging In with MFA
Now, attempt to log into the server again using a different terminal session or window. This time, SSH should prompt you for your verification code. Enter the code to complete the login.
In this tutorial, you implemented 2FA across two devices (computer and phone) for your server. This approach significantly improves security by making it much more difficult for unauthorized users to gain SSH access.