OpenLDAP and MozNSS Compatibility Layer
Introduction
OpenLDAP in Fedora had been compiled with NSS (MozNSS, i.e. Mozilla Network Security Services) as a crypto library for several years. This effort was driven only by Fedora downstream and its derivatives. However, this implementation had not been optimal and for that it was later decided to move back to OpenSSL which is the preferred crypto library within OpenLDAP upstream community.
In order to make the transition to OpenSSL smoother for users of OpenLDAP it was decided to implement a mechanism which would allow to use NSS databases (which is the PKI store within NSS) while the actual crypto library used would be OpenSSL (which uses PEM files as a PKI store). This resulted in implementation of MozNSS Compatibility Layer (abbreviated TLSMC).
Lifespan
TLSMC is currently downstream only and it is currently not planned to spread it wider.
TLSMC has been introduced in Fedora 28 with an approval through a change proposal, before originally tracked in bugzilla, with openldap-2.4.45-4.fc28, at the same time compiling with OpenSSL instead of NSS.
Currently (2018-03-01), TLSMC is planned to be dropped in Fedora 29 which already does not contain it.
Building
In order to compile with TLSMC (given the patch is included) one has to run ./configure
with --enable-moznss-compatibility=yes
.
Configuration
One can control the runtime availability of TLSMC by setting the LDAP_OPT_X_TLS_MOZNSS_COMPATIBILITY
to either LDAP_OPT_X_TLS_MOZNSS_COMPATIBILITY_ENABLED
or LDAP_OPT_X_TLS_MOZNSS_COMPATIBILITY_DISABLED
(the default in Fedora 28 is to enable it). The respective userspace options take values yes
/true
/on
and no
/false
/off
, and are the following:
- ldap.conf(5) -
TLS_MOZNSS_COMPATIBILITY
- slapd.conf(5) -
TLSMozNSSCompatibility
- slapd-config(5) -
olcTLSMozNSSCompatibility
Behavior
TLSMC is a routine which is executed each time just before new TLS context is created internally (specificaly at the beginning of ldap_int_tls_init_ctx
). This routine tries to open an NSS database based on OpenLDAP's TLS_* parameters as it would do when built with NSS. If it succeeds to do so it tries to extract the user certificate, user private key, and CA certificates, then putting them in a uniquely created folder and setting the runtime TLS_* parameters to the values pointing to the newly created PEM files to be used by OpenSSL later on. If it fails to open the NSS database then it silently expects the configuration is in OpenSSL style. Finally, only OpenSSL continues to do its work.
Fingerprint data
In order to not extract the data from an NSS database every time the new TLS context is created the TLSMC creates a fingerprint of the state the current configuration represents. This fingerprint takes into account relevant TLS_* parameters, the effective UID of the POSIX user, and timestamps of the NSS database. These data represent the state which, when encountered next time, let the TLSMC know it does not have to extract the certificates again and that it can reuse the existent files if present. The fingerprint is stored in a README
file. A hash of the fingerprint is then included in the name of the base folder.
Extracted data structure
The extracted data structure looks for example like this:
/tmp/openldap-tlsmc-nssdb-nopass--6FCBA2496C72F8F233D1D9943450965BCAC06902131799DD62645BC60D420A2C/ ├── cacerts │ ├── cert0.pem │ └── ee8c0644.0 -> cert0.pem ├── cert.pem ├── key.pem └── README
The base directory is always located in the /tmp
folder and its name is built with the following template: openldap-tlsmc-<nss-db-dir-name>-<nss-db-prefix>-<fingerprint-hash>
. The cacerts
subdirectory contains extracted trusted CA certificates and follows the OpenSSL rehash format (see openssl-rehash(1)). The README
file contains unique data the fingerprint hash is created from. The rest of the files should be self-explanatory.
Permissions of the files are set so that only user that created them can actually access them. This should prevent private information leakage.
Known issues
Fail to configure TLS in cn=config with incosistent TLS setup
It has been noticed that when e. g. one tries to configure olcTLSCertificateFile with one change record and the olcTLSCertificateKeyFile with another change record, the slapd fails to set up a new TLS context in between the two operations. This is due to the difference in when the crypto libraries create new context: MozNSS does so effectively on a new connection, OpenSSL does so as soon as possible (e. g. at the slapd's startup or, here, when a change in configuration occurs). Therefore, it is recommended to change the setup in one change record, like so:
dn: cn=config changetype: modify replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/openldap/certs/server.crt.pem - replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/openldap/certs/server.key.pem