--- id: PROJ-71 title: TLS-Pflicht (optional) für eingehenden SMTP-BCC-Journaling-Kanal status: Deployed created: 2026-07-08 --- ## Problem Eingehender SMTP-Daemon (`internal/smtpd/`) für BCC-Journaling erlaubt STARTTLS optional, erzwingt es aber nicht. Mails können unverschlüsselt per Klartext eintreffen, obwohl TLS-Zertifikat konfiguriert ist. Sicherheitslücke für den Journaling-Kanal, der Original-Mails 1:1 (Rohbyte-Erhalt für Revisionssicherheit, siehe GoBD-Anforderung) entgegennimmt. ## Lösung Neues optionales Config-Flag `smtp.require_tls` (`config/config.go`, Feld `RequireTLS`). Wenn `true`: - Start-Validierung: Daemon startet nicht, wenn `require_tls: true` gesetzt ist, aber `tls_cert`/`tls_key` fehlen (`internal/smtpd/smtpd.go` `Start()`). - Enforcement bei `MAIL FROM`: Session ohne aktive TLS-Verbindung wird mit `530 5.7.0 Must issue STARTTLS first` abgelehnt, bevor Daten übertragen werden (`session.Mail()`). - TLS-Status pro Session wird beim Verbindungsaufbau via `c.TLSConnectionState()` ermittelt (`backend.NewSession()`). Standardmäßig deaktiviert (`require_tls` fehlt/false) — keine Breaking Change für bestehende Installationen ohne TLS-Zertifikat. ## Implementation Notes - `config/config.go`: `SMTPConfig.RequireTLS bool` `yaml:"require_tls"`. - `internal/smtpd/smtpd.go`: - `session.isTLS bool` Feld, gesetzt in `NewSession()`. - `Start()`: Fehler beim Boot, falls `RequireTLS` ohne Cert/Key. - `session.Mail()`: Reject vor Datenübertragung, spart Bandbreite ggü. Ablehnung erst nach `DATA`. - Rohbyte-Erhalt, Message-ID-Erhalt, Envelope/Header-Trennung (BCC-Journaling) bereits vorhanden und unverändert (siehe Code-Review vom 2026-07-08) — dieses Feature schließt nur die TLS-Lücke im Transportkanal. ## Acceptance Criteria - [x] `require_tls: false`/fehlend → Verhalten unverändert (STARTTLS optional). - [x] `require_tls: true` ohne `tls_cert`/`tls_key` → Daemon-Start schlägt fehl. - [x] `require_tls: true` + Cert/Key gesetzt → Klartext-`MAIL FROM` wird mit 530 abgelehnt, STARTTLS-Verbindung wird angenommen.