[[Uebersicht|← Zurück zur Homepage]] # PaperSafe – Proton Mail Bridge (Installation & Anbindung) > **Rolle dieser Note:** Die **vollständige, tatsächlich umgesetzte** Einrichtung der Proton-Anbindung – von der Bridge im eigenen LXC über die knifflige Zertifikats-/Erreichbarkeitslösung bis zu den Paperless-Regeln. Ausgegliedert aus [[11-E-Mail-Postfaecher]] (dort steht das allgemeine IMAP-Konzept + Outlook); diese Note ist für Proton **maßgeblich**. > > **Stand 24.07.2026:** Bridge läuft produktiv, Anbindung an Paperless steht, Erstimport abgeschlossen (alle Ordner geleert). Der laufende Abruf erfolgt automatisch alle 10 Min (siehe „Betrieb"). ## Überblick / Datenfluss ``` Proton-Server ──(HTTPS, Login+2FA)──► Proton Bridge [CT 100, eigener LXC] │ lokaler IMAP 127.0.0.1:1143 (STARTTLS, self-signed CN=127.0.0.1) │ systemd-socket-proxyd: 0.0.0.0:143 → 127.0.0.1:1143 ▼ LAN: 192.168.2.49:143 socat-Sidecar (im Netz-Namespace des Paperless-webservers) 127.0.0.1:143 → 192.168.2.49:143 ▼ Paperless (CT 110) ── Mail-Konto 127.0.0.1:143 ──► 15 Regeln (je Ordner ein Tag) ``` **Warum dieser Umweg?** Das Bridge-Zertifikat ist fest auf **`CN=127.0.0.1` / SAN IP 127.0.0.1** ausgestellt und liegt **verschlüsselt** in der Bridge (`vault.enc`) – es ist **nicht** gegen ein Zertifikat mit der LAN-IP austauschbar. Paperless prüft aber den Hostnamen (kein Abschalter). Lösung: Paperless spricht die Bridge als **`127.0.0.1`** an (dann passt der Zertifikatsname), und ein winziger **socat-Weiterleiter im Netz-Namespace des webserver-Containers** reicht `127.0.0.1:143` an die Bridge-IP weiter. Das selbstsignierte Zertifikat wird über `PAPERLESS_EMAIL_CERTIFICATE_LOCATION` als vertrauenswürdig hinterlegt. ## Komponenten (Ist-Stand) | Komponente | Ort / Wert | |---|---| | Bridge-LXC | **CT 100** „protonmail-bridge", **192.168.2.49**, Debian 13 (Community-Script) | | Bridge-Dienst | `protonmail-bridge.service` (headless, `--noninteractive`), enabled | | LAN-Proxy | `protonmail-bridge-imap.socket` → `…-imap-proxy.service` (systemd-socket-proxyd), `0.0.0.0:143 → 127.0.0.1:1143` | | socat-Sidecar | Compose-Dienst `proton-imap-proxy`, Image `docker.io/alpine/socat:1.8.0.3` (gepinnt), `network_mode: service:webserver`, Kommando `TCP4-LISTEN:143,fork,reuseaddr,bind=127.0.0.1 TCP4:192.168.2.49:143` | | Zertifikat | `/opt/paperless/certs/proton-bridge.pem` (Host) → gemountet nach `/usr/src/paperless/certs/proton-bridge.pem` (ro) | | Env | `PAPERLESS_EMAIL_CERTIFICATE_LOCATION=/usr/src/paperless/certs/proton-bridge.pem` (in `docker-compose.env`) | | Paperless-Konto | „Proton", Server **127.0.0.1**, Port **143**, **STARTTLS**, User = Proton-Adresse, Passwort = Bridge-IMAP-Passwort | ## Installation – so wurde es gemacht ### 1. Bridge-LXC anlegen (Community-Script) Proxmox-VE-Helper-Script **„Proton Mail Bridge"** ([community-scripts.org/scripts/protonmail-bridge](https://community-scripts.org/scripts/protonmail-bridge)) in der Proxmox-Shell ausführen (interaktives whiptail-Menü, Defaults gewählt). Ergebnis: CT 100, Debian 13, Bridge + `pass`/GPG + die beiden Socket-Proxy-Units (IMAP 143, SMTP 587) – jeweils zunächst **disabled**, mit Bedingung `ConditionPathExists=/home/protonbridge/.protonmailbridge-initialized`. ### 2. Proton-Login (interaktiv, Nutzer) Im Container `protonmailbridge-configure` ausführen → CLI-Login mit **Proton-Adresse + 2FA**. Die Bridge erzeugt dabei das **IMAP-Passwort** (Benutzername = Proton-Adresse). > **Abschluss nicht vergessen:** Im Bridge-Prompt `>>>` am Ende **`exit`** eingeben. Erst dann setzt das `configure`-Script den Marker `.protonmailbridge-initialized`, aktiviert den **headless-Dienst** und **beide Sockets** (`systemctl enable --now`). Ohne `exit` bleibt der LAN-Port `:143` zu. ### 3. Erreichbarkeit prüfen ```bash # im CT 100 systemctl is-active protonmail-bridge.service protonmail-bridge-imap.socket # beide active ss -tlnp | grep :143 # *:143 (systemd) # vom Host openssl s_client -connect 192.168.2.49:143 -starttls imap # Zertifikat CN=127.0.0.1 ``` ### 4. Zertifikat für Paperless hinterlegen ```bash # im CT 110 mkdir -p /opt/paperless/certs echo | openssl s_client -connect 192.168.2.49:143 -starttls imap 2>/dev/null \ | openssl x509 -outform PEM > /opt/paperless/certs/proton-bridge.pem ``` Dann in `docker-compose.yml` beim `webserver` mounten: `- ./certs/proton-bridge.pem:/usr/src/paperless/certs/proton-bridge.pem:ro` und in `docker-compose.env`: `PAPERLESS_EMAIL_CERTIFICATE_LOCATION=/usr/src/paperless/certs/proton-bridge.pem` (Setting-Name ist `…_LOCATION`, **nicht** `…_FILE`.) ### 5. socat-Sidecar in den Compose-Stack Neuer Dienst in `docker-compose.yml` (teilt den Netz-Namespace des webservers, damit `127.0.0.1:143` das Loopback ist, das Paperless sieht): ```yaml proton-imap-proxy: image: docker.io/alpine/socat:1.8.0.3 restart: unless-stopped network_mode: "service:webserver" depends_on: - webserver command: TCP4-LISTEN:143,fork,reuseaddr,bind=127.0.0.1 TCP4:192.168.2.49:143 ``` `docker compose up -d` → webserver wird neu erstellt (Mount + Env), Sidecar startet. ### 6. Verbindungstest (exakt wie Paperless) ```python import imaplib, ssl ctx = ssl.create_default_context() ctx.load_verify_locations(cafile="/usr/src/paperless/certs/proton-bridge.pem") M = imaplib.IMAP4("127.0.0.1", 143); M.starttls(ssl_context=ctx) M.login("<proton-adresse>", "<bridge-imap-passwort>") # muss OK liefern ``` Vertrauen (Zertifikatsdatei) **+** Hostname (`127.0.0.1` = SAN) **+** Login müssen zusammen durchlaufen. ### 7. Mail-Konto + Regeln in Paperless Konto „Proton" (Server 127.0.0.1, Port 143, STARTTLS, User/Passwort). Je Proton-Ablageordner **eine Regel** (`folder` = genau ein Ordner, keine Rekursion), `assign_tags` = Ordnername, `assign_title_from` = Betreff, `consumption_scope` = **Stufe 3** (Mail als `.eml` + Anhänge getrennt), `attachment_type` = nur echte Anhänge. > **Sonderfall Gesendet (`Sent`, seit 25.07.2026):** Zusätzlich zu den Ablageordnern wird auch der System-Ordner **`Sent`** gesichert (Regel „Proton: Gesendet", Tag **`Gesendet`**, Aktion Delete wie die übrigen). **Kein Korrespondent** – bei gesendeten Mails ist der Absender immer der eigene Account; Paperless kann den **Empfänger nicht** als Korrespondent setzen (`assign_correspondent_from` kennt nur Absender/fest/keiner). Der Empfänger bleibt über den Volltext (Header „An:") auffindbar. ## Betriebs-Fallstricke (am System gelernt) > **⚠ Mailverarbeitung als User `paperless` anstoßen, nie als root.** > Wird `process_mail_accounts()` über die Django-Shell **als root** ausgelöst, gehören die temporären `.eml` in `data/scratch` root (Modus 0600). Der Consumer läuft als `paperless` und kann sie **nicht** lesen → `[Errno 13] Permission denied`. Immer `docker compose exec --user paperless …` verwenden. Der reguläre Zeitplan (Celery-Beat) läuft ohnehin als `paperless`. > **⚠ Getrennte Datenbestände O365 ↔ Proton.** Das Paperless-Archiv stammt aus dem **alten O365-Postfach** (PST-Import); Proton ist das **neue** Postfach (Umstellung ~Mitte 2025). Überlappung minimal. Die **.eml-Texte** werden neu importiert (PST- und IMAP-Serialisierung unterscheiden sich → Byte-MD5 greift nicht als Duplikatschutz). **Anhänge** (PDF/Bild) sind dagegen byte-identisch – vorhandene werden von Paperless als Duplikat **übersprungen** (Task-Status „FAILURE: … is a duplicate of …"). Das ist **kein Fehler**, sondern gewollt: keine doppelten Belege. > **Delete-Semantik bei Proton:** Die Regel-Aktion „Delete" entfernt die Mail nach erfolgreichem Import **aus dem Ordner** – Proton **entlabelt** sie, die Mail bleibt in **„All Mail"** (nicht im Papierkorb, nicht endgültig weg). Gelöscht wird **nur nach erfolgreichem** eml-Import (chord-abgesichert); scheitert der Import, bleibt die Mail liegen. > **⚠ webserver-Neustart reißt den Sidecar mit.** Der socat-Sidecar `proton-imap-proxy` teilt den **Netz-Namespace des webservers** (`network_mode: service:webserver`). Wird der `webserver`-Container neu gestartet (z. B. als Consumer-Notgriff oder durch den Post-Boot-Fix, siehe [[04-Betrieb-Backup]] Abschnitt 4a), entsteht ein neuer Namespace und der Sidecar hängt am alten → `127.0.0.1:143` liefert `Connection refused`, **der Proton-Abruf fällt still aus**. Fix: `docker compose restart proton-imap-proxy` **nach jedem** webserver-Neustart. Am 25.07.2026 real aufgetreten und behoben. ## Betrieb – wann und wie der Import läuft Der Abruf läuft **vollautomatisch alle 10 Minuten**, rund um die Uhr. | Punkt | Wert (am System verifiziert 24.07.2026) | |---|---| | Auslöser | Celery-Beat-Task **„Check all e-mail accounts"** → `paperless_mail.tasks.process_mail_accounts` | | Zeitplan | **`*/10 * * * *`** (alle 10 Min). `PAPERLESS_EMAIL_TASK_CRON` ist **nicht** gesetzt → Paperless-Standard | | Ausführungs-User | `paperless` (Worker) – nie root (siehe Fallstrick oben) | | Voraussetzung | CT 110 **und** CT 100 (Bridge) laufen. Ist die Bridge aus, scheitert der Lauf still und wird beim nächsten Zyklus erneut versucht | **Ablauf je Lauf:** verbinden (`127.0.0.1:143` → socat → Bridge) → alle **15 Regeln** abarbeiten (je Regel ein Ordner) → neue Mails einlesen (Stufe 3: `.eml` + Anhänge, Tag = Ordnername, Korrespondent aus Absender – Ausnahme `Sent`: keiner) → **Delete** = Ordner-Label entfernen (Mail → „All Mail"). Bereits verarbeitete Mails erkennt Paperless an der UID (kein Doppel-Import). **Im Alltag:** Eine Mail in Proton in einen der 15 Ordner verschieben → innerhalb von **10 Min** in Paperless (mit Tag) und aus dem Ordner verschwunden. Kein manueller Schritt nötig. **Sofort statt warten:** In der Weboberfläche *Einstellungen → E-Mail* beim Konto „Ausführen", oder am Host `docker compose exec --user paperless webserver python manage.py mail_fetch`. ## Wiederherstellung / Neuaufbau - **Bridge (CT 100):** Der LXC ist ein eigener Gast → vom Proxmox-Backup (vzdump) wiederherstellbar. Nach Restore ggf. `protonmailbridge-configure` erneut (Login+2FA), dann `exit` → Dienst/Sockets aktiv. - **Paperless-Seite:** `certs/proton-bridge.pem`, der Sidecar-Dienst und die Env-Zeile stecken in `docker-compose.yml`/`.env` (im vzdump von CT 110 enthalten). Ändert sich das Bridge-Zertifikat (Neuaufbau der Bridge), muss `proton-bridge.pem` neu exportiert werden (Schritt 4). ## Sicherheit Proton-Login und das Bridge-IMAP-Passwort **kommen nicht ins Vault** (Projektregel 6) – **generiert, separat übermittelt**. In Paperless liegt das Bridge-Passwort verschlüsselt in der DB (nötig für den Abruf); das ist kein Vault-Inhalt. ## Quellen - Proxmox VE Helper-Scripts – *Proton Mail Bridge*, `community-scripts.org/scripts/protonmail-bridge`: LXC-Default Debian 13 (2 Kerne/1024 MB/8 GB), headless-Bridge, `systemd-socket-proxyd` (IMAP 143 → 127.0.0.1:1143), Erstsetup `protonmailbridge-configure` – Zugriff 22.07.2026 - Proton – *Bridge for Linux*, `proton.me/support/bridge-for-linux`: Bridge nur mit kostenpflichtigem Plan, Secret-Store (`pass`/GPG) – Zugriff 21.07.2026 - Eigene Prüfung am laufenden System (24.07.2026): Bridge-Zertifikat `CN=127.0.0.1, SAN IP 127.0.0.1`, Zertifikat verschlüsselt in `bridge-v3/vault.enc` (keine austauschbare `cert.pem`); Paperless `paperless_mail/mail.py` `get_mailbox()` nutzt `create_default_context()` + optional `EMAIL_CERTIFICATE_FILE`, Setting-Name `PAPERLESS_EMAIL_CERTIFICATE_LOCATION`; Duplikatprüfung `documents/consumer.py` per `hashlib.md5` gegen `checksum`/`archive_checksum`; **Abrufzeitplan** `settings.CELERY_BEAT_SCHEDULE` „Check all e-mail accounts" = `paperless_mail.tasks.process_mail_accounts`, Crontab `*/10 * * * *`, `PAPERLESS_EMAIL_TASK_CRON` nicht gesetzt (Standard) --- **Status:** Bridge produktiv, Paperless-Anbindung steht (Konto + 15 Regeln), Erstimport abgeschlossen, laufender Abruf alle 10 Min **Version:** 1.3 **Letzte Aktualisierung:** 25.07.2026, 12:08 Uhr ### Änderungshistorie | Version | Datum | Uhrzeit | Änderung | |---|---|---|---| | 1.3 | 25.07.2026 | 12:08 | **Kritischer Fallstrick ergänzt:** Ein `webserver`-Neustart reißt den socat-Sidecar `proton-imap-proxy` mit (gemeinsamer Netz-Namespace) → Proton-IMAP `127.0.0.1:143` tot, bis der Sidecar ebenfalls neu gestartet wird. Am 25.07. real aufgetreten (webserver-Neustart als Consumer-Fix legte Proton lahm), per `docker compose restart proton-imap-proxy` behoben | | 1.2 | 25.07.2026 | 08:02 | **Gesendet-Ordner ergänzt.** 15. Regel „Proton: Gesendet" (Ordner `Sent`, Tag `Gesendet`, Stufe 3, Aktion Delete, **kein Korrespondent** – Empfänger als Korrespondent von Paperless nicht unterstützt). Datenfluss/Betrieb/Status auf 15 Regeln aktualisiert. 576 Sent-Mails werden per regulärem 10-Min-Abruf importiert | | 1.1 | 24.07.2026 | 21:24 | Abschnitt **„Betrieb – wann und wie der Import läuft"** ergänzt: automatischer Abruf alle 10 Min (Celery-Beat `*/10 * * * *`, `PAPERLESS_EMAIL_TASK_CRON` nicht gesetzt = Standard; am System verifiziert), Voraussetzung Bridge läuft, Ablauf je Lauf, manuelles Sofort-Auslösen. Stand/Status auf „Erstimport abgeschlossen" gesetzt | | 1.0 | 24.07.2026 | 14:15 | Erstfassung. Bridge-Installation und Paperless-Anbindung aus [[11-E-Mail-Postfaecher]] ausgegliedert und auf den **tatsächlich umgesetzten** Stand gebracht: CT 100 (Community-Script), Login+2FA, headless-Dienst, LAN-Socket-Proxy, **socat-Sidecar + `PAPERLESS_EMAIL_CERTIFICATE_LOCATION`** als Lösung für das 127.0.0.1-Zertifikat, Konto + Regeln. Fallstricke dokumentiert (paperless-User, O365↔Proton getrennt, Anhang-Dedup, Delete=Entlabeln) | --- [[Impressum|Impressum]] | [[Datenschutzerklärung|Datenschutz]]