← Zurück zum BlogRatgeber

SPF too many DNS lookups: den PermError bei 10 Abfragen beheben

Warum SPF nach 10 DNS-Abfragen permerror liefert, welche Mechanismen zählen, wie Sie Ihren Record von Hand zählen, welche Lösungen länger halten als Flattening.

Veröffentlicht: · 7 Min. Lesezeit

Ein SPF-Record darf pro Prüfung höchstens zehn Terme auslösen, die eine DNS-Abfrage verursachen. include, a, mx, exists, redirect und ptr zählen, und alles innerhalb verschachtelter Includes zählt ebenfalls. ip4, ip6 und all kosten nichts. Die elfte Abfrage beendet die Auswertung mit permerror, und ein permerror ist kein pass: Für DMARC hat SPF dann schlicht nicht bestanden. Die dauerhafte Lösung besteht darin, weniger Dienste im Record zu haben, nicht darin, sie geschickter zu verstecken.

Die Regel stammt aus RFC 7208, Abschnitt 4.6.4.

Was zählt und was nicht

Term Zählt zu den 10? Anmerkung
include: Ja Plus jeder zählende Term im eingebundenen Record, rekursiv
a Ja Auch a:host.example.com
mx Ja Hat zusätzlich ein eigenes Limit, siehe unten
exists: Ja Meist zusammen mit Makros im Einsatz
redirect= Ja Ein Modifikator, löst aber eine Abfrage aus
ptr Ja Vom RFC selbst als veraltet eingestuft; entfernen
ip4:, ip6: Nein Adressen im Klartext, kein DNS nötig
all Nein
exp= Nein Wird nur abgerufen, um nach einem fail einen Erklärungstext zu bilden

Das Limit gilt für eine SPF-Auswertung als Ganzes. Der erste Abruf Ihres eigenen TXT-Records wird nicht gezählt; alles, was dieser Record danach auslöst, schon.

Zwei weitere Limits im selben Abschnitt

  • Auffächerung bei mx und ptr. Die Auswertung eines einzelnen mx-Mechanismus darf nicht zu mehr als zehn Adressabfragen für die zurückgegebenen MX-Namen führen (dieselbe Obergrenze gilt für die Namen, die ptr findet). Eine Domain mit mehr als zehn MX-Hosts erzeugt über diesen Weg einen permerror, selbst wenn die Gesamtzahl der Terme niedrig ist.
  • Leere Abfragen (void lookups). Eine Abfrage, die NXDOMAIN oder eine leere Antwort liefert, ist ein „void lookup“. Der RFC sagt, dass Empfänger davon höchstens zwei pro Auswertung zulassen SOLLTEN und darüber hinaus permerror zurückgeben. Zwei tote Includes, die von gekündigten Diensten übrig geblieben sind, können dafür schon reichen.

Und ein Klassiker, der nichts mit Zählen zu tun hat

Zwei TXT-Records, die unter demselben Namen mit v=spf1 beginnen, ergeben ebenfalls einen permerror. Das passiert, wenn die Anleitung eines neuen Anbieters „fügen Sie diesen SPF-Record hinzu“ sagt und jemand genau das tut. Führen Sie die Mechanismen in einem einzigen Record zusammen.

Warum die Fehler unregelmäßig wirken

Permerror bedeutet „dieser Record lässt sich nicht auswerten“. Was ein Empfänger daraus macht, ist seine eigene Richtlinie: Manche behandeln es wie fail, andere wie neutral. DMARC fragt nur, ob SPF ein pass mit Alignment geliefert hat, und permerror ist kein pass. Trägt Ihre E-Mail zusätzlich eine DKIM-Signatur mit Alignment, besteht DMARC trotzdem, und der kaputte SPF-Record fällt monatelang niemandem auf. Bis eine Nachricht ohne DKIM (ein vergessener Anwendungsserver, ein Scanner) bei einem Anbieter zurückkommt und bei einem anderen ankommt.

Die Reihenfolge der Mechanismen trägt zur Verwirrung bei. SPF wertet von links nach rechts aus und hält beim ersten Treffer an. Ein Absender, auf den Ihr zweiter Mechanismus passt, erreicht die elfte Abfrage nie; ein Absender, der am Ende des Records steht, schon. Derselbe Record kann also für Ihren Postfachanbieter bestehen und für Ihr Rechnungssystem permerror liefern.

Den Record von Hand zählen

Beginnen Sie mit dem Record selbst:

$ dig +short TXT example.com | grep spf1
"v=spf1 mx a include:_spf.mailprovider.example include:spf.newsletter.example include:spf.crm.example include:spf.helpdesk.example ip4:192.0.2.10 -all"

Folgen Sie dann jedem Include und jedem Include darin:

$ dig +short TXT _spf.mailprovider.example
"v=spf1 include:_netblocks1.mailprovider.example include:_netblocks2.mailprovider.example include:_netblocks3.mailprovider.example ~all"

$ dig +short TXT _netblocks1.mailprovider.example
"v=spf1 ip4:198.51.100.0/24 ip6:2001:db8:10::/48 ~all"

Notieren Sie eine Zeile je zählendem Term:

Term in example.com Eigene Kosten Verschachtelte Kosten Zwischensumme
mx 1 0 1
a 1 0 1
include:_spf.mailprovider.example 1 3 Includes 4
include:spf.newsletter.example 1 1 Include 2
include:spf.crm.example 1 1 Include + 1 a 3
include:spf.helpdesk.example 1 0 1
ip4:192.0.2.10 0 0 0
Summe 12

Zwölf: permerror für jeden Absender, der nicht früh im Record gefunden wird. Beachten Sie, dass das all in einem eingebundenen Record Ihre Auswertung nicht beendet; ein Include spielt nur dann eine Rolle, wenn es ein pass liefert.

Lösungen, in der Reihenfolge, in der Sie sie versuchen sollten

1. Entfernen, was Sie nicht mehr nutzen

Die meisten Records über dem Limit enthalten mindestens einen Dienst, der vor Jahren gekündigt wurde. Jeder entfernte Anbieter gibt typischerweise ein bis vier Abfragen frei. Zugleich schließt das eine Lücke: Ein Include autorisiert die Versandadressen der Plattform für Ihre Domain, und auf gemeinsam genutzter Infrastruktur transportieren diese Adressen auch die E-Mails anderer Kunden.

2. a und mx durch Adressen ersetzen

mx und a sind bequeme Voreinstellungen, die viele Generatoren einfügen. Versendet Ihr Webserver keine E-Mails, ist a nutzlos. Versenden die Hosts in Ihren MX-Records nicht Ihre ausgehenden E-Mails (üblich bei E-Mail beim Anbieter, wo dessen Include den Versand abdeckt), ist auch mx nutzlos. Wo ein Server tatsächlich versendet und seine Adresse stabil ist, schreiben Sie stattdessen ip4:192.0.2.10 oder ip6:2001:db8::25: null Abfragen.

3. Prüfen, ob der Dienst Ihre Domain im Envelope überhaupt verwendet

SPF prüft die Domain des Envelope-Absenders (MAIL FROM, später als Return-Path sichtbar), nicht den From-Header, den Menschen sehen. Viele E-Mail-Dienstleister verwenden dort ihre eigene Bounce-Domain. In diesem Fall fragt der Empfänger deren SPF-Record ab, niemals Ihren, und deren Include in Ihrem Record kostet Abfragen, ohne etwas zu bewirken.

Öffnen Sie eine Nachricht, die der Dienst tatsächlich versendet hat, und lesen Sie die Header:

Return-Path: <bounce-7f3a@bounces.newsletter.example>
From: Example Shop <news@example.com>

Return-Path liegt nicht unter example.com, also kann include:spf.newsletter.example aus Ihrem Apex-Record verschwinden. Was diese E-Mail DMARC bestehen lässt, ist eine DKIM-Signatur mit d=example.com oder ein eigener Return-Path (nächster Schritt).

4. Jedem versendenden Dienst eine eigene Subdomain geben

Das Limit gilt je Auswertung, und jede Auswertung beginnt bei der Envelope-Domain. Versenden Sie Newsletter von news.example.com und Transaktions-E-Mails von billing.example.com, dann bekommt jeder Name seinen eigenen Record und sein eigenes Budget von zehn:

news.example.com.     TXT  "v=spf1 include:spf.newsletter.example -all"
billing.example.com.  TXT  "v=spf1 include:spf.invoicing.example -all"

