After upgrading to Security Services Platform (SSP) version 5.1.0, LDAP users may experience significantly slow login times (up to 90 seconds or more) or complete login failures. This issue affects environments using Active Directory (AD) or OpenLDAP with nested group memberships.
SSP 5.1.1 addresses this issue by disabling recursive group search by default while providing administrators the option to enable it if nested group functionality is required.
SSP 5.1.1 and later
SSP 5.1.0 introduced LDAP_MATCHING_RULE_IN_CHAIN (OID: 1.2.840.113556.1.4.1941) for recursive group membership resolution. This feature allows users in nested groups to inherit permissions from parent groups.
Example of nested groups:
user10 --> memberOf --> Group1 --> memberOf --> sspgroup
With recursive search enabled, assigning enterprise_admin role to sspgroup would grant user10 the same permissions.
Why does this cause slow logins?
The LDAP_MATCHING_RULE_IN_CHAIN OID instructs the LDAP server to traverse the entire group membership hierarchy from the object to the root, checking ancestry at every level. In environments with:
This recursive traversal becomes computationally expensive and results in slow LDAP queries or timeouts.
Before enabling recursive group search, test how long LDAP queries take in your environment.
SSH to the SSPI VM via CLI using sysadmin user (the management VM that deploys and manages the SSP Kubernetes cluster) and run the following commands to test query time.
Test DIRECT group search (default behavior in SSP 5.1.1+):
time ldapsearch -x -H {REPLACE_WITH_LDAP_SERVER} \
-D {REPLACE_WITH_BIND_DN} \
-w {REPLACE_WITH_LDAP_PASSWORD} \
-b {REPLACE_WITH_BASE_DN} \
"(&(member={REPLACE_WITH_TEST_USER_DN})(objectClass=group))" dn
Example:
time ldapsearch -x -H ldaps://ad-server.corp.example.com:636 \ -D "CN=ldapbind,OU=Service Accounts,DC=corp,DC=example,DC=com" \ -w "ldappassword123" \ -b "DC=corp,DC=example,DC=com" \ "(&(member=CN=testuser,OU=Users,DC=corp,DC=example,DC=com)(objectClass=group))" dn
Test RECURSIVE group search (optional feature):
time ldapsearch -x -H {REPLACE_WITH_LDAP_SERVER} \
-D {REPLACE_WITH_BIND_DN} \
-w {REPLACE_WITH_LDAP_PASSWORD} \
-b {REPLACE_WITH_BASE_DN} \
"(&(member:1.2.840.113556.1.4.1941:={REPLACE_WITH_TEST_USER_DN})(objectClass=group))" dn
Example:
time ldapsearch -x -H ldaps://ad-server.corp.example.com:636 \ -D "CN=ldapbind,OU=Service Accounts,DC=corp,DC=example,DC=com" \ -w "ldappassword123" \ -b "DC=corp,DC=example,DC=com" \ "(&(member:1.2.840.113556.1.4.1941:=CN=testuser,OU=Users,DC=corp,DC=example,DC=com)(objectClass=group))" dn
Test DIRECT group search (default behavior in SSP 5.1.1+):
time ldapsearch -x -H {REPLACE_WITH_LDAP_SERVER} \
-D {REPLACE_WITH_BIND_DN} \
-w {REPLACE_WITH_LDAP_PASSWORD} \
-b {REPLACE_WITH_BASE_DN} \
"(&(|(memberUid={REPLACE_WITH_TEST_USER_UID})(uniqueMember={REPLACE_WITH_TEST_USER_DN})(member={REPLACE_WITH_TEST_USER_DN}))(|(objectClass=group)(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=posixGroup)))" dn
Example:
time ldapsearch -x -H ldaps://openldap.corp.example.com:636 \ -D "cn=admin,dc=corp,dc=example,dc=com" \ -w "ldappassword123" \ -b "dc=corp,dc=example,dc=com" \ "(&(|(memberUid=testuser)(uniqueMember=uid=testuser,ou=People,dc=corp,dc=example,dc=com)(member=uid=testuser,ou=People,dc=corp,dc=example,dc=com))(|(objectClass=group)(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=posixGroup)))" dn
Test RECURSIVE group search (optional feature):
time ldapsearch -x -H {REPLACE_WITH_LDAP_SERVER} \
-D {REPLACE_WITH_BIND_DN} \
-w {REPLACE_WITH_LDAP_PASSWORD} \
-b {REPLACE_WITH_BASE_DN} \
"(&(|(memberUid={REPLACE_WITH_TEST_USER_UID})(uniqueMember={REPLACE_WITH_TEST_USER_DN})(member:1.2.840.113556.1.4.1941:={REPLACE_WITH_TEST_USER_DN}))(|(objectClass=group)(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=posixGroup)))" dn
Example:
time ldapsearch -x -H ldaps://openldap.corp.example.com:636 \ -D "cn=admin,dc=corp,dc=example,dc=com" \ -w "ldappassword123" \ -b "dc=corp,dc=example,dc=com" \ "(&(|(memberUid=testuser)(uniqueMember=uid=testuser,ou=People,dc=corp,dc=example,dc=com)(member:1.2.840.113556.1.4.1941:=uid=testuser,ou=People,dc=corp,dc=example,dc=com))(|(objectClass=group)(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=posixGroup)))" dn
| < 2 seconds | Safe to enable recursive group search |
| 2-10 seconds | Consider carefully; may impact user experience |
| > 10 seconds | Do NOT enable recursive group search |
If testing shows acceptable query times and you require nested group functionality, follow these steps:
The SSPI VM (Secop) is the management VM that deploys and manages the SSP Kubernetes cluster. It has kubectl pre-configured to access the SSP cluster.
ssh sysadmin@<sspi-vm-ip>
k get configmap authelia-ldap-override -n nsxi-platform -o yaml
Expected default output:
apiVersion: v1
kind: ConfigMap
metadata:
name: authelia-ldap-override
namespace: nsxi-platform
data:
override.yaml: |
activedirectory:
groups_filter: ""
users_filter: ""
attributes:
display_name: ""
distinguished_name: ""
group_name: ""
mail: ""
member_of: ""
username: ""
openldap:
groups_filter: ""
users_filter: ""
attributes:
display_name: ""
distinguished_name: ""
group_name: ""
mail: ""
member_of: ""
username: ""
k edit configmap authelia-ldap-override -n nsxi-platform
For Active Directory, modify the activedirectory section:
data:
override.yaml: |
activedirectory:
groups_filter: "(&(member:1.2.840.113556.1.4.1941:={dn})(objectClass=group))"
users_filter: ""
attributes:
display_name: ""
distinguished_name: ""
group_name: ""
mail: ""
member_of: ""
username: ""
openldap:
groups_filter: ""
users_filter: ""
attributes:
display_name: ""
distinguished_name: ""
group_name: ""
mail: ""
member_of: ""
username: ""
For OpenLDAP, modify the openldap section:
data:
override.yaml: |
activedirectory:
groups_filter: ""
users_filter: ""
attributes:
display_name: ""
distinguished_name: ""
group_name: ""
mail: ""
member_of: ""
username: ""
openldap:
groups_filter: "(&(|(memberUid={input})(uniqueMember={dn})(member:1.2.840.113556.1.4.1941:={dn}))(|(objectClass=group)(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=posixGroup)))"
users_filter: ""
attributes:
display_name: ""
distinguished_name: ""
group_name: ""
mail: ""
member_of: ""
username: ""
k rollout restart deployment/authelia -n nsxi-platform
k rollout status deployment/authelia -n nsxi-platform
Expected output:
deployment "authelia" successfully rolled out
Check Authelia logs for confirmation by executing below command
k logs -n nsxi-platform deployment/authelia -c authelia-ldap | grep -i "groups_filter\|override"
If recursive group search is causing issues and you need to disable it:
k edit configmap authelia-ldap-override -n nsxi-platform
Set groups_filter to an empty string:
data:
override.yaml: |
activedirectory:
groups_filter: ""
users_filter: ""
# ... rest of config
openldap:
groups_filter: ""
users_filter: ""
# ... rest of config
k rollout restart deployment/authelia -n nsxi-platform k rollout status deployment/authelia -n nsxi-platform
After making changes, verify LDAP login functionality:
If enabling recursive search: