Configure TLS Versions and Cipher Suites in 389 Directory Server

Inspect and restrict TLS protocol versions and cipher suites in 389 Directory Server, test LDAPS and STARTTLS compatibility, and roll back safely.

Published

Updated

Read time 17 min read

Reviewed byDeepak Prasad

389 Directory Server TLS protocol and cipher suite configuration with LDAPS and STARTTLS compatibility testing

After LDAPS and STARTTLS are working, you can harden transport security by disabling obsolete TLS protocol versions, reviewing the cipher suites Directory Server negotiates, and applying a stricter policy when compliance or interoperability requirements demand it. The goal is stronger defaults without breaking LDAP clients, replication, chaining, or monitoring tools that still depend on specific protocol or cipher support.

This guide covers protocol and cipher inventory, minimum TLS version configuration, nsSSL3Ciphers patterns, operating-system crypto policy interaction, OpenSSL and ldapsearch verification, staged rollout, troubleshooting, and rollback.

Before you start:

IMPORTANT
This guide covers TLS protocol versions and cipher suites only. It does not install or renew certificates, require secure binds or minimum SSF, configure client-certificate authentication, or enable FIPS mode. Certificate work belongs in certificate management; bind enforcement belongs in require secure LDAP connections; FIPS enablement belongs in FIPS mode.

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. Instance ldap2 on ports 1389 and 1636 provides a second listener pair for non-default port tests. Commands that target ldap2 through dsconf use an explicit LDAP URL because local instance-name resolution can behave differently from ldap1.


Understand TLS protocols and cipher suites

A successful LDAPS or STARTTLS connection requires a shared TLS version and compatible cryptographic parameters. With TLS 1.2, the selected suite must match the server certificate authentication type, such as RSA or ECDSA. With TLS 1.3, cipher suites no longer encode the certificate or key-exchange type; compatible signature algorithms and key-exchange groups are negotiated separately.

Setting Controls
TLS protocol version The TLS generation used by the connection
Cipher suite See the TLS-version table below
Certificate key type Whether the server certificate uses RSA, ECDSA, or another supported key
System crypto policy Algorithms and protocols permitted by the operating system
Directory Server cipher configuration Additional cipher selection inside the instance through nsSSL3Ciphers
TLS version Cipher-suite meaning
TLS 1.2 and earlier Usually identifies key exchange, certificate authentication, bulk encryption, and message authentication
TLS 1.3 Identifies the AEAD encryption algorithm and HKDF hash; key exchange and certificate signature algorithms are negotiated separately

Directory Server stores protocol bounds in sslVersionMin and optionally sslVersionMax under cn=encryption,cn=config. Cipher policy is stored in nsSSL3Ciphers and can be influenced by allowWeakCipher.

A connection succeeds only when the client and server share a compatible protocol and negotiable cryptographic parameters. Changing only one side (an old Java LDAP client, a hardened server, or a stricter host crypto policy) can produce no shared cipher or protocol version errors even when the certificate itself is valid.


Check the current TLS configuration

Start by recording the protocol range Directory Server is configured to allow.

bash
dsconf ldap1 security get |
    grep -Ei 'sslVersionMin|sslVersionMax'

Sample output:

output
sslversionmin: TLS1.2
sslversionmax: TLS1.3

On this lab host, sslVersionMin is TLS1.2. The sslversionmax line shows the effective maximum; when sslVersionMax is not stored in dse.ldif, Directory Server can still report the strongest version supported by the installed NSS stack.

List the cipher suites currently enabled for this instance:

bash
dsconf ldap1 security ciphers list --enabled

Sample output:

output
TLS_AES_128_GCM_SHA256
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

The full enabled list in this lab contains twenty-two suites spanning TLS 1.2 and TLS 1.3. That list includes both TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 and TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 even though the active server certificate in this lab is RSA. The ECDSA suite is enabled in NSS configuration but is not negotiable for TLS 1.2 with that RSA certificate.

List every cipher the installed Directory Server and NSS versions support locally:

bash
dsconf ldap1 security ciphers list --supported

Sample output:

output
TLS_AES_128_GCM_SHA256
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA

Supported output in this lab lists seventy-one suites, including legacy algorithms that are not enabled by default.

Record the current nsSSL3Ciphers expression:

bash
dsconf ldap1 security ciphers list

Sample output:

output
default

default means the instance relies on the NSS default cipher policy unless you override nsSSL3Ciphers. Supported, default, and enabled lists can differ between operating-system and Directory Server releases. Always build policy from local output rather than copying another host.


Understand default, supported, and enabled ciphers

dsconf security ciphers list --enabled lists ciphers enabled by the server’s NSS cipher configuration. Actual negotiation still depends on protocol version, certificate and signature compatibility, client capabilities, and crypto policy. The CLI distinguishes configured, supported, enabled, and disabled lists but does not claim that every enabled cipher is usable in every handshake.

Term Meaning
Supported Known to the installed Directory Server and NSS build
Configured Selected by the current nsSSL3Ciphers expression
Enabled Enabled by the NSS and Directory Server cipher configuration after weak-cipher handling
Negotiable Enabled and compatible with the chosen TLS version, server certificate or signature algorithm, client offer, key-exchange groups, and system crypto policy
Disabled Supported but not currently enabled by the instance policy
Weak/insecure Cipher requires explicit insecure-cipher allowance through allowWeakCipher

Directory Server applies nsSSL3Ciphers using NSS cipher-spec patterns:

text
default
-all,+CIPHER_NAME
default,-CIPHER_NAME

Use default when the NSS default set is acceptable. Use -all,+CIPHER_NAME when you need an explicit allow-list. Prefix with default, when you want to start from NSS defaults and remove individual suites.

Do not copy a cipher list from another server without first checking dsconf INSTANCE security ciphers list --supported on the target host. An RSA server certificate cannot negotiate an ECDSA-authenticated TLS 1.2 suite such as TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384. TLS 1.3 uses separate signature-algorithm negotiation, so its short cipher names do not indicate RSA or ECDSA. A restricted allow-list that omits all TLS 1.3 suites disables TLS 1.3 even when the protocol version permits it.


Set the minimum TLS version

Raise the minimum TLS version when every client, replication peer, and monitoring tool in your environment supports the newer protocol.

I'll require TLS 1.2 or newer:

bash
dsconf ldap1 security set --tls-protocol-min="TLS1.2"

For an environment where every client supports TLS 1.3:

bash
dsconf ldap1 security set --tls-protocol-min="TLS1.3"

Sample output:

output
Successfully updated security configuration (nsSSL3Ciphers)

On the tested build, dsconf printed nsSSL3Ciphers even though this command changed sslVersionMin. Treat this as a CLI reporting issue rather than proof that the cipher expression changed. Verify the stored and effective protocol values with dsconf security get after the restart.

Restart the instance so the listener loads the new protocol bounds:

bash
dsctl ldap1 restart

Verify the stored values:

bash
dsconf ldap1 security get |
    grep -Ei 'sslVersionMin|sslVersionMax'

Sample output after setting the minimum to TLS 1.3 in the lab:

output
sslversionmin: TLS1.3
sslversionmax: TLS1.3

When the minimum is TLS 1.3, a TLS 1.2-only client receives a protocol-version alert:

bash
openssl s_client \
    -connect ldap1.example.com:636 \
    -servername ldap1.example.com \
    -tls1_2 </dev/null 2>&1 |
    grep -E 'Protocol|alert|Cipher'

Sample output:

output
40F748C9E47F0000:error:0A00042E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:ssl/record/rec_layer_s3.c:918:SSL alert number 70
Protocol: TLSv1.2
New, (NONE), Cipher is (NONE)

TLS 1.3-only configuration can break older LDAP libraries, replication peers, monitoring tools, and Java runtimes. Inventory clients before you raise the minimum, test in a non-production instance first, and roll back if any dependency still requires TLS 1.2.

Restore TLS 1.2 as the minimum before continuing the lab guide:

bash
dsconf ldap1 security set --tls-protocol-min="TLS1.2"

I restart the instance so the restored minimum takes effect:

bash
dsctl ldap1 restart

Leave the maximum TLS version unset

The normal production policy is:

text
Minimum TLS version: explicitly configured
Maximum TLS version: unset

When sslVersionMax is not set in cn=encryption,cn=config, Directory Server can adopt newer protocols supported by the server and client after software upgrades. Red Hat explicitly warns that setting a maximum can force clients to negotiate a weaker protocol than their default standard.

