Du kennst das: Passbolt läuft, die Anmeldung klappt, alles gut – bis du einmal in die Systemprüfung schaust. „Passbolt is not configured to force SSL use“, „SMTP Settings plugin endpoints are enabled“, und die Wiederherstellungs-Mail, auf die du seit zehn Minuten wartest, kommt auch nicht. Schaltest du SSL-Erzwingen einfach ein, quittiert der Browser das mit „zu viele Weiterleitungen“. Willkommen im Zusammenspiel von Passbolt Plesk und Docker.
In meinem Fall läuft Passbolt CE als Docker-Container auf einem gemieteten Server mit Plesk. Plesk kümmert sich um Zertifikat und HTTPS, der Container lauscht nur lokal. Damit du (oder dein zukünftiges Ich) nicht dieselben Runden drehst, hier der Weg zu einem grünen Healthcheck – samt der vier Fallen, in die ich nacheinander getappt bin.
Ziel
- Passbolt ist nur über HTTPS erreichbar, der Container selbst nur lokal.
- SSL wird von Passbolt erzwungen – ohne Weiterleitungsschleife.
- Passbolt verschickt Mails, obwohl Microsoft 365 die SMTP-Anmeldung blockiert.
- Der Import großer Passwortlisten scheitert nicht an der Web Application Firewall.
- Der Healthcheck meldet „No error found“.
Voraussetzungen
- Ein Server mit Plesk (hier Ubuntu 24.04, Plesk Obsidian) und Root-Zugang per SSH.
- Passbolt CE mit dem offiziellen Docker-Compose-Setup unter
/opt/passbolt. - Eine Subdomain in Plesk für Passbolt, z. B.
passbolt.example.org, mit gültigem Let’s-Encrypt-Zertifikat. - Vor jeder Änderung: Sicherungskopie der Compose-Datei und ein Datenbank-Dump.
cp -p /opt/passbolt/docker-compose.yaml /opt/passbolt/docker-compose.yaml.bak-$(date +%Y%m%d-%H%M)
Schritt 1: Plesk als Reverse Proxy – der Container bleibt lokal
Der Container bekommt keinen öffentlichen Port, sondern nur einen auf 127.0.0.1. In der Compose-Datei beim Dienst passbolt:
ports:
- 127.0.0.1:8080:80
In Plesk unter Websites & Domains → passbolt.example.org → Apache & nginx → Zusätzliche Apache-Direktiven für HTTPS:
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"

Die beiden RequestHeader-Zeilen sind wichtig: Sie sagen Passbolt, dass der Besucher eigentlich per HTTPS kommt – auch wenn zwischen Plesk und Container nur HTTP läuft. Ohne sie geht es in Schritt 2 schief.
Schritt 2: SSL erzwingen, ohne dass sich alles im Kreis dreht
Der naheliegende Schalter ist PASSBOLT_SSL_FORCE: "true". Allein gesetzt passiert aber Folgendes: Passbolt sieht eine HTTP-Anfrage (vom Proxy), leitet auf HTTPS um, der Browser kommt per HTTPS bei Plesk an, Plesk fragt wieder per HTTP – und so weiter, bis der Browser aufgibt.
Die Lösung: Passbolt muss dem Proxy vertrauen und die X-Forwarded-Proto-Angabe auswerten. Dafür braucht es die Adresse, von der der Proxy aus Sicht des Containers kommt – das Gateway des Docker-Netzes:
docker network inspect passbolt_default -f '{{range .IPAM.Config}}{{.Subnet}} gw {{.Gateway}}{{end}}'
# 172.18.0.0/16 gw 172.18.0.1
Dann in der Compose-Datei beim Dienst passbolt unter environment:
APP_FULL_BASE_URL: https://passbolt.example.org
PASSBOLT_SSL_FORCE: "true"
PASSBOLT_SECURITY_PROXIES_ACTIVE: "true"
PASSBOLT_SECURITY_PROXIES_TRUSTED_PROXIES: "172.18.0.1"
Container neu erstellen:
cd /opt/passbolt && docker compose up -d
Hinweis: Trag hier wirklich nur das Gateway ein, nicht das ganze Netz. Wer jedem Absender den Header glaubt, lässt sich die HTTPS-Angabe auch von außen unterjubeln.

