First Commit

This commit is contained in:
Lonny Lowe 2026-09-24 11:29:54 -05:00
commit 2e5a4751a7
30 changed files with 2517 additions and 0 deletions

77
tests/ldaps-test.sh Executable file
View file

@ -0,0 +1,77 @@
#!/usr/bin/env bash
# =====================================================================================
# LDAPS test. Proves three separate things:
# * the DC serves 636 and the chain verifies against our CA
# * the SAN actually matches the DC FQDN (Windows requires SAN, not CN)
# * a client WITHOUT our CA is rejected (i.e. we are not accidentally self-trusted)
# Run ./scripts/tls.sh first to create secrets/tls/.
# ./tests/ldaps-test.sh # tears down afterwards
# =====================================================================================
# LDAPS end-to-end check against a freshly provisioned DC with our generated certs.
set -uo pipefail
cd /dockers/WindowsAD
PW='Lab!Only9Tester#2026'
LABTLS="$PWD/secrets/tls-lab"
trap '[ "${KEEP:-0}" = 1 ] || { docker rm -f ad-tlslab >/dev/null 2>&1; docker volume rm tlslab-lib >/dev/null 2>&1; rm -rf "$LABTLS"; }' EXIT
# certs for THIS lab only. Never reuse secrets/tls: that is the production chain,
# regenerating it here would silently destroy the trust anchor every client has installed.
echo "=== generating throwaway testlab CA + leaf (isolated dir, no SYSVOL publish) ==="
mkdir -p "$LABTLS"
AD_TLS_DIR="$LABTLS" AD_TLS_PUBLISH=no AD_REALM=TESTLAB.LOCAL AD_DNS_DOMAIN=testlab.local \
AD_HOSTNAME=dc1 AD_IP=172.28.90.10 AD_CONTAINER=ad-tlslab-absent ./scripts/tls.sh >/tmp/ldaps-tls.log 2>&1 \
|| { echo "cert generation failed:"; tail -15 /tmp/ldaps-tls.log; exit 1; }
# Guard: refuse to run against a cert that is not ours, otherwise this test silently tests the
# production chain and can "pass" for the wrong reason (or fail confusingly).
openssl x509 -in "$LABTLS/dc.crt" -noout -subject | grep -q 'testlab.local' \
|| { echo "!! $LABTLS/dc.crt is not a testlab cert - refusing to run this test"; exit 1; }
openssl x509 -in "$LABTLS/dc.crt" -noout -ext subjectAltName | sed 's/^/ /'
docker rm -f ad-tlslab >/dev/null 2>&1 || true
docker volume rm tlslab-lib >/dev/null 2>&1 || true
docker network rm adlab >/dev/null 2>&1 || true
docker network create --subnet 172.28.90.0/24 --internal adlab >/dev/null
docker run -d --name ad-tlslab --hostname dc1.testlab.local --network adlab --ip 172.28.90.10 \
--cap-drop ALL --cap-add SYS_ADMIN --cap-add CHOWN --cap-add FOWNER --cap-add DAC_OVERRIDE \
--cap-add SETUID --cap-add SETGID --cap-add NET_BIND_SERVICE \
-v "$PWD/secrets:/run/ad-secrets:ro" -v "$LABTLS:/run/ad-secrets/tls:ro" -v tlslab-lib:/var/lib/samba \
-e AD_REALM=TESTLAB.LOCAL -e AD_DNS_DOMAIN=testlab.local -e AD_HOSTNAME=dc1 \
-e AD_IP=172.28.90.10 -e AD_ADMIN_PASSWORD="$PW" \
-e AD_TLS_CERT=/run/ad-secrets/tls/dc.crt -e AD_TLS_KEY=/run/ad-secrets/tls/dc.key \
-e AD_TLS_CA=/run/ad-secrets/tls/ca.crt \
local/samba-ad-dc:4.22-debian13 >/dev/null || { echo "start failed"; exit 1; }
h=none
for _ in $(seq 1 60); do
h="$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' ad-tlslab 2>/dev/null || echo gone)"
[ "$h" = healthy ] && break
sleep 4
done
echo "health: $h"
st="$(docker inspect -f '{{.State.Status}} exit={{.State.ExitCode}}' ad-tlslab 2>/dev/null)"
echo "state: $st"
[ "$h" = healthy ] || { echo "--- log ---"; docker logs ad-tlslab 2>&1 | grep -vE 'Applied |Skip ' | tail -20; exit 1; }
echo "=== 636 listening? ==="
docker exec ad-tlslab ss -ltn | grep ':636' || { echo "636 not listening"; exit 1; }
echo "=== handshake, trusting our CA (must verify) ==="
docker exec ad-tlslab openssl s_client -connect 127.0.0.1:636 \
-CAfile /run/ad-secrets/tls/ca.crt -verify_return_error </dev/null 2>&1 \
| grep -E 'Verify return code|subject=|CN' | head -4
echo "=== handshake with default trust store (must FAIL, proves certs are not self-trusted) ==="
if docker exec ad-tlslab openssl s_client -connect 127.0.0.1:636 -verify_return_error </dev/null >/dev/null 2>&1; then
echo "UNEXPECTED: untrusted handshake succeeded"; RC=1
else
echo "rejected as expected ✔"
fi
echo "=== full battery with LDAPS enabled ==="
AD_SKIP_DOTENV=1 AD_CONTAINER=ad-tlslab AD_REALM=TESTLAB.LOCAL AD_DNS_DOMAIN=testlab.local \
AD_HOSTNAME=dc1 AD_ADMIN_PASSWORD="$PW" \
AD_TLS_CERT=/run/ad-secrets/tls/dc.crt AD_TLS_CA=/run/ad-secrets/tls/ca.crt \
./scripts/verify.sh | grep -E 'LDAPS|passed,'
RC=${RC:-0}
exit "$RC"