Emmanuel Dreyfus wrote:
For future reference, here is what I had to do to get multiple LDAP servers answering on the same DNS address and using TLS.
The DNS contains this records: srv1 IN A 192.0.2.4 srv2 IN A 192.0.2.5 ldap 1 IN A 192.0.2.4 ldap 1 IN A 192.0.2.5
The clients have this in ldap.conf: BASE dc=example,dc=net TLS_CACERT /etc/openssl/certs/ca.crt URI ldaps://ldap.example.net:636 TLS_REQCERT demand # Cannot get this working! #TLS_CRLCHECK peer
This only works with recent OpenSSL 0.9.8 releases. You didn't mention which version of OpenSSL you're using. And since this entire subject is purely an OpenSSL matter and not an LDAP matter, that's a pretty key piece of information.
In order to have this working, we need x509 certificate that have the subjectAltName extension. This is not an OpenLDAP-specific problem, but the information about how to do it seems difficult to find, hence, here is the result of my experiments.
The information is all at your fingertips. You just haven't absorbed it yet.
- Creating a CSR
On the LDAP servers, we need to setup OpenSSL for generating the certificate request (CSR). We need this in the [ req ] section of /etc/openssl/openssl.cnf: req_extensions = v3_req
The, we need a [ v3_req ] section: [ v3_req ] basicConstraints = CA:FALSE subjectAltName = "DNS:ldap.example.net, DNS:srv1.example.net"
It seems the subjectAltName has to be set in the config file. I found no way to have it prompted by the openssl command.
No, but you can obtain the value through an environment variable, to avoid having to re-edit the file all the time. Again, this is documented in the OpenSSL config file manpage. http://www.openssl.org/docs/apps/config.html#
e.g. setenv ALTNAME "DNS:ldap.example.net"
### subjectAltName=$ENV::ALTNAME ###
Also note "subject alternative name" means exactly that - it lists *alternative* names for the identity. You don't have to list the real name here, since that's already going into the subject CN. It does no harm, but it does no good either. (And it makes your cert bigger than it needs to be...)
If you don't have a private key yet, generate it: # ( umask 077; openssl genrsa > /etc/openssl/private/srv1.key )
Next, make the CSR: # openssl req -new -key /etc/openssl/private/srv1.key -out srv1.csr Answers to the questions openssl ask. The common name is srv1.example.net
Of course the same must be done on srv2
- Signing the certificate
On the machine that holds your certificate authority, some setup is also needed in openssl.cnf:
In the [ CA_default ] section (or in [ ca ]), copy_extensions = copy
Note that this will copy any extensions, so you have to be careful about what you are signing. See the WARNINGS section of openssl_ca.
Sign it (I assume your CA setup already work, here) # openssl ca -key /etc/openssl/private/ca.crt -in srv1.csr -out src1.crt # openssl ca -key /etc/openssl/private/ca.crt -in srv2.csr -out src2.crt
Typo there, src1.crt should be srv1.crt. Likewise for src2/srv2. Pay attention to what you're doing.
- Configuring slapd
Install ca.crt and srv1.crt (srv2.crt) on srv1 (srv2), and configure slapd, with this in slapd.conf: TLSCertificateFile /etc/openssl/certs/srv1.crt TLSCertificateKeyFile /etc/openssl/private/srv1.key TLSCACertificateFile /etc/openssl/certs/ca.crt TLSVerifyClient allow sasl-secprops none
Setting "sasl-secprops none" is never a good idea. Why did you put this here?
Then, restart slapd, and the thing should work.
- Having this working with syncrepl
An add-on: now let's imagine srv1 and srv2 are syncrepl-powered replica. The master is ldap0.example.net. In order to avoid pushing sensitive data to a rogue machine that would claim being a replica, we want to use client and server TLS certificate authentication for syncrepl exchange.
Note that on the consumer, the same certificate must be used for syncrepl and for the ldaps:// service. This is alimitation in OpenLDAP 2.3.x
4.1) On the syncrepl consumer (srv1 and srv2), in slapd.conf: syncrepl rid=24 type=refreshAndPersist searchbase="dc=example,dc=net" starttls=critical bindmethod=sasl saslmech=EXTERNAL retry=3,1,10,2,60,+
Make sure rid is different on srv1 and srv2.
As already noted by others, rid only needs to be unique within a single slapd configuration.
Don't forget to add entryUUID and entryCSN to the index of your databases (see http://www.openldap.org/doc/admin23/syncrepl.html#Configuring%20Syncrepl)
4.2) On the syncrepl producer (ldap0), in slapd.conf: TLSCertificateFile /etc/openssl/certs/ldao0.crt TLSCertificateKeyFile /etc/openssl/private/ldap0.crt TLSCACertificateFile /etc/openssl/certs/ca.crt TLSVerifyClient allow
# This allows login/password protected by TLS (for users) sasl-secprops none
No, that's not what it does. It turns off all security requirements in the SASL layer, allowing all insecure mechanisms to be used. A rather big mistake, after you've gone to the trouble of enabling secure authentication with certificates.