How to Implement LDAP Authentication with Nginx: A Complete Technical Guide


2 views

Nginx doesn't include built-in LDAP authentication support like Apache's mod_auth_ldap. The core Nginx distribution focuses on high-performance web serving and reverse proxying without native LDAP integration. This architectural difference is important when migrating from Apache.

There are several approaches to implement LDAP authentication with Nginx:

1. Nginx Plus (Commercial Version):
   - Includes LDAP authentication via the auth_ldap module
   - Official documentation provides detailed configuration examples

2. Open Source Solutions:
   - auth_request module with an external authentication service
   - lua-resty-ldap for OpenResty users
   - Third-party modules like nginx-auth-ldap

The most common approach in open-source Nginx is using the auth_request module. Here's a sample configuration:

server {
    listen 80;
    server_name example.com;

    location / {
        auth_request /auth;
        error_page 401 = @error401;

        # Your normal proxy or static file configuration
        proxy_pass http://backend;
    }

    location = /auth {
        internal;
        proxy_pass http://auth-service;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URI $request_uri;
    }

    location @error401 {
        return 302 /login;
    }
}

Here's a basic Python Flask service that handles LDAP authentication:

from flask import Flask, request
import ldap

app = Flask(__name__)

@app.route('/auth', methods=['GET'])
def auth():
    username = request.headers.get('X-Username')
    password = request.headers.get('X-Password')
    
    try:
        conn = ldap.initialize('ldap://your-ldap-server')
        conn.simple_bind_s(f"uid={username},ou=users,dc=example,dc=com", password)
        return "", 200
    except ldap.INVALID_CREDENTIALS:
        return "", 401
    except Exception as e:
        return "", 403

if __name__ == '__main__':
    app.run(port=5000)

When implementing LDAP authentication with Nginx:

  • Cache successful authentications to reduce LDAP server load
  • Implement connection pooling for your LDAP service
  • Consider failover mechanisms for your LDAP infrastructure
  • Monitor authentication latency

For more direct integration, OpenResty provides Lua-based LDAP capabilities:

location /secure {
    access_by_lua_block {
        local ldap = require "resty.ldap"
        local ldap_auth = require "resty.ldap.authenticate"
        
        local ok, err = ldap_auth.authenticate({
            ldap_server = "ldap.example.com",
            ldap_port = 389,
            base_dn = "ou=users,dc=example,dc=com",
            attribute = "uid",
            timeout = 5000,  -- 5 seconds
        })
        
        if not ok then
            ngx.exit(ngx.HTTP_FORBIDDEN)
        end
    }
    
    proxy_pass http://backend;
}

When moving from Apache's mod_auth_ldap:

  • Map your existing LDAP search filters to the new implementation
  • Replicate any special attribute requirements
  • Test group membership requirements thoroughly
  • Consider session duration and caching behavior differences

Nginx doesn't natively support LDAP authentication like Apache's mod_auth_ldap. However, you can achieve this through various workarounds. The most common approach is using the auth_request module with an external authentication service.

This method delegates authentication to an external service that handles LDAP:


location / {
    auth_request /auth;
    error_page 401 = @error401;
}

location = /auth {
    internal;
    proxy_pass http://ldap-auth-service;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
}

For more flexibility, consider OpenResty (Nginx + Lua):


location /secure {
    access_by_lua_block {
        local ldap = require "resty.ldap"
        local ld = ldap:new()
        local ok, err = ld:connect("ldap.example.com", 389)
        if not ok then
            ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
        end
        
        local res, err = ld:bind("uid="..ngx.var.remote_user..",ou=users,dc=example,dc=com", ngx.var.remote_passwd)
        if not res then
            ngx.exit(ngx.HTTP_FORBIDDEN)
        end
    }
}

Consider these community-developed modules:

  • nginx-auth-ldap: https://github.com/kvspb/nginx-auth-ldap
  • nginx-ldap-auth: https://github.com/nginxinc/nginx-ldap-auth

When migrating from Apache's mod_auth_ldap:

  1. Map your existing LDAP queries to the new solution
  2. Test group membership requirements thoroughly
  3. Consider performance impact of external auth services

LDAP authentication adds overhead. Implement caching:


proxy_cache_path /tmp/ldap_cache levels=1:2 keys_zone=ldap_cache:10m inactive=60m;

location /auth {
    proxy_cache ldap_cache;
    proxy_cache_valid 200 10m;
    # ... rest of auth config
}