Die meisten Plattformen setzen das als „custom return-path“ oder „eigene Bounce-Domain“ um: Sie legen einen CNAME wie bounce.news.example.com an, der auf den Anbieter zeigt, und der SPF-Record liegt vollständig auf dessen Seite. Im relaxed Alignment (der DMARC-Voreinstellung) passt bounce.news.example.com zu einer From-Adresse unter example.com. SPF-Records werden nicht vererbt, eine Subdomain ohne eigenen Record hat also keinen.

5. Auf DKIM mit Alignment setzen

DMARC braucht ein bestandenes Ergebnis mit Alignment, SPF oder DKIM. Für jeden Dienst, der mit Ihrer Domain in d= signieren kann, reicht DKIM allein, und es übersteht Weiterleitungen, was SPF nicht tut (siehe Warum E-Mail-Weiterleitung SPF bricht). Genau das macht Schritt 3 ungefährlich.

6. Flattening, nur mit Automatisierung

„Flattening“ ersetzt jedes Include durch die IP-Bereiche, zu denen es gerade auflöst. Die Zahl der Abfragen sinkt auf null, und der Record funktioniert heute. Das Problem ist morgen: Anbieter nehmen Bereiche hinzu und außer Betrieb, ohne Ihnen Bescheid zu sagen, und an dem Tag, an dem sie das tun, scheitert ein Teil Ihrer legitimen E-Mails an SPF, mit einem Record, der völlig gültig aussieht. Wenn Sie flatten, muss es ein Prozess sein, der die Includes regelmäßig neu auflöst und den Record neu veröffentlicht, und diesen Prozess müssen Sie überwachen. Ein von Hand geflatteter Record ist ein Ausfall mit Verzögerung.

Geflattete Records werden außerdem lang. Eine TXT-Zeichenkette fasst höchstens 255 Byte; längere Records werden auf mehrere Zeichenketten verteilt, die Empfänger ohne Leerzeichen aneinanderhängen. Eine Trennung an der falschen Stelle klebt also zwei Mechanismen zusammen. Halten Sie auch die gesamte Antwort klein: Antworten über der traditionellen UDP-Größe von 512 Byte hängen von EDNS0 oder dem Ausweichen auf TCP ab, und der RFC rät, darunter zu bleiben.

7. Makros

SPF-Makros (exists:%{i}._spf.example.com) können viele Absender in einer einzigen Abfrage zusammenfassen. Sie brauchen ein dafür gebautes DNS-Backend und sind schwer zu debuggen: keine Lösung für den ersten Griff.

~all gegenüber -all hat mit alledem nichts zu tun: Der Qualifikator bei all entscheidet, was mit nicht passenden Absendern geschieht, und kostet in keinem Fall eine Abfrage.

Häufige Fehler

  • Nur die Includes zählen, die im obersten Record sichtbar sind, und die verschachtelten vergessen.
  • Ein include: für einen Dienst ergänzen, dessen Return-Path auf seiner eigenen Domain liegt.
  • Includes gekündigter Dienste stehen lassen: Sie kosten Abfragen und, sobald der Anbieter den Namen löscht, leere Abfragen.
  • Einen zweiten v=spf1-Record veröffentlichen, statt den ersten zu bearbeiten.
  • Einen langen Record in Zeichenketten zu 255 Byte aufteilen und an der Nahtstelle das Leerzeichen zwischen zwei Mechanismen verlieren.

Wenn Sie einen Record von Grund auf neu aufbauen, setzt der SPF-Generator die Syntax zusammen; gezählt werden muss trotzdem anhand der tatsächlich veröffentlichten Includes.

Mit OrbitProbe prüfen

Der SPF-Check von OrbitProbe fragt den SPF-Record einer Domain ab und weist auf die Probleme hin, an denen er am häufigsten scheitert: mehr als ein Record, +all, ein fehlender all-Mechanismus und zu viele DNS-Abfragen. Führen Sie ihn für die Apex-Domain aus und danach getrennt für jede Subdomain, die E-Mails versendet, denn jeder Name wird für sich ausgewertet. Eine DNS-Abfrage zeigt, was in diesem Moment veröffentlicht ist; ob Ihre E-Mails angenommen werden, kann sie nicht zeigen, also lesen Sie weiterhin Ihre DMARC-Berichte. Wie die vier Mail-Records voneinander abhängen, erklärt MX, SPF, DKIM und DMARC erklärt, und für eine vollständige Prüfung der Zustellung gibt es die DNS-Checkliste für E-Mails im Spam.