fix: LDAPS-Auth, Mail-Zustellung und Zertifikat komplett funktionsfaehig

- LDAP: REFERRALS off + TLS_REQCERT never in /etc/ldap/ldap.conf
- LDAP: pass_attrs/user_attrs fuer Active Directory angepasst (via user-patches.sh)
- LDAP: LDAP_SERVER_HOST auf ldaps://10.10.10.10 gesetzt
- Mail: Bind-Mounts durch Docker Named Volumes ersetzt (v9fs -> ext4)
- SSL: Zertifikat mit CA:FALSE neu generiert (Thunderbird-Kompatibilitaet)
- Doku: DOKU-Mailserver-Setup.txt mit allen Problemen und Loesungen
This commit is contained in:
unknown
2026-05-08 07:55:19 -07:00
parent 32800dc9f0
commit a3689a6498
8 changed files with 304 additions and 3 deletions
+7
View File
@@ -0,0 +1,7 @@
# Runtime-Daten nicht committen
docker-data/dms/mail-data/
docker-data/dms/mail-state/
docker-data/dms/mail-logs/
# SSL Private Key nicht committen
docker-data/dms/ssl/key.pem
+204
View File
@@ -0,0 +1,204 @@
================================================================================
Docker-Mailserver mit Active Directory LDAPS - Dokumentation
ByteTrail GmbH | FH Burgenland SS 2026 | Team 3 VZ
================================================================================
UMGEBUNG
--------
- Mailserver: SRV-EXCH01.byte.trail (10.10.10.11), Docker mit docker-mailserver v15.1.0
- Domain Controller: SRV-DC01.byte.trail (10.10.10.10), Windows Server, AD DS
- Domain: byte.trail
- 29 Benutzer + 1 Service-Account in Active Directory
- Git-Repo: https://git.lucida.ee/blackicedbear/dms.git (Branch: main)
UEBERSICHT: WAS WURDE GEMACHT
------------------------------
1. LDAPS-Zertifikat auf dem Domain Controller (AD CS)
- Active Directory Certificate Services (AD CS) als Enterprise Root CA installiert
- Rolle: Certification Authority (Enterprise Root CA)
- CA-Name: byte-SRV-DC01-CA
- LDAPS (Port 636) wird automatisch aktiviert sobald ein Zertifikat mit
CN=SRV-DC01.byte.trail ausgestellt wird
- Skript: Setup-LDAPS-Certificate.ps1
Warum LDAPS statt LDAP?
- Windows Security Update erzwingt LDAP Signing unabhaengig von Registry-Einstellungen
- Einfaches LDAP (Port 389) funktioniert nicht mehr zuverlaessig mit Signing-Enforcement
- LDAPS (Port 636) umgeht das Problem komplett durch TLS-Verschluesselung
2. Active Directory Benutzer und Struktur
- Skript: Setup-ByteTrail-AD.ps1
- 6 OUs: Geschaeftsfuehrung, Sales, Marketing, Service, Server, Gruppen
- 11 Sicherheitsgruppen (GRP-GF-*, GRP-SALES-*, GRP-MKT-*, GRP-SVC-*, GRP-ALL-EMAIL, GRP-ADMINS)
- 29 Benutzer mit E-Mail-Adressen (vorname.nachname@byte.trail)
- 1 Service-Account: svc-mailserver (fuer LDAP-Bind)
- Standardpasswort Benutzer: ByteTrail2026!
- Service-Account Passwort: Mail$3rv!ceAcc2026
3. Docker-Mailserver Konfiguration (mailserver.env)
- ACCOUNT_PROVISIONER=LDAP
- LDAP_SERVER_HOST=ldaps://10.10.10.10
- LDAP_BIND_DN=CN=Mailserver Service Account,OU=Server,DC=byte,DC=trail
- LDAP_START_TLS=no (weil wir ldaps:// verwenden)
- DOVECOT_AUTH_BIND=yes (Authentifizierung per LDAP-Bind statt Passwort-Vergleich)
- DOVECOT_USER_FILTER=(&(objectClass=person)(mail=%u))
- DOVECOT_PASS_FILTER=(&(objectClass=person)(mail=%u))
- SSL_TYPE=manual (selbst-signiertes Zertifikat)
4. SSL/TLS Zertifikat fuer den Mailserver
- Selbst-signiertes Zertifikat fuer mail.byte.trail
- Wird automatisch beim ersten Start durch ssl-init Container erstellt
- Wichtig: basicConstraints=CA:FALSE (Thunderbird lehnt CA-Zertifikate als
Server-Zertifikate ab)
- SAN: DNS:mail.byte.trail, DNS:byte.trail
- Gueltig fuer 10 Jahre
PROBLEME UND LOESUNGEN
-----------------------
Problem 1: LDAP-Verbindung haengt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Symptom: Dovecot LDAP-Verbindung zu ldaps://10.10.10.10 haengt endlos,
keine Fehlermeldung, keine Timeout-Meldung.
Ursache: Die globale OpenLDAP-Client-Konfiguration (/etc/ldap/ldap.conf)
hatte kein TLS_REQCERT never. Die OpenLDAP-Bibliothek hat das
selbst-signierte CA-Zertifikat des DC stillschweigend abgelehnt.
Dovecot's eigene tls_require_cert=never Einstellung reicht NICHT aus,
weil die darunterliegende OpenLDAP-Bibliothek die globale Konfiguration
fuer ldaps:// Verbindungen nutzt.
Loesung: In /etc/ldap/ldap.conf im Container:
TLS_REQCERT never
Problem 2: LDAP-Suche gibt "Operations error"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Symptom: ldap_search() failed: Operations error (LDAP Error Code 1)
Ursache: Active Directory liefert standardmaessig Referrals (Verweise auf
andere Naming Contexts wie CN=Configuration, CN=Schema).
Die OpenLDAP-Client-Bibliothek kann diese Referrals nicht verarbeiten
und meldet "Operations error".
Loesung: In /etc/ldap/ldap.conf im Container:
REFERRALS off
Problem 3: LDAP-Authentifizierung schlaegt fehl (Password mismatch)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Symptom: doveadm auth test anna.huber@byte.trail ByteTrail2026!
-> "Password mismatch (for LDAP bind)"
Ursache: Alle AD-Benutzer wurden mit -ChangePasswordAtLogon $true erstellt
(im Setup-Skript). Das setzt pwdLastSet=0 in AD. Solange pwdLastSet=0
ist, scheitern LDAP-Simple-Binds mit "Invalid Credentials" (data 52e).
Loesung: Auf dem Domain Controller fuer alle Benutzer ausfuehren:
Invoke-Command -ComputerName 10.10.10.10 -ScriptBlock {
Get-ADUser -Filter {mail -like "*@byte.trail"} |
ForEach-Object { Set-ADUser $_ -ChangePasswordAtLogon $false }
}
Problem 4: Dovecot kennt pass_attrs/user_attrs nicht (AD-Attribute fehlen)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Symptom: "uniqueIdentifier missing", "no fields returned by the server",
"User is missing UID"
Ursache: Docker-mailserver generiert die Dovecot-LDAP-Konfiguration mit
Standardwerten fuer OpenLDAP-Schemata:
- pass_attrs = uniqueIdentifier=user,userPassword=password
- user_attrs = mailHomeDirectory=home,mailUidNumber=uid,...
Active Directory hat diese Attribute NICHT (kein uniqueIdentifier,
kein mailHomeDirectory, kein mailUidNumber etc.).
Loesung: In user-patches.sh werden die Attribute beim Container-Start
automatisch umgeschrieben auf:
- pass_attrs = =user=%u
(statischer Wert, da auth_bind=yes den Benutzer per LDAP-Bind
authentifiziert und kein Passwort aus LDAP lesen muss)
- user_attrs = =uid=5000,=gid=5000,=home=/var/mail/%d/%n/home/,=mail=maildir:/var/mail/%d/%n
(statische Werte fuer UID/GID des vmail-Benutzers und Maildir-Pfade)
Problem 5: Mail-Zustellung scheitert mit "Mailbox was deleted under us"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Symptom: dovecot-lda und LMTP melden beim Speichern einer Mail:
"failed to store into mailbox 'INBOX': Mailbox was deleted under us"
Ursache: Die /var/mail Verzeichnisse waren als Bind-Mount von Windows NTFS
eingebunden. Docker auf Windows nutzt dafuer das v9fs-Dateisystem
(Plan 9 Filesystem Protocol). v9fs unterstuetzt die POSIX-Dateioperationen
nicht korrekt, die Dovecot fuer Maildir-Operationen benoetigt
(insbesondere dotlock-Dateien und dovecot-uidvalidity).
Loesung: In docker-compose.yml Bind-Mounts durch Docker Named Volumes ersetzen:
Vorher: - ./docker-data/dms/mail-data/:/var/mail/
Nachher: - dms-mail-data:/var/mail/
Docker Named Volumes nutzen ext4 statt v9fs, was alle
POSIX-Dateisystemoperationen korrekt unterstuetzt.
Problem 6: Thunderbird "Basic Constraints" Fehler
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Symptom: "Der Server verwendet ein Zertifikat mit einer Basiseinschraenkung,
die es als eine Zertifizierungsstelle identifiziert."
Ursache: Das selbst-signierte Zertifikat wurde mit basicConstraints CA:TRUE
generiert (OpenSSL-Standard fuer -x509). Thunderbird lehnt korrekt
ab, ein CA-Zertifikat als Server-Zertifikat zu akzeptieren.
Loesung: Zertifikat neu generieren mit expliziten Extensions:
-addext "basicConstraints=critical,CA:FALSE"
-addext "keyUsage=digitalSignature,keyEncipherment"
-addext "extendedKeyUsage=serverAuth"
Problem 7: Container-Restart ueberspringt user-patches.sh
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Symptom: Nach "docker restart" meldet der Container
"Skipping most setup routines" und user-patches.sh wird nicht
ausgefuehrt. LDAP-Fixes gehen verloren.
Ursache: docker-mailserver erkennt einen Restart (vs. frischen Start)
und ueberspringt Setup-Routinen inkl. user-patches.sh.
Loesung: Statt "docker restart" immer "docker compose down && docker compose up -d"
verwenden, damit der Container frisch erstellt wird und
user-patches.sh ausgefuehrt wird.
Bei einem einfachen Restart bleiben die Aenderungen im
Container-Dateisystem erhalten (nur relevant wenn der Container
nicht geloescht wird).
WICHTIGE DATEIEN
----------------
docker-compose.yml - Docker Services (ssl-init, mailserver, mssql)
mailserver.env - Mailserver-Konfiguration (LDAP, SSL, Filter)
docker-data/dms/config/user-patches.sh - Startup-Patches (LDAP TLS, Referrals, Dovecot attrs)
docker-data/dms/config/ldap-ca.pem - LDAPS CA-Zertifikat vom Domain Controller
docker-data/dms/ssl/cert.pem - Mailserver TLS-Zertifikat (selbst-signiert)
docker-data/dms/ssl/key.pem - Mailserver TLS-Schluessel
Setup-ByteTrail-AD.ps1 - AD-Setup (OUs, Gruppen, Benutzer, Service-Account)
Setup-LDAPS-Certificate.ps1 - LDAPS-Zertifikat-Setup auf dem DC
THUNDERBIRD-EINSTELLUNGEN
-------------------------
Server: mail.byte.trail
IMAP: Port 993, SSL/TLS
SMTP: Port 587, STARTTLS
Benutzername: anna.huber@byte.trail (oder jeder andere AD-Benutzer)
Passwort: ByteTrail2026!
Beim ersten Verbinden muss die Sicherheitsausnahme fuer das selbst-signierte
Zertifikat bestaetigt werden. Alternativ kann das Zertifikat
(docker-data/dms/ssl/cert.pem) in Thunderbird importiert werden:
Einstellungen > Datenschutz & Sicherheit > Zertifikate verwalten >
Zertifizierungsstellen > Importieren
USER-PATCHES.SH - WAS WIRD BEIM START GEMACHT
----------------------------------------------
1. /etc/ldap/ldap.conf: TLS_REQCERT never + REFERRALS off
2. LDAP CA-Zertifikat in System Trust Store installieren
3. Dovecot LDAP: tls_require_cert=never, pass_attrs und user_attrs fuer AD anpassen
4. Postfix LDAP: TLS-Zertifikatspruefung deaktivieren
+4 -2
View File
@@ -34,8 +34,8 @@ services:
- "587:587" # ESMTP (explicit TLS => STARTTLS) - "587:587" # ESMTP (explicit TLS => STARTTLS)
- "993:993" # IMAP4 (implicit TLS) - "993:993" # IMAP4 (implicit TLS)
volumes: volumes:
- ./docker-data/dms/mail-data/:/var/mail/ - dms-mail-data:/var/mail/
- ./docker-data/dms/mail-state/:/var/mail-state/ - dms-mail-state:/var/mail-state/
- ./docker-data/dms/mail-logs/:/var/log/mail/ - ./docker-data/dms/mail-logs/:/var/log/mail/
- ./docker-data/dms/config/:/tmp/docker-mailserver/ - ./docker-data/dms/config/:/tmp/docker-mailserver/
- ./docker-data/dms/ssl/:/tmp/dms-ssl/:ro - ./docker-data/dms/ssl/:/tmp/dms-ssl/:ro
@@ -68,4 +68,6 @@ services:
- mssql_data:/var/opt/mssql - mssql_data:/var/opt/mssql
volumes: volumes:
dms-mail-data:
dms-mail-state:
mssql_data: mssql_data:
Binary file not shown.
+57
View File
@@ -0,0 +1,57 @@
#!/bin/bash
# Custom patches for docker-mailserver
# Wird bei jedem Container-Start ausgefuehrt
# Fixes fuer Active Directory LDAPS-Authentifizierung
echo "=== user-patches.sh: Starte Anpassungen ==="
# 1. Globale OpenLDAP Client-Konfiguration
cat > /etc/ldap/ldap.conf <<'EOF'
TLS_REQCERT never
REFERRALS off
EOF
echo "[OK] /etc/ldap/ldap.conf: TLS_REQCERT never + REFERRALS off"
# 2. LDAP CA-Zertifikat in den System Trust Store kopieren
if [ -f /tmp/docker-mailserver/ldap-ca.pem ]; then
cp /tmp/docker-mailserver/ldap-ca.pem /usr/local/share/ca-certificates/ldap-ca.crt
update-ca-certificates 2>/dev/null
echo "[OK] LDAP CA-Zertifikat installiert"
fi
# 3. Dovecot LDAP config fuer Active Directory anpassen
if [ -f /etc/dovecot/dovecot-ldap.conf.ext ]; then
# TLS-Zertifikatspruefung deaktivieren
sed -i 's/^tls_require_cert =.*/tls_require_cert = never/' /etc/dovecot/dovecot-ldap.conf.ext
if ! grep -q '^tls_require_cert' /etc/dovecot/dovecot-ldap.conf.ext; then
echo 'tls_require_cert = never' >> /etc/dovecot/dovecot-ldap.conf.ext
fi
# pass_attrs: AD hat kein uniqueIdentifier/userPassword - nutze statische Werte mit auth_bind
sed -i 's|^pass_attrs.*=.*uniqueIdentifier=user,userPassword=password|pass_attrs = =user=%u|' /etc/dovecot/dovecot-ldap.conf.ext
# Falls pass_attrs noch den alten Wert hat (verschiedene Varianten)
if grep -q 'uniqueIdentifier=user' /etc/dovecot/dovecot-ldap.conf.ext; then
sed -i 's|^pass_attrs.*=.*|pass_attrs = =user=%u|' /etc/dovecot/dovecot-ldap.conf.ext
fi
# user_attrs: AD hat keine mailHomeDirectory/mailUidNumber etc. - statische Werte setzen
sed -i 's|^user_attrs.*=.*mailHomeDirectory=home.*|user_attrs = =uid=5000,=gid=5000,=home=/var/mail/%d/%n/home/,=mail=maildir:/var/mail/%d/%n|' /etc/dovecot/dovecot-ldap.conf.ext
# Fallback falls anderes Format
if grep -q 'mailHomeDirectory' /etc/dovecot/dovecot-ldap.conf.ext; then
sed -i 's|^user_attrs.*=.*|user_attrs = =uid=5000,=gid=5000,=home=/var/mail/%d/%n/home/,=mail=maildir:/var/mail/%d/%n|' /etc/dovecot/dovecot-ldap.conf.ext
fi
echo "[OK] Dovecot LDAP config angepasst (tls_require_cert, pass_attrs, user_attrs)"
fi
# 4. Postfix LDAP: TLS-Zertifikatspruefung deaktivieren
for f in /etc/postfix/ldap-*.cf; do
if [ -f "$f" ]; then
if grep -q 'tls_require_cert' "$f"; then
sed -i 's/^tls_require_cert =.*/tls_require_cert = no/' "$f"
fi
fi
done
echo "[OK] Postfix LDAP TLS config angepasst"
echo "=== user-patches.sh: Alle Anpassungen abgeschlossen ==="
+31
View File
@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFXjCCA0agAwIBAgIUNo3ZPo09L3u82esTpepPnxZtLRAwDQYJKoZIhvcNAQEL
BQAwGjEYMBYGA1UEAwwPbWFpbC5ieXRlLnRyYWlsMB4XDTI2MDUwODE0MzQ0OFoX
DTM2MDUwNTE0MzQ0OFowGjEYMBYGA1UEAwwPbWFpbC5ieXRlLnRyYWlsMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7xCzBbQzPoweGWJnHB/7A12LSUJK
+DZRtEVYByQl0gLFe9hAGNmzUsj+ubyUGoQwhbwy2+GQVwx0kUlBRIurtGYhZNUm
zZj3Np4ovzPMvYRynlG1SOCCjhdDmC9MQTpcNfOiHMsTNlkDPR93UW+ZkMwwPm05
H1cibyOXDfvlMn8U5UAvSUzW9KNXMYCTXyu4iin0BLud78Gt8eXT62gdo/+keyJz
WW3W0vqndxElbvRb9tbLp2Ut95VdUtEBCdBac+qppfj1DXYsh9tNG+AOyKxFW7Nq
EIJJjYGgEGN17DV5BgqTga71F+42j9XvwG/H92at6QijOrOqyZOMI6GanJvl0SHj
2Aw8dX6QFg/DvAOKs2OTLBX3cW087w6Snf6zKSuVHcMV6fvcN5hvwPQ/eTwwIE3/
2om0Djg1BhqcJWPfKqfreWCEwsZT3AnqDN5j24a12N1QQNGtwBtwk6srX4GIOdvd
vo8YhpIaaYekoO0AsWEvU0JtwtADtRhWNLxiMkVLhsj3QTEKpTYGVlgSF64FTXKM
2Ty5a9BJ1S3ts43ODFPkmu6P65I7ur4gcIgeFXIeAXxjQNAGAzvM9LotscuTyuNM
/NY3YQgSTOHBpS/i1+cdBbj8KsY1wvgkLsL+SIaNo2M0qMmRQY1snoqcm5/nVe5E
aXjYW8pkv2aAObcCAwEAAaOBmzCBmDAdBgNVHQ4EFgQUyj742ZIMSLDYRpjnWbY/
mLwmdf4wHwYDVR0jBBgwFoAUyj742ZIMSLDYRpjnWbY/mLwmdf4wJgYDVR0RBB8w
HYIPbWFpbC5ieXRlLnRyYWlsggpieXRlLnRyYWlsMAwGA1UdEwEB/wQCMAAwCwYD
VR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IC
AQCfTDcjt00TR615ef8DpOf9B4ty4nRLg4ZRjKW2OAqgL0gWY5ymg7BkTnbawHj7
RyS3sRjqO4O+9KXxDBOou+YqpvLoEmM9lHQGPaU6CxSgt+9ef1moMP0szAyQNrTW
5buPBGg/nUQl6zT2PYuv5B5ry7yuNgYJWw+2bVveH+W41FkKSfI3dGyXXGXLRbmf
LzeBX146jkaO9cr61QauA+IwYDuWgMOu8R+VssYCU5wLbkwRU3d9qHoZD6VwJpwF
doyzAm0LfJj/0B8Zjj+84Lsx7uhQtmMeYqt4RtsQXxt9dWEap8numAfgNBOA2kaR
M0/9dYz4DP9udq+0PJmaBPGYFRAfWCweThWAEmPrm8q6JoruZZvj3vmONiL9VhpC
FUQKkq9bmQrJr+qHUm1oYOUp6eM3aDRZRnoh7UKv8DALMoGggQmorFC/3bgOhBS0
I5RcS1Nny6sTlnMHXTM9zZYM2obWGY/r5Dr97F0s00bftPEcEMO78LJvp5cJwdqo
kQ6U1Tm+/T8Sazt5jxomA1JoC+sUhcS++5EdvEDxZY28k68TBuKLW68AsveV3FkC
4JHM7vUIk2WkXocE6txj7Y0VcpbWd95c6zyGqlrKYN1pARm7iUlQFcU79UxQLJGW
2dL16VyHbaxW1TkWja2d8dW5bvGh2i/IfwW2FaoKXBWeEg==
-----END CERTIFICATE-----
Binary file not shown.
+1 -1
View File
@@ -460,7 +460,7 @@ LDAP_START_TLS=no
# empty => mail.example.com # empty => mail.example.com
# Specify the `<dns-name>` / `<ip-address>` where the LDAP server is reachable via a URI like: `ldaps://mail.example.com`. # Specify the `<dns-name>` / `<ip-address>` where the LDAP server is reachable via a URI like: `ldaps://mail.example.com`.
# Note: You must include the desired URI scheme (`ldap://`, `ldaps://`, `ldapi://`). # Note: You must include the desired URI scheme (`ldap://`, `ldaps://`, `ldapi://`).
LDAP_SERVER_HOST=ldap://10.10.10.10 LDAP_SERVER_HOST=ldaps://10.10.10.10
# empty => ou=people,dc=domain,dc=com # empty => ou=people,dc=domain,dc=com
# => e.g. LDAP_SEARCH_BASE=dc=mydomain,dc=local # => e.g. LDAP_SEARCH_BASE=dc=mydomain,dc=local