# How to Secure SSH on Any Linux Server using PAM and Google Authenticator

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](https://apps.apple.com/us/app/google-authenticator/id388497605)/[Android](https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en_IN)), Microsoft Authenticator([iOS](https://apps.apple.com/us/app/microsoft-authenticator/id983156458)/[Android](https://play.google.com/store/apps/details?id=com.azure.authenticator&hl=en_IN)),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](https://apps.apple.com/us/app/google-authenticator/id388497605)/[Android](https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en_IN)), Microsoft Authenticator([iOS](https://apps.apple.com/us/app/microsoft-authenticator/id983156458)/[Android](https://play.google.com/store/apps/details?id=com.azure.authenticator&hl=en_IN)),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**:

```bash
sudo apt-get update
```

Next, install the PAM:

```bash
sudo apt-get install libpam-google-authenticator
```

**For RHEL/CentOS 8/Fedora (using** `dnf`**)**:

```bash
sudo dnf update -y
```

Next, install the PAM:

```bash
sudo dnf install google-authenticator qrencode-libs -y
```

**For RHEL/CentOS 7 (using** `yum`**)**:

```bash
sudo yum update -y
```

Next, install the PAM:

```bash
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:

```bash
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.

![](https://cdn-images-1.medium.com/max/1600/1*DycJSBGZ4ARL2DN1oKurhA.png align="left")

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.

![](https://cdn-images-1.medium.com/max/1600/1*zO3KY2hE52trQDGrSwTFww.png align="left")

scan the QR code from your authenticator app

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.

![](https://cdn-images-1.medium.com/max/1600/1*JR3PWfiGwfF4WhkGbONEXQ.png align="left")

> **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.

![](https://cdn-images-1.medium.com/max/1600/1*0a0iBYau8pd751SpMFwHPQ.png align="left")

### 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.

```bash
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.

```bash
sudo nano /etc/pam.d/sshd
```

Append the following line to the end of the file,save and close the file.

```bash
auth required pam_google_authenticator.so nullok
auth required pam_permit.so
```

![](https://cdn-images-1.medium.com/max/1600/1*Cdi7bBQxSdqAvFlPROX21A.png align="left")

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:

```bash
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
```

Now, open the SSH configuration file for editing

```bash
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.

![](https://cdn-images-1.medium.com/max/1600/1*M8GsiaAmxtQP0UWjZsUzdw.png align="left")

In OpenSSH 8.7p1 and above, ChallengeResponseAuthentication has been replaced with KbdInteractiveAuthentication.

![](https://cdn-images-1.medium.com/max/1600/1*ThjXOUV7wx2B8IrukrQ20Q.png align="left")

In OpenSSH &lt; 8.7p1

Save and close the file, then restart SSH to reload the configuration file

```bash
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:

```bash
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):

```bash
AuthenticationMethods publickey,password publickey,keyboard-interactive
```

![](https://cdn-images-1.medium.com/max/1600/1*fri1DR_AGb-1XcGSxlNi5Q.png align="left")

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.

![](https://cdn-images-1.medium.com/max/1600/1*LwoJAgEduBTltGjXPLif3Q.png align="left")

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.