Schritt 3: Mails verschicken, obwohl Microsoft 365 nicht will
Meine Domain hat ihre Postfächer bei Microsoft 365. Also erster Gedanke: Passbolt einfach per SMTP mit Anmeldung über smtp.office365.com schicken lassen. Ergebnis: Anmeldung abgelehnt. In den Anmeldeprotokollen von Entra ID steht dann der Fehler 530035 – „durch Sicherheitsstandards blockiert“. Sind in M365 die Sicherheitsstandards aktiv (bei neuen Mandanten der Normalfall), lässt Microsoft eine reine Passwort-Anmeldung per SMTP gar nicht erst zu.
Die Sicherheitsstandards abzuschalten, nur damit ein Passwortmanager Mails schicken kann, wäre der falsche Tausch. Stattdessen verschickt Passbolt über den Postfix, der auf dem Plesk-Server ohnehin läuft:
- Postfix für Docker-Netze öffnen: In Plesk unter Tools & Einstellungen → Mailserver-Einstellungen → Whitelist das interne Docker-Netz
172.16.0.0/12eintragen. Das Netz existiert nur auf dem Server selbst.

- Container den Host erreichen lassen: in der Compose-Datei beim Dienst
passbolt:
yaml
extra_hosts:
- "host.docker.internal:host-gateway"
- SMTP in Passbolt: Server
host.docker.internal, Port25, ohne Anmeldung, ohne TLS, Absender z. B.passbolt@example.org. - SPF ergänzen: Der Server verschickt jetzt im Namen der Domain. Also muss seine IP in den SPF-Eintrag, neben dem Eintrag für Microsoft:
text
v=spf1 ip4:203.0.113.10 include:spf.protection.outlook.com -all
Achtung, falls die Domain auch in Plesk als Maildomain eingerichtet ist: Dann stellt Postfix Mails an die eigene Domain lokal zu, statt sie zu Microsoft zu schicken. Den Maildienst der Domain in Plesk abschalten – aber vorher sichern, denn dabei verschwinden die lokalen Postfächer.
Schritt 4: SMTP-Einstellungen in die Datenbank – und dann abschließen
Passbolt meckert im Healthcheck, solange die SMTP-Einstellungen über die Oberfläche geändert werden können („SMTP Settings plugin endpoints are enabled“). Die Reihenfolge, die bei mir funktioniert hat:
- In Passbolt unter Administration → E-Mail-Server die Werte aus Schritt 3 eintragen, Testmail schicken, speichern. Ab jetzt liegen sie verschlüsselt in der Datenbank.
- Alle
EMAIL_TRANSPORT_*-Zeilen aus der Compose-Datei entfernen. - Die Endpunkte sperren und die Absenderprüfung einschalten:
yaml
PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED: "true"
PASSBOLT_EMAIL_VALIDATE_MX: "true"
docker compose up -d.
Willst du später etwas an den Mail-Einstellungen ändern, musst du die Endpunkte vorher wieder freigeben – solange sie gesperrt sind, lässt sich dort in der Oberfläche nichts speichern.
Schritt 5: ModSecurity lässt den Import nicht durch
Beim Import meiner Passwortliste brach Passbolt mitten drin ab, im Browser nur ein knappes „403“. Die Ursache stand im Log der Web Application Firewall: Passbolt fragt beim Import eine Adresse mit …contain[creator.profile]… ab, und eine Regel aus dem Comodo-Regelsatz (ID 210580) hält .profile für einen Versuch, Systemdateien auszulesen.
Die Lösung ist chirurgisch: nur diese eine Regel, nur für diese Domain. In Plesk unter Websites & Domains → passbolt.example.org → Web Application Firewall bei Sicherheitsregel-IDs ausschalten 210580 eintragen.

