# Zustellbarkeit ausgehender Mails Die Anwendung setzt alle Kopfzeilen korrekt, aber ob eine Mail im Posteingang oder im Spam landet, entscheidet sich überwiegend im DNS und beim Relay – nicht im Anwendungscode. Diese Notiz trennt beides sauber. ## Was die Anwendung erledigt | Kopfzeile | Warum | |---|---| | `Date` | Fehlt sie, werten praktisch alle Filter ab | | `Message-ID` | Mit der Domain aus `SMTP_ENVELOPE_FROM`, damit sie zur DKIM-Signatur passt | | `From` mit Anzeigename | RFC-konform kodiert über `email.headerregistry` | | `Reply-To` | Optional, wenn Antworten woanders hin sollen | | `Auto-Submitted: auto-generated` | RFC 3834 – unterdrückt Abwesenheitsschleifen | | `X-Auto-Response-Suppress: All` | Dasselbe für Exchange/Outlook | | EHLO-Hostname | Aus `SMTP_HELO_HOSTNAME` statt der Container-ID | | Envelope-From getrennt vom `From` | SPF wird gegen den Envelope geprüft | Der Versand wiederholt sich bei temporären Fehlern mit wachsendem Abstand (2 s, 4 s, 8 s). Bei permanenter Ablehnung – Empfänger unbekannt, Absender abgelehnt, Authentifizierung fehlgeschlagen – bricht er sofort ab, statt das Relay weiter zu belasten. ## Was du im DNS einrichten musst Ohne diese drei Einträge landen Mails auch bei perfektem Code im Spam. Alle beziehen sich auf die Domain aus `SMTP_ENVELOPE_FROM`. **SPF** – erlaubt deinem Relay, für die Domain zu senden: ``` example.de. IN TXT "v=spf1 mx a:mail.example.de -all" ``` `-all` (hard fail) ist strenger als `~all` und wird von Empfängern besser bewertet. Setze es erst, wenn du sicher bist, dass alle legitimen Absender erfasst sind. **DKIM** – signiert ausgehende Mails. Die Signatur erzeugt das Relay, nicht diese Anwendung. In Postfix über OpenDKIM oder rspamd, in mailcow ist es eingebaut. Der öffentliche Schlüssel gehört ins DNS: ``` selector._domainkey.example.de. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBg..." ``` Wichtig: Die signierende Domain (`d=` in der Signatur) muss zur Domain im `From`-Header passen, sonst schlägt die DMARC-Ausrichtung fehl. **DMARC** – sagt Empfängern, was bei Fehlschlägen passieren soll: ``` _dmarc.example.de. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.de; adkim=s; aspf=s" ``` Fang mit `p=none` an und wertet die Reports ein paar Wochen aus, bevor du auf `quarantine` oder `reject` gehst. **PTR (Reverse DNS)** – die IP deines Relays muss auf einen Namen auflösen, der vorwärts wieder auf dieselbe IP zeigt. Bei Hetzner setzt du das im Cloud-Console-Interface bzw. im Robot. Fehlt der PTR, weisen einige große Anbieter direkt beim `MAIL FROM` ab. ## Ausrichtung von From und Envelope-From DMARC verlangt, dass mindestens eine der beiden Prüfungen *ausgerichtet* ist: - **SPF-Ausrichtung:** Domain in `SMTP_ENVELOPE_FROM` = Domain in `SMTP_FROM` - **DKIM-Ausrichtung:** signierende Domain = Domain in `SMTP_FROM` Mit `adkim=s; aspf=s` im DMARC-Record verlangst du exakte Übereinstimmung (nicht nur die Organisationsdomain). Das ist strenger und sicherer, bedeutet aber: `bounces@example.de` und `einkaufsapp@example.de` sind ausgerichtet, `bounces@bounce.example.de` wäre es nicht mehr. ## Testen Vor dem ersten echten Versand: ```bash # Verbindung zum Relay prüfen, ohne etwas zu senden curl -s -b cookies.txt localhost:8000/api/admin/mail/check | jq # Testnachricht auslösen CSRF=$(grep ea_csrf cookies.txt | awk '{print $7}') curl -s -b cookies.txt -H "X-CSRF-Token: $CSRF" \ -X POST localhost:8000/api/admin/mail/test \ -H 'Content-Type: application/json' \ -d '{"to":"dein-postfach@example.de"}' docker compose logs --tail=20 api ``` Für eine unabhängige Bewertung eignet sich ein Dienst, der dir eine Wegwerf-Adresse gibt und die eingehende Mail auf SPF, DKIM, DMARC, PTR und Inhaltsmerkmale prüft – etwa `mail-tester.com`. Alles unterhalb von 8/10 lohnt das Nachbessern. Achte in der Auswertung besonders auf: - `SPF: pass` mit der Envelope-Domain - `DKIM: pass` mit `d=` gleich der From-Domain - `DMARC: pass` - kein Eintrag auf Spamhaus/Barracuda für deine Relay-IP ## Häufige Ursachen für Spam-Einstufung | Symptom | Ursache | |---|---| | Landet bei Gmail im Spam, sonst nirgends | Fehlender oder falscher PTR-Eintrag | | DKIM `pass`, DMARC `fail` | Signierende Domain weicht von der From-Domain ab | | SPF `softfail` | Relay-IP nicht im SPF-Record der Envelope-Domain | | Alles `pass`, trotzdem Spam | Neue Domain ohne Sendereputation – das gibt sich nach einigen Wochen regelmäßigen Versands | | Outlook/Hotmail blockt | Microsoft verlangt oft eine Anmeldung beim SNDS-Programm |