Skip to content

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