SPF
Een SPF-record lijkt op reverse DNS: Het is een DNS-entry (een tekstveld om precies te zijn) dat aangeeft welke computers geauthoriseerd zijn om namens een bepaald domein e-mail te versturen. Zonder SPF-records zal e-mail snel als spam worden aangemerkt. Daarnaast is een domein met correcte SPF-records minder interessant voor spoofing, omdat dat gemakkelijk onthuld kan worden.
Header-meldingen
Voorbeeld van header-meldingen voor een domein waar SPF nog niet is ingesteld: De e-mail is verstuurd naar een Gmail-account:
Received-SPF: none (google.com: info@example.de does not designate permitted sender hosts) client-ip=83.173.149.10; Authentication-Results: mx.google.com; spf=none (google.com: info@example.de does not designate permitted sender hosts) smtp.mail=info@example.de
En nu voor een verbeterde variant (niet precies vergelijkbaar met de situatie hiervoor):
Received-SPF: pass (plesk2.dudsfsd.net: domain of example.de designates 37.79.127.236 as permitted sender) client-ip=37.79.127.236; envelope-from=info@example.de;
Theorie
Een SPF-entry, ook bekend als SPF resource record (RR), komt in twee smaken: SPF RR en SPF TXT RR. Het gaat alleen om deze laatste.
Syntaxis
Enkele identieke manieren om de syntaxis te beschrijven:
v=spf1 [ [sender mechanism] [sender mechanism] ... [modifier1] [modifier2] ] v=spf1 [ [mechanism] [mechanism] ... [modifier1] [modifier2] ] v=spf1 [ [[pre] type] [[pre] type] ... [modifier1] [modifier2] ] v=spf1 [ [[qualifier] type] [[qualifier] type] ... [modifier1] [modifier2] ]
Een SPF TXT RR kan uit meerdere type's bestaan die door een spatie worden gescheiden, en wordt van links naar rechts geëvalueerd. Evaluatie stopt als een passende regels is gevonden, of als het eind van het record is bereikt. Type's moeten dus van specific naar algemeen worden opgegeven. Dit is de reden waarom -all de laatste type in een record is.
spf1
Een record begint verplicht met
v=spf1
Op dit moment is versie 1 de enige bestaande versie.
Qualifiers
Een mechanism kan voorafgegaan worden door een qualifier die aangeeft hoe het betreffende mechanisme geëvalueerd dient te worden:
+ Pass - Dit is de standaardwaarde. Je kunt '+' daarom weglaten - Fail ~ Softfail ? Neutral
Types
Mechanismes om designated outbound mailers te specifieren:
ip4 - Dit IPv4-adres/range mag verzenden ip6 - Dit IPv6-adres/range mag verzenden a - Gebruik DNS A-records voor verificatie mx - Gebruik DNS MX-records voor verificatie ptr - Gebruik DNS PTR-records voor verificatie exists - Test voor het bestaan van een domein include - Incorporeer de positieve types van het gerefereerde SPF-record
Er is een behoorlijke flexibiliteit in de syntaxis van records. Daarnaast is macro-expansion gedefineerd. Zie [1] voor details.
En als laatste: Je kunt maar één SPF-record per domeinnaam hebben. Sommige mensen hadden bedacht om bv. een apart SPF-record voor IPv4 en een apart record voor IPv6 te hebben, maar dat werkt niet.
IPv4, IPv6 & URL's
Ik begreep dat je van een bepaalde server zowel het IPv4-adres als het IPv6-adres moet specificeren, als deze beide gebruikt kunnen worden door de SMTP-server. Daarnaast geloof ik dat je de bijbehorende URL kunt gebruiken om deze beide af te vangen.
ip4-mechanisme
ip4:<ip4-address> ip4:<ip4-network-address>/<prefix-length> <=> <ip4-network-address>/<CIDR>
Waarbij prefix=length hetzelfde is als CIDR, oftewel Classless Inter-Domain Routing. Het getal na de schuine streep, geeft het aantal vastgestelde bits aan in het netmask. Een paar ipv4-voorbeelden:
10.0.0.1/32 → 10.0.0.1 is het basisadres, 32 bits zijn vastgelegd. Masker = 255.255.255.255 → 2^0 = 1 IP-adres beschikbaar 10.0.0.1/30 → 10.0.0.1 is het basisadres, 30 bits zijn vastgelegd. Masker = 255.255.255.252 → 3 IP-adressen beschikbaar 10.0.0.1/24 → 10.0.0.1 is het basisadres, 24 bits zijn vastgelegd. Masker = 255.255.255.0 → 2^8 = 256 IP-adressen beschikbaar 10.0.0.1/20 → 10.0.0.1 is het basisadres, 20 bits zijn vastgelegd. Masker = 255.255.258.0 → ? 10.0.0.1/16 → 10.0.0.1 is het basisadres, 16 bits zijn vastgelegd. Masker = 255.255.0.0 → 2^16 = 1.048.576 IP-adressen beschikbaar 10.0.0.1/8 → 10.0.0.1 is het basisadres, 8 bits zijn vastgelegd. Masker = 255.0.0.0 → 2^24 IP-adressen beschikbaar
ip6-mechanisme
ip6:<ip6-address> ip6:<ip6-network-address</<prefix-length> <=> <ip6-network-address</<CIDR>
Include-mechanisme
Tekst van openspf.org/SPF_Record_Syntax:
include:<domain>
The specified domain is searched for a match. If the lookup does not return a match or an error, processing proceeds to the next directive. Warning: If the domain does not have a valid SPF record, the result is a permanent error. Some mail receivers will reject based on a PermError.
Examples:
In the following example, the client IP is 1.2.3.4 and the current-domain is example.com.
v=spf1 include:example.com -all
- If example.com has no SPF record, the result is PermError.
- Suppose example.com's SPF record were "v=spf1 a -all". Look up the A record for example.com. If it matches 1.2.3.4, return Pass.
- If there is no match, other than the included domain's "-all", the include as a whole fails to match; the eventual result is still Fail from the outer directive set in this example.
Trust relationships — The "include:" mechanism is meant to cross administrative boundaries. Great care is needed to ensure that "include:" mechanisms do not place domains at risk for giving SPF Pass results to messages that result from cross user forgery. Unless technical mechanisms are in place at the specified otherdomain to prevent cross user forgery, "include:" mechanisms should give a Neutral rather than Pass result. This is done by adding "?" in front of "include:". The example above would be:
v=spf1 ?include:example.com -all
In hindsight, the name "include" was poorly chosen. Only the evaluated result of the referenced SPF record is used, rather than acting as if the referenced SPF record was literally included in the first. For example, evaluating a "-all" directive in the referenced record does not terminate the overall processing and does not necessarily result in an overall Fail. (Better names for this mechanism would have been "if-pass", "on-pass", etc.)
Modifiers
Als laatste kan een SPF-regel modifiers bevatten. Er zijn er twee, en ze mogen beiden slechts eenmaal gebruikt worden:
redirect exp
Deze worden hier niet verder behandeld.
Voorbeelden
De MX-entry die bij het domein hoort is ok. De rest niet:
v=spf1 mx -all
Geen enkele server is geauthoriseerd. Dit domein verstuurd waarschijnlijk geen email:
v=spf1 -all
Alle servers zijn geauthoriseerd. Dat is gek:
v=spf1 +all
Het a-record van domein mail.example.com geeft de geauthoriseerde server weer:
v=spf1 a:mail.example.com -all
Allow any IPv6 address between 1080::8:800:0000:0000 and 1080::8:800:FFFF:FFFF:
v=spf1 ip6:1080::8:800:200C:417A/96 -all
Drie IPv4-adressen mogen emailen:
v=spf1 ip4:204.200.197.197 ip4:199.236.109.182 ip4:72.54.24.99 -all
Alle ip-adressen 2a01:7c7:7c7:: - 2a01:7c7:7c7::ff (128-120=8 bits submask) mogen emailen. Dit is een effectieve regel om alle potentiële mailservers van TransIP te dekken:
v=spf1 ip6:2a01:7c7:7c7::/120 -all
Casus Sep. 2015: TransIP Web-Only
Een domein draait op een VPS bij TransIP. Email wordt exterm verzorgd door TransIP. Wat zijn de goede instellingen voor SPF?
Test: Verzenden van een email middels de SMTP Authentication Support-module voor Drupal naar een Gmail-account.
Eerste iteratie (do. 17 sep.) - Fail
Header:
Received-SPF: fail (google.com: domain of info at example5 punt nl does not designate 2a01:7c7:7c7::69 as permitted sender) client-ip=2a01:7c7:7c7::69; spf=fail (google.com: domain of info at example5 punt nl does not designate 2a01:7c7:7c7::69 as permitted sender) smtp.mailfrom=info at example5 punt nl
Tweede iteratie (vr. 18 sep.) - Fail
SPF-record - Vantevoren:
v=spf1 a mx a:transip.nl mx:transip.nl a:mail.example2.nl mx:mail.example2.nl a:submission2.mail.example2.nl a:outbound0.mail.example2.nl -all
Header:
Received-SPF: fail (google.com: domain of info at example5 punt nl does not designate 2a01:7c7:7c7::72 as permitted sender) client-ip=2a01:7c7:7c7::72; spf=fail (google.com: domain of info at example5 punt nl does not designate 2a01:7c7:7c7::72 as permitted sender) smtp.mailfrom=info at example5 punt nl
Nieuw SPF-record:
De verzendende servers hebben ipv6-adressen 2a01:7c7:7c7::69 en 2a01:7c7:7c7::72. Wat zal ik daar 's van maken:
- Van 69 naar 72 is 3 cijfers en dus met 2 bits af te dekken → 2a01:7c7:7c7::69/126 → 2a01:7c7:7c7::69 is het basisadres, en er zijn 2 bits beschikbaar om af te wisselen
- Om het wat ruimer in te stellen: 2a01:7c7:7c7:: → Nu is het laatste octet ongedefineerd. Dat is 16 bits. Dus 128-16 = 112 bits zijn gedefineerd: 2a01:7c7:7c7::/112 - Is dit een geldige notatie?
- Ultratools heeft een aardig tooltje. Met
2a01:7c7:7c7::
en2a01:7c7:7c7::ff
als input, krijg je2a01:7c7:7c7:0:0:0:0:0/120
(256 hosts) als output. Daar kan ik goed mee leven:
v=spf1 ip6:2a01:7c7:7c7:0:0:0:0:0/120 a mx a:transip.nl mx:transip.nl a:mail.example2.nl mx:mail.example2.nl a:submission2.mail.example2.nl a:outbound0.mail.example2.nl -all
Derde iteratie (vr. 18 sep.) - Pass
Header:
Received-SPF: pass (google.com: domain of info@example.com designates 2a01:7c7:7c7::69 as permitted sender) client-ip=2a01:7c7:7c7::69; spf=pass (google.com: domain of info@example.com designates 2a01:7c7:7c7::69 as permitted sender) smtp.mailfrom=info@example.com
Nieuw SPF-record:
Waarschijnlijk kan de spf-regel een stuk korter, en dit is het moment om dat uit te proberen:
v=spf1 ip6:2a01:7c7:7c7::/120 -all
Vierde iteratie (vr. 18 sep.) - Pass
Het ziet er goed uit. Er is een kansje dat dit voorbarig is, en DNS-entries nog niet zijn gepropageerd. Huidige SPF-record:
v=spf1 ip6:2a01:7c7:7c7::/120 -all
Header test-email:
Received-SPF: pass (google.com: domain of info@example.com designates 2a01:7c7:7c7::72 as permitted sender) client-ip=2a01:7c7:7c7::72; spf=pass (google.com: domain of info@example.com designates 2a01:7c7:7c7::72 as permitted sender) smtp.mailfrom=info@example.com
Vijfde iteratie (za. 19 sep.) - Pass
Nu weet ik het zeker. Header:
Received-SPF: pass (google.com: domain of info@example.com designates 2a01:7c7:7c7::72 as permitted sender) client-ip=2a01:7c7:7c7::72; spf=pass (google.com: domain of info@example.com designates 2a01:7c7:7c7::72 as permitted sender) smtp.mailfrom=info@example.com
Naderhand
Alleen een IPv6-adres vermelden, geeft storingen indien ook gebruik wordt gemaakt van IPv4. Je moet beide toevoegen.
Casus sep. 2015: Softfail & VPS
Dit betreft een site met een eigen mailserver, plus dat het iets ingewikkelder ligt.
Eerste iteratie - Softfail
Received-SPF: softfail (google.com: domain of transitioning info@example.com does not designate 2a01:7c8:aaae:5c7:795b:8b65:d534:335e as permitted sender) client-ip=2a01:7c8:aaae:5c7:795b:8b65:d534:335e; spf=softfail (google.com: domain of transitioning info@example.com does not designate 2a01:7c8:aaae:5c7:795b:8b65:d534:335e as permitted sender) smtp.mailfrom=info@example.com Received: by example6-01.colo.example3.net (Postfix, from userid 33)
Nieuwe SPF-regel:
v=spf1 ip6:2a01:7c8:aaae:5c7:795b:8b65:d534:335e MX -all
Tweede iteratie - Fail
Vreemd dat er nu een IPv4-afzender-adres staat. Sois:
Received-SPF: fail (google.com: domain of info@example.com does not designate 37.79.127.236 as permitted sender) client-ip=37.79.127.236; spf=fail (google.com: domain of info@example.com does not designate 37.79.127.236 as permitted sender) smtp.mailfrom=info@example.com Received: by example6-01.colo.example3.net (Postfix, from userid 33)
Nieuwe SPF-regel:
v=spf1 ip4:37.79.127.236 ip6:2a01:7c8:aaae:5c7:795b:8b65:d534:335e MX -all
Casus Sep. 2015: Fail of niet?
Beginsituatie
In een vlijtige bui heb ik het SPF-record van een domein 'verbeterd' en nu geeft het soms foutmeldingen. Dit is de foutregel die bij een terugkerende email gegeven werd:
5.7.1 failed SPF. The SPF-record you have published in your DNS is invalid
Dit is de header van een email dat ik vanuit het betreffende account naar een eigen Gmail-account heb gestuurd:
Received: by 10.37.93.8 with SMTP id r8csp2225592ybb; Received: from outbound2.mail.example2.nl (outbound2.mail.example2.nl. [2a01:7c7:7c7::73]) Received-SPF: pass (google.com: domain of info@example.nl designates 2a01:7c7:7c7::73 as permitted sender) client-ip=2a01:7c7:7c7::73; Authentication-Results: mx.google.com; spf=pass (google.com: domain of info@example.nl designates 2a01:7c7:7c7::73 as permitted sender) smtp.mailfrom=info@example.com
Eerste iteratie - Di. 29 sep.
Nieuwe SPF-regel. Deze is een verruiming van de oorspronkelijke regel. De toevoeging include:_spf.example3.email
is de standaard-SPF-regel die TransIP lijkt toe te passen bij aanvraag van een Email-Only-account:
v=spf1 include:_spf.example3.email ip4:37.79.127.236 ip6:2a01:7c7:7c7::/120 -all
Tweede iteratie - Wo. 30 sep.
Opnieuw met succes een testmail verstuurd:
Received: from outbound0.mail.example2.nl (outbound0.mail.example2.nl. [2a01:7c7:7c7::69]) Received-SPF: pass (google.com: domain of info@example.com designates 2a01:7c7:7c7::69 as permitted sender) client-ip=2a01:7c7:7c7::69; Authentication-Results: mx.google.com; spf=pass (google.com: domain of info@example.com designates 2a01:7c7:7c7::69 as permitted sender) smtp.mailfrom=info@example.com
Geen wijzigingen aangebracht aan de SPF-regel.
Casus okt. 2015: SMTP via Ziggo
Iemand gebruikte SMTP van Ziggo voor versturen van email via een werkstation. Zoals de meeste providers, gebruikt Ziggo meer dan één IP-adres/URI voor uitgaande email. Dit is het rijtje dat ik heb kunnen achterhalen:
smtpq1.tb.mail.iss.as9143.net (212.54.42.164) smtpq5.tb.mail.iss.as9143.net (212.54.42.168) smtpq6.tb.mail.iss.as9143.net (212.54.42.169)
Dit is gemakkelijk te vangen in een subnet, bv.:
212.54.42.1/24
maar dat dekt alleen IPv4 en niet IPv6. Daarom wellicht handig om te werken met URL's:
smtpq1.tb.mail.iss.as9143.net/24
Daarnaast kwam ik in een posting ook nog dit rijtje tegen:
smtpq1.gn.mail.iss.as9143.net (212.54.42.164) smtpq4.gn.mail.iss.as9143.net (212.54.42.168)
en dat is te vangen in bv.:
smtpq1.gn.mail.iss.as9143.net/24
Casus nov. 2015: SMTP via VPS
Deze casus lijkt op deze casus hierboven
Casus juni 2016: SMTP via KPN Exchange
Email wordt verstuurd door een mail server van KPN: cpsmtpb-ews05.kpnxchange.com (213.75.39.8)
. De betreffende openspf-pagina suggereert als toevoeging aan het SPF-record:
v=spf1 [...] a:cpsmtpb-ews05.kpnxchange.com -all
Oplossing 10 juni 2016
- Toegevoegd aan spf-record:
a:kpnxchange.com
- Is dit voldoende, of moet het geëxpandeerd worden naar een compleet CIDR-subnet?
Zie ook
Bronnen
- http://www.openspf.org/SPF_Record_Syntax - Mijn belangrijkste bron
- http://stackoverflow.com/questions/6110534/how-to-create-spf-record-for-multiple-ips
- http://www.microsoft.com/mscorp/safety/content/technologies/senderid/wizard/default.aspx
- http://stackoverflow.com/questions/6110534/how-to-create-spf-record-for-multiple-ips
- http://www.zytrax.com/books/dns/ch9/spf.html - Grondig!
- http://www.zytrax.com/tech/protocols/ip-classes.html#cidr
- http://serverfault.com/questions/29777/will-adding-a-second-spf-record-mess-up-my-dns