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:
- Verify your service account has permissions to read group membership
- Check for circular group references
- Test with a direct LDAP query first
- Enable debug logging with
LogLevel debug