Inspect whether a maximum is currently configured:

bash
dsconf ldap1 security get |
    grep -Ei 'sslVersionMin|sslVersionMax'

I also check whether sslVersionMax is stored directly in dse.ldif:

bash
grep -i 'sslVersionMax' /etc/dirsrv/slapd-ldap1/dse.ldif

If dse.ldif contains an sslVersionMax line you no longer need, remove it while planning a controlled maintenance window. One supported method is an online modify of cn=encryption,cn=config:

bash
ldapmodify -x -H ldaps://ldap1.example.com:636 \
    -D "cn=Directory Manager" -y /root/dm.pw <<'EOF'
dn: cn=encryption,cn=config
changetype: modify
delete: sslVersionMax
EOF

Restart the instance after changing TLS protocol bounds:

bash
dsctl ldap1 restart

Verify both the stored configuration and the effective values:

bash
grep -i 'sslVersionMax' /etc/dirsrv/slapd-ldap1/dse.ldif

No output means the maximum is not explicitly stored in dse.ldif.

bash
dsconf ldap1 security get |
    grep -Ei 'sslVersionMin|sslVersionMax'

dsconf security get can still display the effective NSS maximum even when sslVersionMax is absent from dse.ldif.

Set a maximum only temporarily when you are troubleshooting a client defect, reproducing a protocol-specific problem, or meeting a narrowly defined compatibility requirement. Document the exception, retest after the client is upgraded, and remove the restriction.


Configure the enabled cipher suites

Save the current configuration before you restrict ciphers:

bash
dsconf ldap1 security ciphers list

Sample output:

output
default

I save the enabled cipher list to a file so I can compare it after changes:

bash
dsconf ldap1 security ciphers list --enabled > /root/ldap1-ciphers-enabled-before.txt

To replace the enabled set with one explicit TLS 1.2 suite, use the -- separator so the shell does not treat -all as a dsconf option:

bash
dsconf ldap1 security ciphers set -- "-all,+TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"

Sample output:

output
Remember to restart the server to apply the new cipher set.
Some ciphers may be disabled anyway due to allowWeakCipher attribute.

Confirm the stored expression:

bash
dsconf ldap1 security ciphers get

Sample output:

output
-all,+TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

Restart and list enabled suites:

bash
dsctl ldap1 restart

After the restart, I confirm only the selected suite remains enabled:

bash
dsconf ldap1 security ciphers list --enabled

Sample output:

output
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

After restart, only the selected TLS 1.2 suite is enabled. TLS 1.3 handshakes fail until you also allow TLS 1.3 cipher suites or return to default.

For multiple suites:

bash
dsconf ldap1 security ciphers set -- "-all,+CIPHER_1,+CIPHER_2,+CIPHER_3"

Build every allow-list from:

  • The locally supported ciphers
  • Server certificate key type
  • Client compatibility
  • Organizational security policy
  • Operating-system crypto policy
  • FIPS requirements where applicable

Do not publish one universal “best cipher list.” Available ciphers change with Directory Server, NSS, and operating-system updates.

Restore the NSS default policy before you continue:

bash
dsconf ldap1 security ciphers set -- "default"

I restart the instance so the listener reloads the default cipher set:

bash
dsctl ldap1 restart

Understand weak and insecure ciphers

Check whether insecure ciphers are allowed:

bash
dsconf ldap1 security get |
    grep -i allowWeakCipher

Sample output:

output
allowweakcipher:

An empty value means weak ciphers are not explicitly allowed. Legacy suites such as TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA can still appear in --supported output but remain disabled unless you change policy.

Where a temporary legacy exception is unavoidable:

bash
dsconf ldap1 security set --allow-insecure-ciphers=on

Allowing weak ciphers does not by itself enable a legacy suite. Select the exact cipher in nsSSL3Ciphers, restart the instance, and confirm that it appears in the enabled list:

bash
dsconf ldap1 security ciphers set -- "-all,+REQUIRED_LEGACY_CIPHER"

I restart the instance because cipher changes load only after a restart:

bash
dsctl ldap1 restart

I confirm the legacy suite now appears in the enabled list:

bash
dsconf ldap1 security ciphers list --enabled |
    grep -F 'REQUIRED_LEGACY_CIPHER'

