Integrating Kerberos SSO with LDAP Group Authorization in Apache: A mod_auth_kerb + mod_authnz_ldap Implementation Guide


2 views

The fundamental issue with standalone mod_auth_kerb is its binary access control. While it handles Kerberos authentication beautifully, it lacks granular authorization capabilities. This becomes problematic when you need to restrict access based on Active Directory/LDAP group membership.

The optimal approach combines three Apache modules:

LoadModule auth_kerb_module modules/mod_auth_kerb.so
LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
LoadModule ldap_module modules/mod_ldap.so

Here's a production-tested configuration snippet:

<Location /secure>
    AuthType Kerberos
    AuthName "Kerberos Auth"
    KrbMethodNegotiate On
    KrbMethodK5Passwd Off
    KrbServiceName HTTP
    KrbAuthRealms DOMAIN.LOCAL
    Krb5Keytab /etc/apache2/http.keytab
    
    # LDAP Authorization Layer
    AuthBasicProvider ldap
    AuthzLDAPAuthoritative on
    AuthLDAPURL "ldap://dc.domain.local:389/DC=domain,DC=local?sAMAccountName?sub?(objectClass=*)"
    AuthLDAPBindDN "CN=LDAP User,CN=Users,DC=domain,DC=local"
    AuthLDAPBindPassword "password123"
    Require ldap-group CN=WebUsers,OU=Groups,DC=domain,DC=local
    
    # Username transformation
    RewriteEngine On
    RewriteCond %{LA-U:REMOTE_USER} (.+)@DOMAIN.LOCAL
    RewriteRule . - [E=RU:%1]
    RequestHeader set X-Remote-User %{RU}e
</Location>

The critical part is transforming username@REALM to username for downstream applications. The mod_rewrite solution shown above handles this elegantly. For applications like Trac, you might alternatively use:

SetEnvIf REMOTE_USER "(.*)@DOMAIN.LOCAL" REMOTE_DISPLAY_NAME=$1

When implementing this in high-traffic environments:

  • Enable LDAP connection pooling with LDAPCacheEntries
  • Set appropriate LDAPOpCacheEntries values
  • Consider using KrbLocalUserMapping to avoid repeated LDAP lookups

Common issues and their solutions:

# Debug mod_auth_kerb
LogLevel debug
Krb5Trace /var/log/httpd/krb5.log

# Debug LDAP
LDAPLibraryDebug 3
LDAPVerifyServerCert off

When implementing Kerberos-based SSO with mod_auth_kerb, administrators often need more granular control than simple domain-wide authentication. The requirement to check LDAP group membership while maintaining the Kerberos SSO flow creates interesting technical hurdles.

The solution lies in combining mod_auth_kerb with mod_authnz_ldap. The key configuration directive is indeed KrbAuthoritative:


<Location /secure>
    AuthType Kerberos
    AuthName "Kerberos Auth"
    KrbMethodNegotiate On
    KrbMethodK5Passwd Off
    KrbAuthoritative Off
    AuthBasicProvider ldap
    AuthzLDAPAuthoritative On
    AuthLDAPURL "ldap://ldap.example.com/ou=users,dc=example,dc=com?uid"
    AuthLDAPGroupAttribute memberUid
    AuthLDAPGroupAttributeIsDN off
    Require ldap-group cn=webusers,ou=groups,dc=example,dc=com
</Location>

The Kerberos authentication typically returns usernames in user@REALM format, while LDAP stores just user. Apache's mod_rewrite can help normalize this:


RewriteEngine On
RewriteCond %{LA-U:REMOTE_USER} ^([^@]+)@
RewriteRule . - [E=RU:%1]
RequestHeader set X-Remote-User %{RU}e

Here's a complete virtual host configuration that implements both Kerberos SSO and LDAP group checks:


<VirtualHost *:443>
    ServerName secureapp.example.com
    
    # Kerberos Authentication
    <Location />
        AuthType Kerberos
        AuthName "Kerberos Login"
        KrbAuthRealms EXAMPLE.COM
        Krb5Keytab /etc/apache2/keytab
        KrbMethodNegotiate On
        KrbMethodK5Passwd Off
        KrbAuthoritative Off
    </Location>
    
    # LDAP Authorization
    <Location /restricted>
        AuthBasicProvider ldap
        AuthLDAPURL "ldap://ldap.example.com/dc=example,dc=com?uid?sub?(objectClass=*)"
        AuthLDAPGroupAttribute member
        AuthLDAPGroupAttributeIsDN on
        Require ldap-group cn=app-users,ou=groups,dc=example,dc=com
    </Location>
    
    # Username transformation
    RewriteEngine On
    RewriteCond %{LA-U:REMOTE_USER} ^([^@]+)@
    RewriteRule . - [E=KRB_USER:%1]
    RequestHeader set X-Remote-User "%{KRB_USER}e"
</VirtualHost>
  • Ensure your keytab file has proper permissions (usually readable by Apache user)
  • Verify LDAP binds work independently of Kerberos first
  • Check Apache error logs with LogLevel debug temporarily
  • Use kinit and ldapsearch to test credentials manually

For high-traffic sites, consider:

  1. LDAP connection pooling with AuthLDAPMaxConnection
  2. Kerberos ticket caching
  3. Implementing a reverse proxy with authentication to offload from app servers

The combination provides enterprise-grade security while maintaining user convenience - the best of both worlds for internal applications.