Skip to content

Configure Mideye MFA for Linux SSH & sudo via PAM RADIUS

This guide covers how to configure Linux SSH authentication to use Mideye Server for multi-factor authentication via the PAM RADIUS module (pam_radius_auth). In this setup, Mideye handles both password validation and MFA via a single RADIUS request — the user's password is forwarded to Mideye, which validates it against AD/LDAP/local database and triggers the configured MFA factor. Configurations where the password is validated separately (e.g. locally via pam_unix or SSSD) before RADIUS are not covered here.

| Component | Details | |---|---| | PAM module | pam_radius_auth (FreeRADIUS pam_radius) | | Linux distributions | RHEL / CentOS / Rocky Linux / AlmaLinux (yum/dnf), Debian / Ubuntu (apt) | | Mideye Server | 5.x / 6.x |

  • A running Mideye Server with RADIUS enabled (default UDP port 1812)
  • The Linux server must be added as a RADIUS client in Mideye Server
  • Root or sudo access on the Linux server
  • Network connectivity from the Linux server to Mideye Server on UDP port 1812
  • User accounts must exist in both the Linux server and the Mideye user repository (Active Directory, LDAP, or local database)

RHEL / CentOS / Rocky Linux / AlmaLinux

Terminal window
dnf -y install epel-release
dnf -y install pam_radius

Debian / Ubuntu

Terminal window
apt-get install libpam-radius-auth

For more information on the PAM RADIUS module, refer to the FreeRADIUS pam_radius GitHub repository and the USAGE documentation.

The configuration file location depends on the distribution:

| Distribution | Config file | |---|---| | RHEL / CentOS / Rocky Linux / AlmaLinux | /etc/pam_radius.conf | | Debian / Ubuntu | /etc/pam_radius_auth.conf |

Edit the file for your distribution and replace the example values with your actual Mideye Server IP address and shared secret:

# server[:port] shared_secret timeout (s)
192.0.2.10 your-shared-secret 35

| Setting | Value | |---|---| | Server address | IP address of the Mideye Server | | Shared secret | Must match the RADIUS client configuration in Mideye Server | | Timeout | 35 seconds — required for MFA flows |

For full configuration options, see the pam_radius_auth.conf sample.

Save the changes.

Edit /etc/pam.d/sshd and add the RADIUS authentication line at the top of the auth section. The client_id parameter sets the NAS-Identifier sent to Mideye Server — it must match the NAS-ID configured in the Mideye RADIUS client.

The exact placement and surrounding lines differ by distribution.

RHEL / CentOS / Rocky Linux / AlmaLinux

Add the line after pam_sepermit.so:

Terminal window
#%PAM-1.0
auth required pam_sepermit.so
auth sufficient pam_radius_auth.so conf=/etc/pam_radius.conf client_id=LinuxPAM retry=1
auth substack password-auth
auth include postlogin

Debian / Ubuntu

Add the line at the top of /etc/pam.d/sshd, before @include common-auth:

Terminal window
auth sufficient pam_radius_auth.so conf=/etc/pam_radius_auth.conf client_id=LinuxPAM retry=1
# Standard Un*x authentication.
@include common-auth

For more on client_id and other parameters, see the pam_radius USAGE documentation.

Save the changes.

4. Enable keyboard-interactive authentication in SSH

Section titled “4. Enable keyboard-interactive authentication in SSH”

Edit /etc/ssh/sshd_config. The correct setting depends on your OpenSSH version:

OpenSSH 9.0 and later

Terminal window
KbdInteractiveAuthentication yes

OpenSSH 8.x and earlier

Terminal window
ChallengeResponseAuthentication yes

To check your OpenSSH version:

Terminal window
ssh -V

If the line exists with no, change it to yes. If it is commented out, uncomment and set it to yes.

Also verify that UsePAM yes is present and uncommented — this is required for the PAM stack to be invoked on login.

Save the changes.

RHEL / CentOS / Rocky Linux / AlmaLinux

Terminal window
systemctl restart sshd

Debian / Ubuntu

Terminal window
systemctl restart ssh

User accounts must exist on the Linux server. Create a local account:

Terminal window
sudo useradd -m <username>

-m creates the home directory. The account has no local password — all authentication goes through RADIUS.

If the Linux server is already joined to Active Directory (via realmd + SSSD), steps 1–5 are identical. The only difference is step 6 — domain users are provided by SSSD and do not need local accounts.

Skip useradd for domain users. Instead, verify the user is resolvable on the Linux server:

Terminal window
id <username>

If the user is not found, SSSD is likely not running or the user does not exist in Active Directory:

Terminal window
systemctl status sssd

| Symptom | Check | |---|---| | SSH times out before OTP entry | Verify timeout in the RADIUS config file (/etc/pam_radius.conf on RHEL, /etc/pam_radius_auth.conf on Debian/Ubuntu) is set to at least 35 seconds | | Authentication fails immediately | Verify shared secret matches between the RADIUS config file and Mideye Server RADIUS client. Check for hidden characters with cat -A /etc/pam_radius_auth.conf | | No RADIUS logs in Mideye Server | Verify UDP port 1812 is open between the Linux server and Mideye Server | | OTP prompt does not appear | Verify KbdInteractiveAuthentication yes (OpenSSH 9+) or ChallengeResponseAuthentication yes (OpenSSH 8.x) is set in /etc/ssh/sshd_config. Also verify UsePAM yes is set. Restart the SSH service after any changes. | | Invalid user or illegal user in auth.log | The username has no local Unix account on this machine. Create one with sudo useradd -m <username> before testing. | | User not found | Verify the Linux user exists (id <username>) and the username matches the Mideye user repository | | client_id mismatch | Verify the NAS-ID in /etc/pam.d/sshd matches the NAS-ID in the Mideye RADIUS client configuration | | RADIUS accepted in Mideye logs but login still fails | Check that pam_radius_auth.so is set to sufficient in /etc/pam.d/sshd, not requisite. With requisite, RADIUS success continues the PAM chain where pam_unix fails on a locked account and denies the login. | | Domain user not found (id returns nothing) | Verify SSSD is running (systemctl status sssd) and the user exists in Active Directory |