This commit is contained in:
		
					parent
					
						
							
								b3d2cddb33
							
						
					
				
			
			
				commit
				
					
						ba3b32a0c7
					
				
			
		
					 1 changed files with 143 additions and 0 deletions
				
			
		|  | @ -0,0 +1,143 @@ | ||||||
|  | --- | ||||||
|  | categories: | ||||||
|  | - General | ||||||
|  | - openSUSE | ||||||
|  | comments: true | ||||||
|  | date: '2021-10-22 21:04:52+02:00' | ||||||
|  | disable_share: true | ||||||
|  | draft: false | ||||||
|  | featured_image: /images/banner.jpg | ||||||
|  | omit_header_text: true | ||||||
|  | tags: | ||||||
|  | - opensuse | ||||||
|  | - ldap | ||||||
|  | - 389-ds | ||||||
|  | title: Setting up Let's Encrypt certificates for the 389-ds LDAP server | ||||||
|  | --- | ||||||
|  | 
 | ||||||
|  | In the past months I've set up LDAP at home, to avoid having different user accounts for the services that I run on my home hardware. Rather than the venerable [OpenLDAP](https://www.openldap.org/) I settled for [389 Directory Server](https://directory.fedoraproject.org/), commercially known as Red Hat Directory Server, mainly because I was more familiar with it. Rather than describing how to set that up ([Red Hat's own documentation](https://access.redhat.com/documentation/en-us/red_hat_directory_server/11/html/administration_guide/index) is excellent on that regard), this post will focus on the steps required to enable encryption using [Let's Encrypt](https://letsencrypt.org) certificates. | ||||||
|  | 
 | ||||||
|  | ## The problem | ||||||
|  | 
 | ||||||
|  | Even the LDAP server (they're actually two, but for the purpose of this post it does not matter) was just operating in my LAN, I wanted to reduce the amount of information going around in clear, including LDAP queries. That meant setting up encryption, of course. | ||||||
|  | 
 | ||||||
|  | The problem was that Red Hat's docs only cover the "traditional" way of obtaining certificates, that is obtaining a Certificate Authority (CA) certificate, request a server certificate, obtain it and set it up in the server. There is (obviously) no mention of Let's Encrypt *anywhere*. I've found [some](https://gist.github.com/plembo/e69720a116f06c3b73452d4e0a9da0e0) [guides](https://possiblelossofprecision.net/?p=2586), but they were either too complicated (lots of fuzzing around with `certutil`) or they weren't clear for some steps. Hence, this post. | ||||||
|  | 
 | ||||||
|  | **NOTE**: I've focused on 389-ds version 2.0 and above, which has a different CLI set of commands than the venerable 1.3 series. All of the steps shown here can also be carried out via the [Cockpit](https://cockpit-project.org) Web interface as well, if your distribution carries it (spoiler: openSUSE doesn't). | ||||||
|  | 
 | ||||||
|  | ## Importing the CA | ||||||
|  | 
 | ||||||
|  | This is arguably one of the most important steps of the process. 389-ds needs also to store the CA for your certificates. As you may (or may not) know, Let's Encrypt's CA certificates are two: | ||||||
|  | 
 | ||||||
|  | - The actual "root" certificate, by Internet Security Research Group (ISRG); | ||||||
|  | - An intermediate certificate, signed by the above root, called "R3". | ||||||
|  | 
 | ||||||
|  | Let's Encrypt certificates, like the one powering this website, are signed by R3. But since you have to follow a "chain of trust", to validate the certificate you follow these steps (excuse me, security people; this is probably a bad semplification): | ||||||
|  | 
 | ||||||
|  | 1. Check the actual certificate (e.g. the one on dennogumi.org) | ||||||
|  | 2. The certificate is signed by "R3", so move up the chain and check the R3 certificate | ||||||
|  | 3. The R3 certificate is signed by the ISRG root certificate, so move up the chain and check the ISRG root | ||||||
|  | 4. The ISRG certificate is trusted by the OS / application using it, so everything stops there. | ||||||
|  | 
 | ||||||
|  | If any of the steps fails, the whole validation fails. | ||||||
|  | 
 | ||||||
|  | This long winding explanation is to tell you that 389-ds needs the *whole certificate chain* for its CA (so ISRG root + R3) in order to properly validate the Let's Encrypt certificate you'll use. If you don't do that, chances are that some software which uses the system CA will work (for example `ldapsearch`) but others, like SSSD will fail with "Unknown CA" errors (buried deep into debug logs, so at the practical level they'll just fail and you won't know why). | ||||||
|  | 
 | ||||||
|  | Let's get to business. Access [the Chain of Trust page](https://letsencrypt.org/certificates/) for Let's Encrypt and download the relevant certificates. I'm not sure if 389-ds supports ECDSA certificates, so I downloaded the RSA ones: ISRG Root X1 and Let's Encrypt R3 (both in PEM format). Put them somewhere in your server. Then, as root, import the two CA certificates into 389-ds (substitute `LDAP_ADDRESS` with the LDAP URI of your server): | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | # ISRG Root | ||||||
|  | 
 | ||||||
|  | dsconf -v -D "cn=Directory Manager"  LDAP_ADDRESS security ca-certificate \ | ||||||
|  |     add --file /path/to/certificate --name "ISRG" | ||||||
|  | 
 | ||||||
|  | # Let's Encrypt R3 | ||||||
|  | 
 | ||||||
|  | dsconf -v -D "cn=Directory Manager"  LDAP_ADDRESS security ca-certificate \ | ||||||
|  |     add --file /path/to/certificate --name "R3" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | **NOTE**: This step may not be necessary if you use Let's Encrypt's "full chain" certificates, but I did not test that. | ||||||
|  | 
 | ||||||
|  | ## Importing the certificates | ||||||
|  | 
 | ||||||
|  | Then, you have to import a Let's Encrypt certificate, which means you have to obtain one. There are hundreds of guides and clients that can do the job nicely, so I won't cover that part. If you use `certbot`, Let's Encrypt's official client, you will have the certificate and the private key for it in `/etc/letsencrypt/live/YOURDOMAIN/fullchain.pem` and `/etc/letsencrypt/live/YOURDOMAIN/privkey.pem`. | ||||||
|  | 
 | ||||||
|  | You need to import the private key first (substitute `LDAP_ADDRESS` and `DOMAIN` with the LDAP URI of your server and the Let's Encrypt domain, respectively): | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | dsctl LDAP_ADDRESS tls import-server-key-cert \ | ||||||
|  |     /etc/letsencrypt/live/DOMAIN/fullchain.pem \ | ||||||
|  |         /etc/letsencrypt/live/DOMAIN/privkey.pem | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Note that you pass the certificate as well as the key to import it (in doubt, [check's Red Hat documentation](https://access.redhat.com/documentation/en-us/red_hat_directory_server/11/html/administration_guide/managing_the_nss_database_used_by_directory_server#installing_a_server_certiticate_using_the_command_line)). | ||||||
|  | 
 | ||||||
|  | Once the key is done, it is time to import the actual certificate: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | dsconf -v -D "cn=Directory Manager" LDAP_ADDRESS security certificate add \ | ||||||
|  |     --file /etc/letsencrypt/live/DOMAIN/fullchain.pem \ | ||||||
|  |         --primary-cert \ | ||||||
|  |         --name "LE" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | `--primary-cert` sets the certificate as the server's primary certificate. | ||||||
|  | 
 | ||||||
|  | Then, we switch on TLS in the server: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | dsconf -v -D "cn=Directory Manager" LDAP_ADDRESS config replace \ | ||||||
|  | 	nsslapd-securePort=636 nsslapd-security=on | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | And finally, we restart our instance (replace `INSTANCE` with your configured instance name): | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | systemctl restart dirsrv@INSTANCE | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Testing everything out | ||||||
|  | 
 | ||||||
|  | You can use `ldapsearch` to check whether the SSL connection is OK (I've used `Directory Manager`, but you can use any user you want): | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | # STARTTLS | ||||||
|  | 
 | ||||||
|  | ldapsearch -H ldap://your.ldap.hostname -W -x -D "cn=Directory Manager" -ZZ "search filter here" | ||||||
|  | 
 | ||||||
|  | # TLS | ||||||
|  | 
 | ||||||
|  | ldapsearch -H ldaps://your.ldap.hostname -W -x -D "cn=Directory Manager" "search filter here" | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | If everything is OK, you should get a result: otherwise, you'll get an error like "Can't contact the LDAP server". | ||||||
|  | 
 | ||||||
|  | Alternatively, you can use `openssl`: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | openssl s_client -connect your.ldap.hostname:636 | ||||||
|  | [...] | ||||||
|  | --- | ||||||
|  | SSL handshake has read 5188 bytes and written 438 bytes | ||||||
|  | Verification: OK | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Don't forget to adjust your applications to connect via `ldaps` rather than `ldap` after everything is done. | ||||||
|  | 
 | ||||||
|  | ## Renewing the certificates | ||||||
|  | 
 | ||||||
|  | To renew the certificates you repeat the steps outlined above for the certificates (without the CA part, of course). Make sure you always import your private key: if there is a mismatch between it and the certificate, 389-ds will refuse to start. | ||||||
|  | 
 | ||||||
|  | If you use `certbot` you can use a post-renewal hook to trigger the import of the certificate into 389-ds. [This is what I've been using](https://git.dennogumi.org/einar/scripts/src/branch/master/sysadmin/le_lan_reload_services.sh): bear in mind it's customized to my setup and does a few more things than needed. Also it does only import the certificate, and not the full chain. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## I messed up and 389-ds won't start! What do I do? | ||||||
|  | 
 | ||||||
|  | You can disable encryption by editing `/etc/dirsrv/slapd-INSTANCE/dse.ldif` and changing `nsslapd-security` to `off`, then start 389-ds again. Then you can review everything and see what went wrong. But if you can, I recommend the Cockpit Web UI: it makes the first-time setup a breeze. | ||||||
|  | 
 | ||||||
|  | ## Wrap up | ||||||
|  | 
 | ||||||
|  | Importing the certificates is surprisingly simple, but my Internet searches have been frustrating because at least half of what I found was either not applicable, incomplete, or did not work. I hope this small tutorial can be useful for those who want a bit more security in their LDAP setup. | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue