ungleich-user/dev/ldap/entrypoint.sh
Sajeyks b9c043dcd4 Serve LDAPS, StartTLS and IPv6 from the dev LDAP
Production and the client's test server use ldaps://, so the dev server
now offers TLS as well: ldaps on 636 (localhost:3636) and StartTLS on
389, with both ports also published on [::1].

A throwaway CA and server certificate are generated on every start, with
the full CA extensions that Python 3.13+ strict verification requires.
The CA certificate is copied to dev/ldap/export/ca.crt (gitignored).
The server certificate covers localhost, the service names and ::1, but
not 127.0.0.1, so tests can show that hostname mismatches are
rejected.
2026-11-10 14:54:20 +03:00

50 lines
2.4 KiB
Bash

#!/bin/sh
# Builds a fresh directory on every container start, so recreating the
# container (`docker compose up -d --force-recreate ldap`) resets all data.
set -eu
CONF=/etc/openldap/slapd.d
DATA=/var/lib/openldap/openldap-data
rm -rf "${CONF:?}"/* "${DATA:?}"/*
# Throwaway CA and server certificate, new on every start. The CA cert is
# copied to /export (mounted from the host) so clients can verify the
# server. 127.0.0.1 is left out on purpose: tests use it to prove that
# hostname verification rejects a name the certificate does not cover.
TLS=/etc/openldap/tls
mkdir -p "$TLS"
# Full CA extensions: Python 3.13+ verifies strictly by default and
# rejects a CA without keyUsage.
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -days 3650 \
-subj "/CN=ungleich-user dev CA" -keyout "$TLS/ca.key" -out "$TLS/ca.crt" \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign" \
-addext "subjectKeyIdentifier=hash" 2>/dev/null
openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
-subj "/CN=localhost" -keyout "$TLS/server.key" -out "$TLS/server.csr" 2>/dev/null
printf 'subjectAltName=%s\nextendedKeyUsage=serverAuth\nkeyUsage=critical,digitalSignature\nbasicConstraints=CA:FALSE\nsubjectKeyIdentifier=hash\nauthorityKeyIdentifier=keyid\n' \
"DNS:localhost,DNS:ldap,DNS:ldap1,DNS:ldap2,DNS:v6-ldap,IP:::1" > "$TLS/ext.cnf"
openssl x509 -req -in "$TLS/server.csr" -CA "$TLS/ca.crt" -CAkey "$TLS/ca.key" \
-CAcreateserial -days 3650 -extfile "$TLS/ext.cnf" -out "$TLS/server.crt" 2>/dev/null
rm -f "$TLS/ca.key"
if [ -d /export ]; then cp "$TLS/ca.crt" /export/ca.crt; fi
ADMIN_PW_HASH=$(slappasswd -s "${LDAP_ADMIN_PASSWORD:-admin}")
# cn=config: modules, schemas, database, ACLs
sed "s|@ADMIN_PW_HASH@|${ADMIN_PW_HASH}|" /bootstrap/config.ldif > /tmp/config.ldif
slapadd -n 0 -F "$CONF" -l /tmp/config.ldif
slapadd -n 0 -F "$CONF" -l /bootstrap/openssh-lpk.ldif
# Directory tree and seed users
slapadd -n 1 -F "$CONF" -l /bootstrap/seed.ldif
chown -R ldap:ldap "$CONF" "$DATA" /run/openldap "$TLS"
# slapd sizes its descriptor table by the open-file limit; under some
# runtimes (kind/containerd) that is ~10^9, and slapd is OOM-killed.
ulimit -n 4096
# -d keeps slapd in the foreground; "stats" logs every operation to stdout.
exec slapd -u ldap -g ldap -F "$CONF" -h "ldap:/// ldaps:///" -d "${SLAPD_LOGLEVEL:-stats}"