How to Configure Apache LDAP Authentication for Nested Active Directory Groups


105 views

When implementing LDAP authentication with Apache, many administrators encounter limitations with nested Active Directory group memberships. The standard configuration using Require ldap-group only checks direct group membership, ignoring the hierarchical structure common in enterprise environments.

Your existing setup looks like this:

AuthName            "whatever"
AuthType            Basic
AuthBasicProvider   ldap
AuthLDAPUrl         "ldap://server/OU=SBSUsers,OU=Users,OU=MyBusiness,DC=company,DC=local?sAMAccountName?sub?(objectClass=*)"
Require ldap-group  CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local

The mod_authnz_ldap module doesn't automatically resolve nested group memberships due to:

  • Performance considerations (recursive queries can be expensive)
  • Potential circular reference risks
  • Varying implementations across directory servers

For Windows Server 2003 and later, we can leverage the matching rule extension:

Require ldap-attribute memberOf:1.2.840.113556.1.4.1941:=CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local

Here's a full working configuration that handles nested groups:

<Location /secure>
    AuthType Basic
    AuthName "Restricted Area"
    AuthBasicProvider ldap
    AuthLDAPUrl "ldap://dc.company.local:389/DC=company,DC=local?sAMAccountName?sub?(objectClass=user)"
    AuthLDAPBindDN "CN=LDAP Bind,OU=Service Accounts,DC=company,DC=local"
    AuthLDAPBindPassword "password"
    AuthLDAPGroupAttribute member
    AuthLDAPGroupAttributeIsDN on
    AuthLDAPMaxSubGroupDepth 10
    Require ldap-attribute memberOf:1.2.840.113556.1.4.1941:=CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local
</Location>
Parameter Purpose
AuthLDAPMaxSubGroupDepth Controls recursion depth (default 10)
memberOf:1.2.840.113556.1.4.1941 LDAP_MATCHING_RULE_IN_CHAIN OID
AuthLDAPGroupAttributeIsDN Required for proper group resolution

If the previous method doesn't work, you can implement a custom solution:

AuthLDAPSubGroupClass group
AuthLDAPSubGroupAttribute member
Require ldap-filter "(&(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local))"

When working with nested groups:

  • Limit the maximum recursion depth
  • Consider using global catalog servers
  • Implement caching where possible
  • Monitor LDAP query response times

Use ldapsearch to verify group membership resolution:

ldapsearch -H ldap://dc.company.local -x -D "binduser@company.local" -W -b "DC=company,DC=local" \
"(memberOf:1.2.840.113556.1.4.1941:=CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local)" \
sAMAccountName

When configuring LDAP authentication in Apache, you might encounter a common limitation: the default setup doesn't automatically recognize users in nested groups. Consider this typical configuration:

AuthName            "whatever"
AuthType            Basic
AuthBasicProvider   ldap
AuthLDAPUrl         "ldap://server/OU=SBSUsers,OU=Users,OU=MyBusiness,DC=company,DC=local?sAMAccountName?sub?(objectClass=*)"
Require ldap-group  CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local

This works fine for users directly in MySpecificGroup, but fails for users in nested groups like MyOtherGroup.

Apache's mod_authnz_ldap doesn't automatically expand group membership by default. This is primarily due to:

  • Performance considerations (recursive group expansion can be expensive)
  • Potential for infinite recursion in circular group references
  • Security implications of deep group nesting

To enable nested group support, you need to modify your configuration:

AuthLDAPGroupAttribute member
AuthLDAPGroupAttributeIsDN on
AuthLDAPSubGroupClass group
AuthLDAPSubGroupAttribute member

Here's a complete working example:

<Location /secure>
    AuthName "Restricted Area"
    AuthType Basic
    AuthBasicProvider ldap
    AuthLDAPUrl "ldap://dc.company.local/OU=Users,DC=company,DC=local?sAMAccountName?sub?(objectClass=user)"
    AuthLDAPBindDN "CN=ServiceAccount,OU=Service Accounts,DC=company,DC=local"
    AuthLDAPBindPassword "password"
    
    # Nested group configuration
    AuthLDAPGroupAttribute member
    AuthLDAPGroupAttributeIsDN on
    AuthLDAPSubGroupClass group
    AuthLDAPSubGroupAttribute member
    
    Require ldap-group CN=MySpecificGroup,OU=Groups,DC=company,DC=local
</Location>

For more complex scenarios, you can use LDAP filters instead of group membership checks:

Require ldap-filter memberOf:1.2.840.113556.1.4.1941:=CN=MySpecificGroup,OU=Groups,DC=company,DC=local

The 1.2.840.113556.1.4.1941 OID enables recursive group expansion in the LDAP query itself.

When working with nested groups:

  • Limit the depth of group nesting (3-4 levels max)
  • Consider caching authentication results
  • Use specific OUs rather than broad searches
  • Monitor LDAP server performance

If nested groups still don't work:

  1. Verify your service account has permissions to read group membership
  2. Check for circular group references
  3. Test with a direct LDAP query first
  4. Enable debug logging with LogLevel debug