After you deploy TLS certificates and verify LDAPS and STARTTLS, the next step is enforcement: reject simple password authentication received over unencrypted connections, require a minimum connection-security level where needed, and confirm that applications, replication, and local administration still work.
In this guide, we'll configure server-wide secure simple binds, optional global minimum Security Strength Factor (SSF), the root DSE exception, LDAPI SSF handling, normal LDAP listener retention versus LDAPS-only deployment, and verification of permitted and rejected connections. Initial certificate installation and client CA trust belong in TLS, STARTTLS, and LDAPS.
Before you start:
- TLS, STARTTLS, and LDAPS — working
Server-Cert, LDAPS on port636, STARTTLS on port389, and client CA trust - dsconf commands — online configuration
- dsctl commands — instance restart
- Manage users and groups — test user
uid=user1 - Restrict anonymous access — anonymous and unauthenticated bind policy
ssf bind rule and links to the dedicated ACI chapters for full examples.
Tested on: Rocky Linux 10.2; 389 Directory Server 3.2.0.
The lab uses instance ldap1 on ldap1.example.com with LDAP port 389 and LDAPS port 636. Enforcement tests run on ldap1 so other lab work on the same host is not disrupted. The plain-port disable demonstration uses ldap2 on ports 1389 and 1636 because that change removes the LDAP listener until you restore it.
Understand the available enforcement controls
Directory Server exposes several independent controls. Treat them as complementary layers, not as a single switch.
| Control | Scope | Typical use |
|---|---|---|
nsslapd-require-secure-binds |
Authenticated simple binds | Reject simple password authentication on unencrypted connections |
| Disable configured LDAP port | All TCP access to the normal LDAP listener | LDAPS-only environment |
nsslapd-minssf |
Most LDAP operations after security negotiation | Reject operations whose TLS, SASL, or LDAPI SSF is below the configured minimum |
nsslapd-minssf-exclude-rootdse |
Root DSE exception | Permit discovery before encryption |
nsslapd-localssf |
LDAPI connections | Assign security strength to local socket connections |
ACI ssf bind rule |
Selected entries or operations | Protect only sensitive actions |
The two server-wide settings most administrators enable first are:
| Control | What it enforces |
|---|---|
nsslapd-require-secure-binds |
Rejects authenticated simple binds unless the connection has confidentiality protection from LDAPS, STARTTLS, or a SASL privacy layer |
nsslapd-minssf |
Requires protected directory operations to meet a minimum strength through TLS, SASL, or LDAPI, while still permitting StartTLS and SASL negotiation |
Requiring secure binds does not block anonymous or unauthenticated binds, because those operations do not supply a password. It also affects server-to-server connections such as replication, synchronization, and database chaining when those agreements use simple binds. Migrate those connections before you enable enforcement.
Setting nsslapd-minssf alone does not prevent a client from first sending a password over plain LDAP. The server evaluates SSF when the operation begins, and the BindRequest can already have travelled in cleartext before the server rejects it. Clients must initiate LDAPS or successfully negotiate STARTTLS before sending credentials.
nsslapd-require-secure-binds is a server-side rejection policy. It does not stop a misconfigured client from sending a password in the initial cleartext BindRequest before the server rejects it. Configure clients to use LDAPS or require a successful STARTTLS upgrade before binding. With OpenLDAP tools, use -ZZ rather than an optional StartTLS request.
Verify TLS before enforcing secure connections
Confirm that TLS already works for the identities and connection modes you plan to keep. Do not enable enforcement while certificate, CA trust, or hostname validation tests are still failing.
Export the issuing CA if you have not already done so during the TLS chapter:
dsctl ldap1 tls export-cert Self-Signed-CA --output-file /tmp/389ds-selfsigned-ca.pemTest LDAPS with a normal directory user:
LDAPTLS_CACERT=/tmp/389ds-selfsigned-ca.pem ldapwhoami -x -H ldaps://ldap1.example.com:636 -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pwSample output:
dn: uid=user1,ou=people,dc=example,dc=comTest required STARTTLS on port 389:
LDAPTLS_CACERT=/tmp/389ds-selfsigned-ca.pem ldapwhoami -x -H ldap://ldap1.example.com:389 -ZZ -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pwSample output:
dn: uid=user1,ou=people,dc=example,dc=comAlso verify Directory Manager access over LDAPS or STARTTLS, client CA trust, certificate hostname validation, and any replication, chaining, or synchronization agreements before you change enforcement policy.
Audit clients and server-to-server connections
Before you enable secure binds or raise the minimum SSF, inventory every connection that touches the directory.
Record for each client or service:
Hostname
Port
Authentication method
TLS or SASL mode
CA trust configuration
Bind identityInclude:
- Applications using
ldap://without-ZZ - Applications already using
-ZZor STARTTLS - Clients using
ldaps:// - Replication agreements
- Database chaining backends
- Synchronization and pass-through authentication
- Monitoring, backup, and administration scripts
Update dependent connections to use LDAPS, required STARTTLS, certificate authentication, or an appropriate SASL mechanism before you enforce the new policy on the server.
Record the current enforcement settings
Before you change secure-bind or SSF policy, capture the current values:
dsconf ldap1 config get nsslapd-require-secure-binds nsslapd-minssf nsslapd-minssf-exclude-rootdse nsslapd-localssfSample lab output:
nsslapd-require-secure-binds: off
nsslapd-minssf: 0
nsslapd-minssf-exclude-rootdse: off
nsslapd-localssf: 71Save these values before changing the policy. The rollback examples later restore this lab's defaults; on another server, restore the values you recorded here.
Require secure authenticated binds
Check the current secure-bind setting:
dsconf ldap1 config get nsslapd-require-secure-bindsSample output:
nsslapd-require-secure-binds: offEnable secure simple binds:
dsconf ldap1 config replace nsslapd-require-secure-binds=onSample output:
Successfully replaced value(s) for 'nsslapd-require-secure-binds': 'on'Restart the instance so the policy takes effect:
dsctl ldap1 restartSample output:
Instance "ldap1" has been restartedWith nsslapd-require-secure-binds=on, Directory Server rejects simple password authentication unless the connection is protected by TLS or an applicable SASL privacy layer. The LDAP listener on port 389 can remain open because STARTTLS still requires that port.
Test secure-bind enforcement
Plain LDAP simple bind
Attempt a simple bind without TLS:
ldapwhoami -x -H ldap://ldap1.example.com:389 -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pwSample output:
ldap_bind: Confidentiality required (13)
additional info: Operation requires a secure connectionThe exact additional message can vary by server version. This failed bind is expected. Result code 13 confirms that Directory Server rejected the unencrypted authentication attempt.
STARTTLS bind
Repeat the bind with required STARTTLS:
LDAPTLS_CACERT=/tmp/389ds-selfsigned-ca.pem ldapwhoami -x -H ldap://ldap1.example.com:389 -ZZ -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pwSample output:
dn: uid=user1,ou=people,dc=example,dc=comLDAPS bind
Repeat the bind over LDAPS:
LDAPTLS_CACERT=/tmp/389ds-selfsigned-ca.pem ldapwhoami -x -H ldaps://ldap1.example.com:636 -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pwSample output:
dn: uid=user1,ou=people,dc=example,dc=comUnderstand what secure binds do not block
Secure-bind enforcement applies only when a client performs an authenticated simple bind with a password. Test these cases separately:
Anonymous bind over plain LDAP on this lab (with nsslapd-allow-anonymous-access: rootdse):
ldapwhoami -x -H ldap://ldap1.example.com:389Sample output:
ldap_parse_result: Inappropriate authentication (48)
additional info: Anonymous access is not allowed.
Result: Inappropriate authentication (48)
Additional info: Anonymous access is not allowed.Anonymous root DSE discovery still works when that mode is enabled. A base-scope ldapsearch command against the empty DN reads namingContexts without a bind password:
ldapsearch -LLL -x -H ldap://ldap1.example.com:389 -b "" -s base "(objectClass=*)" namingContextsSample output:
dn:
namingContexts: dc=example,dc=comUnauthenticated bind with a DN and empty password:
ldapwhoami -x -H ldap://ldap1.example.com:389 -D "uid=user1,ou=people,dc=example,dc=com" -w ''Sample output:
ldap_bind: Inappropriate authentication (48)
additional info: Anonymous access is not allowedAnonymous access, unauthenticated binds, SASL authentication, and LDAPI connections are controlled by separate settings. See Restrict anonymous access for bind-policy details. Do not assume that nsslapd-require-secure-binds=on disables every operation over plain LDAP.
Decide whether to keep the normal LDAP listener
The default LDAP listener uses port 389. Instance ldap2 in this lab listens on port 1389 instead; the same policy applies to whichever port nsslapd-port defines.
Keep the LDAP listener
Keep the LDAP listener when clients use:
- STARTTLS
- Anonymous root DSE discovery before STARTTLS
- SASL mechanisms that begin on the LDAP port
Secure binds can remain enabled while port 389 continues listening.
Disable the LDAP listener
For an intentionally LDAPS-only environment, disable the plain LDAP port after LDAPS is verified. This lab runs the command on ldap2 so ldap1 remains available for other exercises:
echo 'Yes I am sure' | dsconf -y /root/dm.pw ldap2 security disable_plain_portSample output:
Disabling plaintext ldap port - you must have ldaps configured :
Type 'Yes I am sure' to continue: Plaintext port disabled - please restart your instance to take effect
To undo this change run the subcommand - 'dsconf <instance> config replace nsslapd-port=<port number>'Restart the instance:
dsctl ldap2 restartSample output:
Instance "ldap2" has been restartedConfirm only the LDAPS listener remains with ss:
ss -lntp | grep -E ':1389|:1636'Sample output:
LISTEN 0 128 *:1636 *:* users:(("ns-slapd",pid=270926,fd=8))Port 1389 is absent because the plain LDAP port was disabled. STARTTLS is no longer available on that instance because clients cannot open the initial LDAP connection.
After disabling the normal LDAP listener, restore it through LDAPI as root. Create the LDIF first:
cat > /tmp/restore-ldap2-port.ldif <<'EOF'
dn: cn=config
changetype: modify
replace: nsslapd-port
nsslapd-port: 1389
EOFThen apply it:
ldapmodify -Y EXTERNAL -H ldapi://%2frun%2fslapd-ldap2.socket -f /tmp/restore-ldap2-port.ldifSample output:
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
modifying entry "cn=config"Restart the instance because port changes require a restart:
dsctl ldap2 restartConfirm both listeners return:
ss -lntp | grep -E ':1389|:1636'Sample output:
LISTEN 0 128 *:1636 *:* users:(("ns-slapd",pid=271357,fd=9))
LISTEN 0 128 *:1389 *:* users:(("ns-slapd",pid=271357,fd=8))Restore the normal LDAP port when you need STARTTLS or plain LDAP access again.
Do not disable the normal LDAP listener by default on a server that still serves STARTTLS clients.
Understand Security Strength Factor
SSF represents the strength of the protection applied to a connection. Directory Server can derive SSF from:
- TLS cipher and protocol negotiation
- SASL security layers
- LDAPI local connections through
nsslapd-localssf
When both TLS and SASL contribute SSF, Directory Server evaluates the stronger applicable value for the operation.
Directory Server permits the StartTLS extended operation and SASL BIND negotiation even when the current connection is below nsslapd-minssf, because those operations can raise the connection SSF. If the resulting TLS or SASL protection still does not meet the minimum, the bind or subsequent directory operations are rejected. UNBIND and ABANDON operations are also permitted below the threshold.
| Connection | Example SSF outcome |
|---|---|
| Plain LDAP simple bind | 0 |
| LDAPS or STARTTLS | Based on negotiated TLS strength (commonly 128 or higher on modern TLS) |
| SASL with integrity or encryption | Based on the SASL mechanism |
| TLS plus SASL | Higher applicable SSF |
| LDAPI | Value assigned through nsslapd-localssf |
nsslapd-localssf does not encrypt the Unix-domain socket. It assigns a policy strength value to the local IPC connection.
Avoid quoting one universal SSF for every TLS connection. The result depends on the negotiated security mechanism.
Configure a global minimum SSF
Check the current SSF settings:
dsconf ldap1 config get nsslapd-minssf nsslapd-minssf-exclude-rootdse nsslapd-localssfSample output:
nsslapd-minssf: 0
nsslapd-minssf-exclude-rootdse: off
nsslapd-localssf: 71Set the root DSE exception, raise the local LDAPI SSF, and apply a global minimum in one step so administration and discovery do not break mid-change:
dsconf ldap1 config replace nsslapd-minssf-exclude-rootdse=on nsslapd-localssf=128 nsslapd-minssf=128Sample output:
Successfully replaced value(s) for 'nsslapd-minssf-exclude-rootdse': 'on'
Successfully replaced value(s) for 'nsslapd-localssf': '128'
Successfully replaced value(s) for 'nsslapd-minssf': '128'The SSF settings are online configuration. A restart is not required for nsslapd-localssf; re-test with fresh connections after the change instead of restarting by default.
The value 128 is an example policy threshold. Validate it against TLS clients, SASL mechanisms, replication agreements, LDAPI administration, and legacy applications before you apply it in production.
These settings solve different problems. nsslapd-minssf-exclude-rootdse=on preserves root DSE discovery over a connection that does not meet the global minimum. Setting nsslapd-localssf to at least the same value as nsslapd-minssf lets LDAPI connections meet the global minimum during policy evaluation. Administrative operations over plain ldap:// still fail when their connection SSF is below the minimum; use LDAPS, required STARTTLS, or LDAPI instead.
Allow root DSE discovery without the minimum SSF
Some clients query the root DSE over plain LDAP to discover naming contexts, supported controls, SASL mechanisms, and STARTTLS support before they upgrade the connection.
With nsslapd-minssf-exclude-rootdse=on, test root DSE access:
ldapsearch -LLL -x -H ldap://ldap1.example.com:389 -b "" -s base namingContexts supportedSASLMechanismsSample output:
dn:
namingContexts: dc=example,dc=com
supportedSASLMechanisms: EXTERNAL
supportedSASLMechanisms: GSS-SPNEGO
supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: DIGEST-MD5The list of advertised SASL mechanisms varies by installed packages, server configuration, and system crypto policy. Do not expect every server to show the same mechanisms as this lab.
The root DSE exception only excludes root DSE queries from minimum-SSF enforcement. It does not override anonymous-access policy or ACIs.
A search against the normal directory suffix over plain LDAP still fails the minimum SSF or anonymous-access policy. On this lab, an anonymous suffix query returns:
Inappropriate authentication (48)
Additional information: Anonymous access is not allowed.Authenticated suffix operations must use LDAPS or STARTTLS when the minimum SSF is enforced.
Verify LDAPI access with minimum SSF
Local LDAPI connections use nsslapd-localssf. Ensure:
nsslapd-localssf >= nsslapd-minssfAfter setting both to 128, test LDAPI administration as root:
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2frun%2fslapd-ldap1.socket -b "cn=config" -s base nsslapd-minssf nsslapd-localssf nsslapd-minssf-exclude-rootdseSample output:
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn: cn=config
nsslapd-minssf: 128
nsslapd-localssf: 128
nsslapd-minssf-exclude-rootdse: onThe client-reported SASL SSF: 0 describes the negotiated SASL security layer. Directory Server separately assigns the LDAPI transport an SSF of 128 through nsslapd-localssf, allowing the operation to meet the global minimum.
This test assumes that LDAPI is enabled and that root is mapped to an authorized identity, normally cn=Directory Manager, through LDAPI autobind. nsslapd-localssf only assigns the local connection an SSF for policy evaluation; it does not enable LDAPI, autobind, or grant access to cn=config.
If nsslapd-localssf remains 71 while nsslapd-minssf=128, LDAPI operations do not meet the minimum. Plain ldap:// administration also remains below the minimum independently of the LDAPI setting.
Use an ACI SSF rule for sensitive operations
Global enforcement is not always necessary. An ACI ssf bind rule can require a minimum SSF for one operation or subtree while leaving other traffic unchanged.
Example intent: allow ordinary profile reads over authenticated connections, but require an SSF of at least 128 for password changes.
Conceptual bind rule:
(userdn="ldap:///self") and (ssf >= "128")Complete ACI syntax and self-service examples live in Advanced ACI targets and bind rules and Self-service password and profile ACIs.
| Requirement | Best control |
|---|---|
| Protect all simple password binds | nsslapd-require-secure-binds |
| Require minimum strength globally | nsslapd-minssf |
| Protect one operation or subtree | ACI ssf rule |
Test all authentication paths
Use this matrix after each policy change:
| Connection | Expected result |
|---|---|
| Plain LDAP simple password bind | Denied with Confidentiality required (13) when secure binds are on |
| STARTTLS simple bind | Allowed with valid credentials and CA trust |
| LDAPS simple bind | Allowed with valid credentials and CA trust |
| Anonymous bind | Controlled by nsslapd-allow-anonymous-access |
| Unauthenticated empty-password bind | Controlled by nsslapd-allow-unauthenticated-binds and anonymous policy |
| SASL mechanism below minimum SSF | SASL negotiation may begin, but the bind or subsequent operations are denied with Unwilling to perform (53) if the resulting SSF remains below the minimum |
| SASL mechanism meeting minimum SSF | Allowed |
| Root DSE over plain LDAP | Allowed when nsslapd-minssf-exclude-rootdse=on and the anonymous or root DSE access policy permits the query |
| LDAPI administration | Allowed when LDAPI authentication and authorization succeed and nsslapd-localssf meets the minimum |
| Replication | Must continue over LDAPS, STARTTLS, or appropriate SASL |
Run the tests with a normal directory account such as uid=user1, not only as Directory Manager.
Verify replication, chaining, and applications
After enforcement, confirm every server-to-server and application connection:
- Replication agreement status and supplier or consumer connectivity
- Chaining backend connections
- Synchronization and pass-through authentication
- Application login and scheduled jobs
- Monitoring probes
Check immediate failures and reconnect behaviour after existing sessions expire. Secure-bind enforcement applies to replication and chaining when those agreements use simple binds over plain LDAP. Update them to LDAPS or STARTTLS before you enable the policy.
Review logs for rejected connections
Inspect the instance logs:
grep -iE "minimum ssf|secure connection|confidentiality" /var/log/dirsrv/slapd-ldap1/access | tail -6Sample output:
[16/Jul/2026:07:46:43 +0530] conn=4 op=1 SRCH dn="cn=config" authzid="(null)", Minimum SSF not met
[16/Jul/2026:07:46:44 +0530] conn=5 op=1 SRCH dn="cn=config,cn=ldbm database,cn=plugins,cn=config" authzid="(null)", Minimum SSF not met
[16/Jul/2026:07:46:44 +0530] conn=5 op=2 MOD dn="cn=config" authzid="(null)", Minimum SSF not metAlso review /var/log/dirsrv/slapd-ldap1/errors and /var/log/dirsrv/slapd-ldap1/security for TLS handshake failures, failed replication binds, and rejected application connections. CA verification errors often appear on the client first; server logs are most useful for policy rejections and certificate-loading problems.
Troubleshoot secure-connection enforcement
| Symptom | Likely cause | Fix |
|---|---|---|
| Plain LDAP bind still succeeds | nsslapd-require-secure-binds is off or the instance was not restarted |
Set nsslapd-require-secure-binds=on; restart; confirm the bind uses a password |
| Anonymous search still succeeds | Secure binds do not control anonymous access | Review nsslapd-allow-anonymous-access and public ACIs in anonymous access |
| STARTTLS stops working after port 389 is disabled | STARTTLS requires the plain LDAP listener | Restore port 389 or move the client to LDAPS |
Client receives Confidentiality required |
Simple bind attempted without TLS | Use LDAPS or -ZZ; install the correct CA certificate |
Client receives Unwilling to perform with Minimum SSF not met |
Connection SSF is below nsslapd-minssf |
Use LDAPS, STARTTLS, or a stronger SASL mechanism; adjust policy if appropriate |
| Root DSE discovery fails | nsslapd-minssf-exclude-rootdse is off or anonymous access is blocked |
Enable the root DSE exception; review anonymous-access policy |
Local dsconf fails after enabling minimum SSF |
Plain ldap:// SSF is below the minimum; nsslapd-localssf is too low for LDAPI |
Raise nsslapd-localssf to at least the global minimum; use LDAPS, required STARTTLS, or LDAPI. The root DSE exception does not restore cn=config access over plain LDAP |
| Replication stops | Agreement uses plain LDAP or simple bind without TLS | Reconfigure the agreement for LDAPS, STARTTLS, or SASL before enforcing policy |
| Port 636 listens but wrong certificate is presented | nssslpersonalityssl points to the wrong nickname |
Run dsconf ldap1 security rsa get; set --nss-cert-name Server-Cert per TLS setup |
When LDAP result codes appear after a successful TLS handshake, continue diagnosis in fix LDAP error 50 for authorization failures.
Roll back safely
Restore secure-bind enforcement to the value you recorded before the change:
dsconf ldap1 config replace nsslapd-require-secure-binds=offSample output:
Successfully replaced value(s) for 'nsslapd-require-secure-binds': 'off'The following command restores this lab's initial SSF values. In production, substitute the values you recorded before the change:
dsconf ldap1 config replace nsslapd-minssf=0 nsslapd-minssf-exclude-rootdse=off nsslapd-localssf=71Sample output:
Successfully replaced value(s) for 'nsslapd-minssf': '0'
Successfully replaced value(s) for 'nsslapd-minssf-exclude-rootdse': 'off'
Successfully replaced value(s) for 'nsslapd-localssf': '71'Restart the instance after changing nsslapd-require-secure-binds or an LDAP listener port. SSF rollback is applied online and does not require a restart by itself.
Restore the normal LDAP port when you need STARTTLS or plain LDAP access again.
Repeat the connection checks from earlier in this guide after rollback. Do not leave enforcement disabled after fixing only one incompatible client. Migrate that client and re-enable the intended policy.
What's Next
- Client certificate authentication — certificate-based binds over LDAPS
- SASL GSSAPI and Kerberos — strong SASL mechanisms that satisfy SSF policy
- Anonymous access — separate anonymous search from bind security
References
- Red Hat Directory Server 13 — Securing RHDS
- Red Hat Directory Server 13 — Requiring a certain level of security in connections
- Red Hat Directory Server 13 — Core server configuration attributes
- 389 Directory Server — Howto: TLS/StartTLS
Summary
- Verify LDAPS, STARTTLS, and client CA trust before you enforce secure connections.
- Inventory applications and server-to-server connections that still use plain LDAP.
- Enable
nsslapd-require-secure-bindsto reject simple password authentication on unencrypted connections. - Keep port
389when clients require STARTTLS; disable it only for LDAPS-only deployments. - Set
nsslapd-minssftogether withnsslapd-minssf-exclude-rootdseand adequatensslapd-localssf. - Test permitted and rejected paths with a normal user, replication, and local administration.
- Roll back deliberately, fix incompatible clients, and re-enable the intended policy.