Danach lief der Import durch. Die Firewall bleibt für alles andere aktiv.
So prüfst du es
Von außen und direkt am Container:
curl -s -o /dev/null -w "http -> %{http_code} %{redirect_url}\n" http://127.0.0.1:8080/ -H "Host: passbolt.example.org"
curl -s -o /dev/null -w "https -> %{http_code} (redirects: %{num_redirects})\n" -L https://passbolt.example.org/auth/login
Erwartet: 302 auf HTTPS beim direkten Aufruf, 200 ohne Weiterleitung von außen. Und dass der Port von außen zu ist:
nc -zv -w 3 203.0.113.10 8080 # muss scheitern
Dann der Healthcheck. Achtung, Falle: Rufst du ihn einfach per docker exec auf, hagelt es rote Meldungen – „The server OpenPGP key is not set“, „private key cannot be used to decrypt“ und ein PHP-Fehler bei den SMTP-Einstellungen.

Das sind keine echten Fehler. Dem docker exec-Aufruf fehlt die Umgebungsvariable mit dem Fingerabdruck des Server-Schlüssels, die der Webserver beim Start bekommt. So läuft er richtig:
docker exec passbolt-passbolt-1 sh -c '
FP=$(su -s /bin/sh -c "gpg --homedir /var/lib/passbolt/.gnupg --list-secret-keys --with-colons" www-data | awk -F: "/^fpr/{print \$10; exit}")
PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$FP su -m -s /bin/sh -c "/usr/share/php/passbolt/bin/cake passbolt healthcheck" www-data'
su -m sorgt dafür, dass die Variable beim Wechsel zu www-data erhalten bleibt. Ergebnis:

Zum Schluss eine Testmail auslösen, z. B. über Passwort vergessen auf der Anmeldeseite, und im Mail-Log nachsehen, ob sie rausging:
grep -i "status=sent" /var/log/maillog | tail -3
Rückweg
- Compose-Datei aus der Sicherung zurückholen und
docker compose up -d. - SSL-Erzwingen allein abschalten:
PASSBOLT_SSL_FORCE: "false"– aber siehe Stolperstellen. - Whitelist-Eintrag,
extra_hostsund WAF-Ausnahme in Plesk wieder entfernen.
Stolperstellen aus der Praxis
"false"ist nicht falsch. In meiner ersten Mail-Konfiguration standEMAIL_TRANSPORT_DEFAULT_TLS: "false". Passbolt liest den Wert als Text, und ein nicht leerer Text zählt als „ja“. Folge: Passbolt versuchte STARTTLS zum lokalen Postfix, lehnte dessen Zertifikat ab, und die Wiederherstellungs-Mail blieb hängen. Was aus sein soll, lässt du besser ganz weg.- Weiterleitungsschleife nach SSL-Erzwingen: Fast immer fehlt
X-Forwarded-Protoim Proxy oder der Proxy steht nicht inTRUSTED_PROXIES. - Falsches Gateway: Jedes Compose-Projekt hat sein eigenes Netz. Das Gateway für
TRUSTED_PROXIESimmer mitdocker network inspectnachsehen, nicht raten. - Fehler 530035 bei Microsoft 365 heißt nicht „falsches Passwort“, sondern „Passwort-Anmeldung gesperrt“. Am Passwort zu drehen bringt nichts.
- Hängengebliebene Mails: Mails, die vor der Umstellung nicht rausgingen, liegen weiter in der Tabelle
email_queue. Passbolt gibt nach einigen Versuchen auf – sie gehen also nicht plötzlich doch noch raus. - Passbolt im Browser ohne Erweiterung: Die Oberfläche funktioniert nur mit der Passbolt-Browsererweiterung. Ohne erscheint nur die E-Mail-Abfrage – und ein Klick darauf löst eine Wiederherstellungs-Mail aus.
Fazit
Passbolt hinter Plesk ist kein Hexenwerk, aber eine Kette aus kleinen Annahmen: Der Proxy muss sagen, dass er HTTPS spricht, Passbolt muss ihm glauben, der Mailversand braucht einen Weg an Microsofts Sicherheitsstandards vorbei, und die Firewall darf den Import nicht für einen Angriff halten. Hat man das einmal sauber verdrahtet, ist Passbolt Plesk ein ziemlich entspanntes Gespann. Und der wichtigste Merksatz für alle, die nachts vor einem roten Healthcheck sitzen: Erst prüfen, ob der Check selbst richtig aufgerufen wurde.





