Introduction
Pluggable Authentication Modules (PAM) form the backbone of Linux authentication. Every SSH login, sudo invocation, and system service authentication flows through PAM’s modular stack. While the default pam_unix module handles basic password authentication, modern security requirements demand multi-factor authentication (MFA), hardware token support, and push-based verification.
This guide compares four major PAM modules for adding second-factor authentication to your Linux servers: Google Authenticator PAM (TOTP-based), pam_u2f (FIDO2/U2F hardware keys), pam_oath (OATH HOTP/TOTP from the PAM ecosystem), and pam_duo (Duo Security push-based 2FA).
Why Self-Host Your Authentication Stack?
Self-hosting your PAM authentication layer means you control the entire authentication pipeline — no third-party service sees your login attempts, user credentials never leave your infrastructure, and you’re not vendor-locked into a proprietary MFA solution that could change pricing or shut down.
For organizations running on-premises or colocated infrastructure, local PAM modules integrate directly with existing directory services like OpenLDAP, FreeIPA, or Samba AD. You can enforce MFA policies uniformly across SSH, console, and sudo without deploying a separate authentication proxy.
Beyond security, self-hosting eliminates per-user SaaS licensing costs for MFA. A Google Authenticator PAM deployment costs nothing beyond the server it runs on, while pam_u2f works with any FIDO2-compatible hardware key — no recurring fees. For teams already managing their own Linux infrastructure, adding PAM-based MFA is a natural extension of existing operations.
Beyond the security benefits, PAM-based MFA is transparent to applications. Unlike application-layer MFA that requires modifying every web app with OAuth/OIDC callbacks, PAM sits below the application — any service that authenticates via PAM (SSH, sudo, login, su, cron, atd) automatically inherits your MFA policy. This means your database login, your monitoring agent, and your deployment scripts all get the same MFA protection without per-application configuration. For teams managing dozens of services across hundreds of servers, this uniformity is invaluable.
PAM modules also integrate with existing monitoring and alerting stacks. Failed authentication attempts flow through syslog, which you can ship to your SIEM or log aggregator. Combined with fail2ban or crowdsec, you can automatically block IPs that trigger repeated MFA failures — creating a defense-in-depth authentication perimeter that spans your entire server fleet.
If you’re also hardening SSH access, see our SSH security auditing guide. For hardware-based authentication at the application layer, check our passkey authentication comparison. For broader security awareness, our phishing simulation guide complements MFA deployment.
Comparison Table
| Feature | pam_google_authenticator | pam_u2f | pam_oath | pam_duo |
|---|---|---|---|---|
| Auth Method | TOTP (time-based) | FIDO2/U2F hardware | HOTP/TOTP (OATH) | Push notification |
| Hardware Required | Phone/app (any TOTP) | YubiKey/security key | Hardware token or app | Phone with Duo app |
| Offline Capable | Yes (fully offline) | Yes (fully offline) | Yes (fully offline) | No (requires Duo cloud) |
| Dependency | libpam-google-authenticator | libpam-u2f | liboath (oath-toolkit) | duo_unix + Internet |
| Setup Complexity | Low | Low | Medium | Medium |
| RHEL/CentOS Package | google-authenticator | pam_u2f | pam_oath | duo_unix |
| Debian/Ubuntu Package | libpam-google-authenticator | libpam-u2f | libpam-oath | duo-unix |
| GitHub Stars | 1,986 ★ | 642 ★ | Part of oath-toolkit | 360 ★ |
| Last Updated | Feb 2026 | Mar 2025 | Active (system project) | May 2026 |
PAM Stack Configuration
PAM configuration files live in /etc/pam.d/. Each service (sshd, sudo, login) has its own file that defines the authentication modules and their control flags. Here’s the standard structure:
| |
The control flags determine behavior: required (must pass, but continues to next module), requisite (must pass, stops on failure), sufficient (if passes, skip remaining), and optional (pass or fail doesn’t matter).
Installing pam_google_authenticator
| |
Then configure PAM to require it. For SSH, add to /etc/pam.d/sshd:
| |
The nullok option allows users without a configured secret to still log in. Remove it once all users have set up their tokens.
Important SSH configuration: In /etc/ssh/sshd_config, ensure:
| |
This requires both SSH key AND TOTP code for login — true two-factor authentication.
Installing pam_u2f
| |
PAM configuration in /etc/pam.d/sshd:
| |
The authfile can be a central mapping file or user-specific ~/.config/Yubico/u2f_keys. The cue option prompts users to touch their security key.
User mapping file format (/etc/u2f_mappings):
| |
Installing pam_oath
| |
PAM uses a central users file at /etc/users.oath:
| |
PAM configuration:
| |
Installing pam_duo
| |
Configure /etc/duo/pam_duo.conf:
| |
PAM configuration:
| |
PAM Configuration Patterns
Pattern 1: SSH Key + TOTP (Most Common)
This gives you public-key first factor plus time-based code second factor:
| |
Pattern 2: Password OR Hardware Key
Allows login with EITHER password or U2F key (convenient migration pattern):
| |
Pattern 3: Required Hardware Key + Optional TOTP
Both factors required for high-security environments:
| |
Pattern 4: Fail-Open with Duo Push
| |
Testing PAM Configuration
PAM configurations are notoriously unforgiving — one mistake can lock you out. Always test in a separate terminal session:
| |
Critical safety tip: Keep a root shell open in a separate tmux/screen session when modifying PAM. If you lock yourself out of SSH, you can recover through the console.
Security Best Practices
Use
requirednotrequisitefor MFA modules —requisitestops processing immediately on failure, which means error messages don’t reach the remaining modules.requiredcontinues to the end of the stack, giving complete audit logging.Centralize user secret storage — For pam_oath and pam_u2f with
authfile, store mappings in a central, root-readable-only file (/etc/u2f_mappings,/etc/users.oath). Never rely on user-writable home directories for security-critical data.Rate-limit authentication attempts — Combine with
pam_faillock.soto lock accounts after repeated failures:
| |
Avoid
nullokin production — Thenullokoption for pam_google_authenticator allows users without configured tokens to bypass MFA. Remove it once all users are enrolled.Use
failmode=securefor pam_duo — In production, change fromfailmode=safe(allows access when Duo is unreachable) tofailmode=secure(denies access).safemode is appropriate during initial rollout.
FAQ
Can I use multiple PAM MFA modules simultaneously?
Yes — PAM’s stacking design allows chaining. A common enterprise pattern is pam_unix.so (password) + pam_google_authenticator.so (TOTP) + pam_u2f.so (hardware key). However, each additional module adds authentication latency and complexity. Most deployments stop at two factors.
What happens if I lose my TOTP device or hardware key?
With pam_google_authenticator, each user’s ~/.google_authenticator file contains emergency scratch codes. Print these and store them securely. For pam_u2f, register at least two U2F keys per user — keep one as a backup in a safe location. For pam_oath, administrators can generate new secrets and update /etc/users.oath.
Does Duo’s cloud dependency create a single point of failure?
Yes. If Duo’s service is unreachable and you’ve configured failmode=safe, authentication falls through to the next PAM module (typically pam_unix password). With failmode=secure, all authentications fail. For mission-critical servers, prefer offline-capable modules like pam_google_authenticator or pam_u2f.
Which module has the lowest operational overhead?
pam_google_authenticator wins on simplicity — a single package install, user-side google-authenticator setup, and one PAM line. No hardware to distribute, no external service dependency, and TOTP apps are free on all platforms. The tradeoff is slightly weaker security compared to hardware-backed U2F.
Can PAM modules integrate with centralized directory services?
Yes. The PAM stack natively supports LDAP via pam_ldap.so and Kerberos via pam_krb5.so. You can layer MFA on top: LDAP for user identification, TOTP for second factor. FreeIPA bundles this integration out of the box with its own OTP module.
💰 想测试你的市场判断力?我用 Polymarket 做预测市场交易——这是全球最大的预测市场平台,从大选结果到科技监管时间线,什么都可以押注。和赌博不同,这是真正的信息市场:你懂的信息越多,胜率越高。我靠预测科技相关事件的走向已经赚了不少。用我的邀请链接注册:Polymarket.com