docker-openldap
docker-openldap copied to clipboard
TLS with LetsEncrypt
Has anyone been able to get LetsEncrypt certs to work properly with this?
I have mapped my certs to the cert.pem, and key.pem however there doesn't seem to be a proper CA.crt that I can use. My LDAP Client (JXplorer) states that it cannot authenticate because the CA certificate is missing from the chain.
I have tried copying fullchain.pem to ca.crt along with other steps I've found on the web, but no success. Hopefully someone has encountered this issue and knows how to resolve?
This image (letsencrypt-nginx-proxy-companion) (despite its name) can be used for anything afaik. It creates certs in the volume or bind mount you specified and creates certificates for all the
containers you specified the env variables LETSENCRYPT_HOST
and LETSENCRYPT_EMAIL
for.
I havent tried it with ldap yet (am about to test it out though), but it creates certs in the following formats: .chain.pem
, .crt
, dhparam.pem
and .key
. It SHOULD work, if not, you can always fork and adjust from their github.
I would love it if you could write an answer comment here if you get it to work, or even create a PR to adjust the readme and add a "using letsencrypt certificates" section <3
Hi, We're using the letsencrypt-nginx-proxy-companion as well. So far, so such luck with getting the certificates to work, due to chain issues. Interested to hear how you make out.
I tried to use let's encrypt certs to securise my server. Everytime I launch the container, the certificates aren't recognized and are overwrited by the defaults self-signed certs. I don't know what I'm doing wrong here.
Symbolics links to the certificates are in the mounted folder /letsencrypt/live/ldap.domain.com
, certificates themselves are in the /letsencrypt/archive/ldap.domain.com
folder. LDAP is configured according to the arch linux wiki recommendations.
I'm using the --copy-service
command according to issue 59.
docker-compose.yaml
version: '2'
services:
openldap:
image: osixia/openldap:1.1.8
container_name: openldap
hostname: "ldap.domain.com"
command: ["--copy-service"]
restart: always
environment:
LDAP_ORGANISATION: domain
LDAP_DOMAIN: domain.com
LDAP_BASE_DN: dc=domain,dc=com
LDAP_ADMIN_PASSWORD: password
LDAP_CONFIG_PASSWORD: password
LDAP_READONLY_USER: "false"
LDAP_BACKEND: mdb
LDAP_TLS: "true"
LDAP_TLS_CRT_FILENAME: cert.pem
LDAP_TLS_KEY_FILENAME: privkey.pem
LDAP_TLS_CA_CRT_FILENAME: chain.pem
LDAP_TLS_ENFORCE: "true"
LDAP_TLS_CIPHER_SUITE: NORMAL:SECURE256:-VERS-SSL3.0
LDAP_TLS_VERIFY_CLIENT: never
LDAP_REPLICATION: "false"
LDAP_REMOVE_CONFIG_AFTER_SETUP: "true"
LDAP_SSL_HELPER_PREFIX: ldap
tty: true
stdin_open: true
volumes:
- ./ldap:/var/lib/ldap
- ./slapd.d:/etc/ldap/slapd.d
- ./letsencrypt/live/ldap.domain.com:/container/service/slapd/assets/certs
ports:
- "389:389"
- "636:636"
log of the container
*** CONTAINER_LOG_LEVEL = 3 (info)
*** Copy /container/service to /container/run/service
*** Killing all processes...
Traceback (most recent call last):
File "/container/tool/run", line 889, in <module>
main(args)
File "/container/tool/run", line 774, in main
setup_run_directories(args)
File "/container/tool/run", line 375, in setup_run_directories
copy_service_to_run_dir()
File "/container/tool/run", line 441, in copy_service_to_run_dir
shutil.copytree(IMPORT_SERVICE_DIR, RUN_SERVICE_DIR)
File "/usr/lib/python2.7/shutil.py", line 208, in copytree
raise Error, errors
shutil.Error: [('/container/service/slapd/assets/certs/chain.pem', '/container/run/service/slapd/assets/certs/chain.pem', "[Errno 2] No such file or directory: '/container/service/slapd/assets/certs/chain.pem'"), ('/container/service/slapd/assets/certs/privkey.pem', '/container/run/service/slapd/assets/certs/privkey.pem', "[Errno 2] No such file or directory: '/container/service/slapd/assets/certs/privkey.pem'"), ('/container/service/slapd/assets/certs/fullchain.pem', '/container/run/service/slapd/assets/certs/fullchain.pem', "[Errno 2] No such file or directory: '/container/service/slapd/assets/certs/fullchain.pem'"), ('/container/service/slapd/assets/certs/cert.pem', '/container/run/service/slapd/assets/certs/cert.pem', "[Errno 2] No such file or directory: '/container/service/slapd/assets/certs/cert.pem'")]
*** CONTAINER_LOG_LEVEL = 3 (info)
*** Copy /container/service to /container/run/service ignored
*** /container/run/service already exists
*** Search service in CONTAINER_SERVICE_DIR = /container/service :
*** link /container/service/:ssl-tools/startup.sh to /container/run/startup/:ssl-tools
*** link /container/service/slapd/startup.sh to /container/run/startup/slapd
*** link /container/service/slapd/process.sh to /container/run/process/slapd/run
*** Set environment for startup files
*** Environment files will be proccessed in this order :
Caution: previously defined variables will not be overriden.
/container/environment/99-default/default.startup.yaml
/container/environment/99-default/default.yaml
To see how this files are processed and environment variables values,
run this container with '--loglevel debug'
*** Running /container/run/startup/:ssl-tools...
*** Running /container/run/startup/slapd...
No certificate file and certificate key provided, generate:
/container/service/slapd/assets/certs/cert.pem and /container/service/slapd/assets/certs/privkey.pem
2017/06/27 14:52:56 [INFO] generate received request
2017/06/27 14:52:56 [INFO] received CSR
2017/06/27 14:52:56 [INFO] generating key: ecdsa-384
2017/06/27 14:52:56 [INFO] encoded CSR
2017/06/27 14:52:56 [INFO] signed certificate with serial number 353108601774684456276929086277369460834475219239
Link /container/service/:ssl-tools/assets/default-ca/default-ca.pem to /container/service/slapd/assets/certs/chain.pem
Start OpenLDAP...
Waiting for OpenLDAP to start...
Add TLS config...
Add enforce TLS...
Disable replication config...
Stop OpenLDAP...
Remove config files...
First start is done...
*** Set environment for container process
*** Remove file /container/environment/99-default/default.startup.yaml
*** Environment files will be proccessed in this order :
Caution: previously defined variables will not be overriden.
/container/environment/99-default/default.yaml
To see how this files are processed and environment variables values,
run this container with '--loglevel debug'
*** Running /container/run/process/slapd/run...
59525529 @(#) $OpenLDAP: slapd (Jan 16 2016 23:00:08) $
root@chimera:/tmp/buildd/openldap-2.4.40+dfsg/debian/build/servers/slapd
TLS: warning: ignoring dhfile
59525529 slapd starting
I swear I had a complete legit environnement running openldap and phpldapadmin with TLS encryption using lets encrypt some days ago. But there came the renewals of certs ...
Did them, did a docker-compose to update the files in containers, and now, it's not working anymore. My config was :
version: '2'
services:
openldap:
image: osixia/openldap:1.1.8
container_name: openldap
volumes:
- ldapData:/var/lib/ldap
- ldapConf:/etc/ldap/slapd.d
- /etc/letsencrypt/live/DOMAIN:/container/service/slapd/assets/certs/
environment:
LDAP_LOG_LEVEL: "256"
LDAP_ORGANISATION: "organisation"
LDAP_DOMAIN: "domain"
LDAP_BASE_DN: "******"
LDAP_ADMIN_PASSWORD: "******"
LDAP_CONFIG_PASSWORD: "*******"
LDAP_READONLY_USER: "false"
LDAP_BACKEND: "hdb"
LDAP_TLS: "true"
LDAP_TLS_CRT_FILENAME: "cert.pem"
LDAP_TLS_KEY_FILENAME: "privkey.pem"
LDAP_TLS_CA_CRT_FILENAME: "fullchain.pem"
LDAP_TLS_VERIFY_CLIENT: "try"
LDAP_TLS_ENFORCE: "false"
LDAP_REPLICATION: "false"
LDAP_REMOVE_CONFIG_AFTER_SETUP: "true"
LDAP_SSL_HELPER_PREFIX: "ldap"
stdin_open: true
ports:
- "636:636"
hostname: "*******"
phpldapadmin:
image: osixia/phpldapadmin:latest
container_name: phpldapadmin
volumes:
- /etc/letsencrypt/live/DOMAIN:/container/service/phpldapadmin/assets/apache2/certs
environment:
PHPLDAPADMIN_LDAP_HOSTS: "openldap"
PHPLDAPADMIN_HTTPS: "true"
PHPLDAPADMIN_HTTPS_CRT_FILENAME: "cert.pem"
PHPLDAPADMIN_HTTPS_KEY_FILENAME: "privkey.pem"
PHPLDAPADMIN_HTTPS_CA_CRT_FILENAME: "fullchain.pem"
PHPLDAPADMIN_LDAP_CLIENT_TLS: "false"
ports:
- "443:443"
depends_on:
- openldap
hostname: "*******"
volumes:
ldapData:
external: true
ldapConf:
external: true
Now everytime I build it again from scratch, openldap is destroying the simlynk of the fullchain.pem to his container (which was a symlink to the archive folder of letsencrypt), then it tries to generate a DH parameter, fail and crash. Then phpldapadmin tries to access the fullchain.pem file which is now linked to the openldap container, so it doesn't find it and create is own ...
Managed to make it work. The main problem is using the live folder of letsencrypt which is using symlinks. By pointing to the archive one, everything worked fine...
Thank you @zeiitoun , your example appears to be working just fine pointing to archive and using the files there.
Guys pointing it to archive makes it complicated with renewal. This is much better approach This is just important part of compose what has been mentioned already above
environment:
- LDAP_TLS_CRT_FILENAME=live/host.domain.com/cert.pem
- LDAP_TLS_KEY_FILENAME=live/host.domain.com/privkey.pem
- LDAP_TLS_CA_CRT_FILENAME=live/host.domain.com/fullchain.pem
volumes:
- /etc/letsencrypt:/container/service/slapd/assets/certs``
You're right, pointing to the upper directory of lets encrypt is working ... My bad !
@chladic are you recommending to generate the certs on the host instead of within the container?\
I want to use ldaps and ldap+tls with letsencrypt. I am concerned by slapd requiring a restart on certificate change. How did you guys manage to send the signal and renew the certs? would be nice to know if some people use this without hassle in produciton.
@kopax I use it with letsencrypt generated on host outside of container and reload it in post hook. But I would like to change it to have some SSL termination in front so ldap does not have to be touched
@chladic I was just analyzing the situation and thought about solving it with traefik v2.1. The problem if you do that is that ldap+tls won't start because the certificate needs to be available to slapd itself
Unless there's a way to export it from traefik and copy it over... which feel a little too manual to me.
Also, if you use a network volume, slapd must be reloaded on certificate change. Do you know how to sent the reload signal to https://github.com/osixia/docker-openldap container?
ldaps is the only proto capable of handling ssl termination in front. I personnaly need both so that's not an option for me. What post hook are you referring to?
@kopax Solution with traefik would be great in case ldap is running without TLS and traefik does SSL termination. Traefik can store certs in shared storage or consul, but importing it to slapd would be complicated and doesnt solve your problem. I dont send any signal, I restart container with: docker restart ldap
With nginx as SSL termination is possible and it can proxy any TCP/UDP traffic:
https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/
Traefik has TCP services what might do the job, but I never tried.
One problem which we faced using Letsencrypt: Different LE intermediate certificates used on nodes when using master-master replication. Replication of one of the master nodes broke with ldap_sasl_bind_s failed (-1) Reason: This host used the "ISRG Root X1" intermediate cert in chain.pem. All other nodes used the "DST Root CA X3" intermediate cert. Therefore, cert validation to/from the node using the X1 cert broke.
A forced LE renewal and Osixia OpenLdap 1.4.0 container rebuild on all nodes using the old X3 cert fixed the issue.
Currently evaluating doing that using a similar approach we did for mariadb.
Fetching the certificate using
- https://github.com/KontextWork/docker-database-cluster/blob/main/docker-compose-mariadb.yml#L21
- maintaining it with https://github.com/KontextWork/docker-database-cluster/blob/main/docker-compose-mariadb.yml#L44
Also considering adding this to our help chart, where CertManager would take care of the LE management, just not sure if we could incorporate a "deploy hook" with that yet.
Just wanted to share the above, because running a custom LE fetcher without using Traefik or similar is always pain in docker, with the above, it works neatly