Replace REQUIRED_LEGACY_CIPHER with the exact NSS name from dsconf ldap1 security ciphers list --supported, such as TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA.

Enabling allowWeakCipher does not override the operating-system crypto policy. A cipher rejected by the host policy can remain unavailable even after you select it in nsSSL3Ciphers.

This is not part of a recommended production baseline. Before enabling a legacy cipher:

  1. Identify the exact incompatible client.
  2. Confirm that upgrading the client is not immediately possible.
  3. Enable only the minimum required cipher.
  4. Document the exception.
  5. Set a removal date.
  6. Retest after the client is upgraded.

Do not enable every supported cipher or switch the entire host to the LEGACY crypto policy merely to support one old LDAP client.

Roll back a temporary weak-cipher exception with:

bash
dsconf ldap1 security set --allow-insecure-ciphers=off

I restore the default cipher expression next:

bash
dsconf ldap1 security ciphers set -- "default"

I restart so both settings take effect on the listener:

bash
dsctl ldap1 restart

Check operating-system crypto policies

On Red Hat Enterprise Linux, Rocky Linux, AlmaLinux, and other distributions that ship crypto-policies, inspect the active profile:

bash
update-crypto-policies --show

Sample output:

output
DEFAULT

The system crypto policy can further constrain Directory Server protocol and cipher settings. Instance configuration can usually make the policy stricter, but it cannot re-enable algorithms the operating system rejects. Common profiles include DEFAULT, LEGACY, FUTURE, and FIPS.

On older RHEL-family releases, LEGACY could lower the system TLS floor. RHDS 13 on RHEL 10 documents TLS 1.2 as the minimum for all standard profiles, including LEGACY. Do not expect update-crypto-policies --set LEGACY to restore TLS 1.0 on the tested platform.

Treat crypto-policy commands as a distribution-specific compatibility section. Ubuntu, Debian, and other distributions without the RHEL system-wide crypto-policy framework use different mechanisms; compare your distribution documentation before you assume update-crypto-policies exists.

When a cipher appears in dsconf security ciphers list --supported but not in --enabled, check both nsSSL3Ciphers and the host crypto policy before you weaken the server.


Test TLS protocol versions

The following commands isolate protocol and cipher negotiation with OpenSSL. They do not by themselves prove that the certificate chain is trusted. openssl s_client can continue after certificate-verification errors unless -verify_return_error is supplied, and the grep filters remove verification details. Run a verified handshake before and after changing policy.

Establish a verified LDAPS baseline:

bash
openssl s_client \
    -connect ldap1.example.com:636 \
    -servername ldap1.example.com \
    -verify_hostname ldap1.example.com \
    -verify_return_error \
    -CAfile /root/example-ca-chain.pem \
    </dev/null

Sample output near the end:

output
Verify return code: 0 (ok)

Verify STARTTLS the same way:

bash
openssl s_client \
    -starttls ldap \
    -connect ldap1.example.com:389 \
    -servername ldap1.example.com \
    -verify_hostname ldap1.example.com \
    -verify_return_error \
    -CAfile /root/example-ca-chain.pem \
    </dev/null

Sample output near the end:

output
Verify return code: 0 (ok)

For a lab that still uses the dscreate host SSCA, /etc/dirsrv/ssca/ca.crt can validate the listener instead of /root/example-ca-chain.pem. After importing or renewing through another CA, use the CA bundle that validates the certificate currently presented by the listener.

Test LDAPS with TLS 1.2:

bash
openssl s_client \
    -connect ldap1.example.com:636 \
    -servername ldap1.example.com \
    -tls1_2 </dev/null 2>&1 |
    grep -E 'Protocol|Cipher'

Sample output:

output
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Protocol: TLSv1.2
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256

Test TLS 1.3:

bash
openssl s_client \
    -connect ldap1.example.com:636 \
    -servername ldap1.example.com \
    -tls1_3 </dev/null 2>&1 |
    grep -E 'Protocol|Cipher'

Sample output:

output
New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
Protocol: TLSv1.3

Test STARTTLS on the plain LDAP port:

bash
openssl s_client \
    -connect ldap1.example.com:389 \
    -starttls ldap \
    -servername ldap1.example.com \
    -tls1_2 </dev/null 2>&1 |
    grep -E 'Protocol|Cipher|STARTTLS'

Sample output:

output
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Protocol: TLSv1.2
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256

Repeat the same tests against the second instance on its non-default secure port when you need to confirm listener-specific behavior:

bash
openssl s_client \
    -connect ldap2.example.com:1636 \
    -servername ldap2.example.com \
    -tls1_2 </dev/null 2>&1 |
    grep -E 'Protocol|Cipher'

Check the negotiated TLS version, cipher, certificate verification result, handshake alerts, and whether a disabled protocol correctly fails.


Test specific cipher suites

For TLS 1.2, force one cipher:

bash
openssl s_client \
    -connect ldap1.example.com:636 \
    -servername ldap1.example.com \
    -tls1_2 \
    -cipher 'ECDHE-RSA-AES256-GCM-SHA384' </dev/null 2>&1 |
    grep -E 'Protocol|Cipher|handshake failure|alert'

Sample output when the suite is allowed:

output
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Protocol: TLSv1.2
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384

When the suite is disabled, OpenSSL reports a handshake failure:

output
SSL alert number 40
New, (NONE), Cipher is (NONE)
Protocol: TLSv1.2

For TLS 1.3, use the OpenSSL option supported by your client version:

bash
openssl s_client \
    -connect ldap1.example.com:636 \
    -servername ldap1.example.com \
    -tls1_3 \
    -ciphersuites 'TLS_AES_128_GCM_SHA256' </dev/null 2>&1 |
    grep -E 'Protocol|Cipher'

Sample output:

output
New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
Protocol: TLSv1.3

OpenSSL cipher names are not always identical to the NSS names displayed by dsconf security ciphers list. Map between them by testing one suite at a time.

Verify both LDAPS on port 636 and STARTTLS on port 389 after every change.


Test LDAP clients and server-to-server connections

OpenSSL confirms the handshake. Applications still need real binds and searches.

bash
export LDAPTLS_CACERT=/root/example-ca-chain.pem

For a lab that still uses the dscreate host SSCA, /etc/dirsrv/ssca/ca.crt can be used instead. After importing or renewing through another CA, use the CA bundle that validates the certificate currently presented by the listener.

Test LDAPS with ldapsearch after you set client CA trust:

bash
ldapsearch -x -H ldaps://ldap1.example.com:636 \
    -D "cn=Directory Manager" -y /root/dm.pw \
    -b "" -s base "(objectClass=*)" namingContexts

Sample output near the end:

output
result: 0 Success

# numResponses: 2
# numEntries: 1

Test STARTTLS:

bash
ldapsearch -x -ZZ -H ldap://ldap1.example.com:389 \
    -D "cn=Directory Manager" -y /root/dm.pw \
    -b "" -s base "(objectClass=*)" namingContexts

Sample output near the end:

output
result: 0 Success

# numResponses: 2
# numEntries: 1

Use a compatibility matrix during staged rollout:

Client or connection TLS 1.2 TLS 1.3 Approved cipher Result
OpenLDAP tools Test Test Test Pass/fail
Application LDAP library Test Test Test Pass/fail
Java application Test Test Test Pass/fail
Replication peer Test Test Test Pass/fail
Chaining backend Test Test Test Pass/fail
Monitoring probe Test Test Test Pass/fail

Record pass/fail for each row before you remove the previous configuration.


Apply a staged cipher-policy change

  1. Record the current protocol and cipher configuration.
  2. Inventory all LDAP clients and server-to-server connections.
  3. Test the proposed policy in a non-production instance such as ldap2.
  4. Change the minimum TLS version first.
  5. Test all clients.
  6. Apply cipher restrictions separately.
  7. Restart and verify both LDAPS and STARTTLS.
  8. Monitor connection failures before you delete the saved rollback files.

Avoid changing TLS version, ciphers, certificates, and secure-bind enforcement in the same maintenance window. Each layer has different rollback steps and failure modes.


Troubleshoot TLS and cipher failures

Symptom Likely cause Fix
no shared cipher Client and server enabled-cipher lists do not overlap, or TLS 1.2 certificate authentication, TLS 1.3 signature algorithms, or key-exchange groups are incompatible Compare dsconf security ciphers list --enabled with the client; confirm TLS version, certificate or signature compatibility, supported groups, and OS crypto policy
protocol version or unsupported protocol Client maximum is below sslVersionMin Lower the minimum temporarily in a test instance or upgrade the client
TLS 1.3 test fails but TLS 1.2 works TLS 1.3 ciphers disabled, NSS build, or crypto policy Restore default ciphers; confirm OpenSSL and system policy allow TLS 1.3
Cipher appears configured but is not enabled Unsupported locally, weak, or rejected by crypto policy Run --supported and --enabled; restart after ciphers set
LDAPS works but STARTTLS fails Different port policy, middlebox, or stale client cache Test both ports with the same OpenSSL options; compare listener settings
Replication fails after cipher hardening Supplier and consumer support different suites Align protocol and cipher policy on every replica
Java or legacy application stops connecting Runtime TLS support below server minimum Upgrade the runtime or test a temporary minimum-version exception in a lab instance

Roll back safely

Restore the previous cipher expression:

bash
dsconf ldap1 security ciphers set -- "default"

That returns nsSSL3Ciphers to the NSS default policy. Or replace default with the saved value from dsconf ldap1 security ciphers get.

Restore the previous minimum protocol:

bash
dsconf ldap1 security set --tls-protocol-min="TLS1.2"

That command returns the instance to TLS 1.2 as the minimum when you are undoing a temporary hardening change.

If you enabled a temporary weak-cipher exception, restore it as well:

bash
dsconf ldap1 security set --allow-insecure-ciphers=off

That turns off explicit weak-cipher allowance before you return to the default cipher set.

Remove an unnecessary sslVersionMax restriction from cn=encryption,cn=config when you no longer need a temporary maximum.

I restart the instance after restoring protocol and cipher settings:

bash
dsctl ldap1 restart

Repeat LDAPS, STARTTLS, application, and replication tests. Confirm enabled ciphers match the pre-change inventory before you close the change ticket.


What's Next


References


Summary

  1. Inventory current protocols with dsconf security get and enabled ciphers with dsconf security ciphers list --enabled.
  2. Distinguish enabled ciphers from negotiable ciphers that match the TLS version, certificate, client, and crypto policy.
  3. Set an appropriate minimum TLS version and restart the instance.
  4. Normally leave the maximum TLS version unset.
  5. Use NSS default ciphers unless a stricter policy is required.
  6. Build custom allow-lists from local --supported output, not from another host.
  7. Test verified LDAPS and STARTTLS handshakes, then application and replication traffic after every change.

Frequently Asked Questions

1. Should I set a maximum TLS version in 389 Directory Server?

Normally no. Red Hat and upstream guidance recommend leaving sslVersionMax unset so Directory Server can negotiate the strongest protocol supported by both the server NSS stack and the client. Set a maximum only for temporary troubleshooting, then remove the restriction and restart.

2. What is the difference between supported and enabled cipher suites?

Supported ciphers are known to the installed Directory Server and NSS build. Enabled ciphers are enabled by the instance NSS policy after nsSSL3Ciphers and allowWeakCipher are applied. An enabled cipher is not guaranteed to negotiate: the TLS version, server certificate or signature algorithm, client offer, key-exchange groups, and operating-system crypto policy must also be compatible.

3. Do I need to restart after changing TLS ciphers or protocol versions?

Yes. dsconf reminds you to restart after cipher changes, and protocol version updates take effect after dsctl INSTANCE restart. Test LDAPS and STARTTLS on both the secure port and the plain LDAP port after every change.

4. Why does OpenSSL report no shared cipher for LDAPS?

The client and server enabled-cipher lists may not overlap, the TLS 1.2 certificate authentication type may not match the suite, TLS 1.3 signature-algorithm compatibility may fail, supported key-exchange groups may differ, sslVersionMin may block the client, or the host crypto policy may reject the algorithm. Compare dsconf security ciphers list --enabled with the client and test one cipher at a time with openssl s_client.

5. Does the system crypto policy override Directory Server cipher settings?

On RHEL-family systems, the system-wide crypto policy can further restrict the protocols, algorithms, key sizes, and signatures available to Directory Server. Instance settings can normally make the policy stricter, but cannot re-enable an algorithm that the operating-system policy rejects. On RHEL 10, every standard crypto-policy profile sets TLS 1.2 as the minimum.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …