auth-pam: PAM authentication dynamic module for NGINX
Requires the Pro plan (or higher) of the GetPageSpeed NGINX Extras subscription.
Installation
You can install this module in any RHEL-based distribution, including, but not limited to:
- RedHat Enterprise Linux 7, 8, 9 and 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 and Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-auth-pam
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-auth-pam
Enable the module by adding the following at the top of /etc/nginx/nginx.conf:
load_module modules/ngx_http_auth_pam_module.so;
This document describes nginx-module-auth-pam v1.6.1 released on Feb 15 2026.
Enterprise-grade PAM authentication for NGINX
Overview
This module provides HTTP Basic Authentication via PAM (Pluggable Authentication Modules) for NGINX.
- Complete ground-up implementation (not a fork)
- Drop-in compatible with legacy configurations
- Hardened security, battle-tested in production
Key Features
- HTTP Basic Auth via PAM
- Variable expansion in realm (conditional auth)
- PAM environment export (HOST, REQUEST)
- Auth result caching in shared memory (for LDAP/AD performance)
- Async authentication via thread pool (non-blocking workers)
- Dynamic module support
Configuration
| Directive | Default | Description |
|---|---|---|
auth_pam |
- | Realm name for HTTP Basic auth. Supports variables. Set to off to disable. |
auth_pam_service_name |
nginx |
PAM service name (matches /etc/pam.d/<name>) |
auth_pam_set_pam_env |
off |
Export HOST and REQUEST to PAM environment |
auth_pam_cache_zone |
- | Define shared memory zone: zone=name:size (http context only) |
auth_pam_cache |
- | Enable auth caching: zone=name time=60s |
auth_pam_thread_pool |
default |
Thread pool for async auth (requires --with-threads). Set to off for sync mode. |
Examples
Basic Usage
Protect a location with PAM authentication:
location /secure {
auth_pam "Secure Zone";
auth_pam_service_name "nginx";
}
Create the PAM service file /etc/pam.d/nginx:
auth required pam_unix.so
account required pam_unix.so
LDAP Authentication
Use PAM LDAP module for directory-based auth:
location /ldap-protected {
auth_pam "LDAP Zone";
auth_pam_service_name "nginx_ldap";
}
PAM service file /etc/pam.d/nginx_ldap:
auth required pam_ldap.so
account required pam_ldap.so
Auth Caching
Cache successful authentications to reduce load on PAM backends (especially useful for LDAP/AD):
http {
auth_pam_cache_zone zone=pam_cache:1m;
server {
location /cached-auth {
auth_pam "Cached Zone";
auth_pam_service_name "nginx_ldap";
auth_pam_cache zone=pam_cache time=60s;
}
}
}
Notes: - Only successful authentications are cached (failed attempts always hit PAM) - Passwords are SHA1-hashed in cache keys, never stored in plaintext - Service name is included in cache key to prevent cross-service collisions - Recommended TTL: 60s (default), adjust based on security requirements
Async Authentication (Thread Pool)
When NGINX is compiled with --with-threads, PAM authentication is automatically offloaded to a thread pool. This prevents slow PAM backends (LDAP/AD) from blocking worker processes.
# Default behavior - uses NGINX's "default" thread pool automatically
location /protected {
auth_pam "Restricted";
auth_pam_service_name "nginx_ldap";
}
# Use a custom thread pool for high-volume auth
thread_pool pam_pool threads=4 max_queue=256;
http {
server {
location /high-volume {
auth_pam "High Volume Zone";
auth_pam_service_name "nginx_ldap";
auth_pam_thread_pool pam_pool;
}
}
}
# Force synchronous mode (disable async)
location /sync-auth {
auth_pam "Sync Zone";
auth_pam_service_name "nginx";
auth_pam_thread_pool off;
}
Notes:
- Requires NGINX built with --with-threads
- Cache is checked before posting to thread pool (fast path for cache hits)
- Returns 503 if thread pool queue is full
Conditional Authentication
Skip PAM for certificate-authenticated clients:
map $ssl_client_verify $pam_realm {
SUCCESS "off";
default "Restricted Area";
}
server {
listen 443 ssl;
ssl_client_certificate /etc/nginx/ca.crt;
ssl_verify_client optional;
location /api {
auth_pam $pam_realm;
auth_pam_service_name "nginx";
}
}
Disable auth for internal networks:
geo $pam_realm {
default "Restricted";
10.0.0.0/8 "off";
}
location /internal {
auth_pam $pam_realm;
auth_pam_service_name "nginx";
}
PAM Environment with pam_exec
Export request details to PAM for custom authentication scripts:
location /custom-auth {
auth_pam "Custom Zone";
auth_pam_service_name "nginx_exec";
auth_pam_set_pam_env on;
}
When enabled, PAM environment includes:
HOST- Request host header (e.g.,localhost:8000)REQUEST- Full request line (e.g.,GET /path?query HTTP/1.1)
PAM service file /etc/pam.d/nginx_exec:
auth required pam_exec.so /path/to/auth-script.sh
account required pam_permit.so
Using the $pam_user Variable
After successful PAM authentication, the $pam_user variable contains the authenticated username:
location /api {
auth_pam "API Access";
auth_pam_service_name "nginx";
# Add username header for backend
proxy_set_header X-Authenticated-User $pam_user;
proxy_pass http://backend;
}
# Custom access log with username
log_format auth '$remote_addr - $pam_user [$time_local] "$request"';
access_log /var/log/nginx/access.log auth;
Notes:
- Empty when auth_pam off or authentication fails
- Works with sync, async (thread pool), and cached authentication