Alan Doherty's things anyone setting up a sender policy framework record properly should know
or How Not to make the same mistakes everyone else keeps repeating
I'm a Network/IT Consultant based in Dublin and a regular contributer on the SPF help mailinglist.
I have seen a lot of bad SPF records in my time, and spf records seem to consistently be poorly written/understood
So if you are setting up a new SPF or checking up on your existing setup competency here are some tips
all do depend on you actually knowing how you do send ALL legitimate outbound mail
Obviously if unsure please get in touch via the mailinglist or contact me direct rather than guessing, I do this to improve the 'ecosystem' as more (easily recognisable) good senders makes bad ones easier to reject
Do not make others perform unnecessary DNS lookups
Parsers of your spf record have limited resources, do not abuse them, here are some simple and common examples
a:mx-host-1 a:mx-host-2
etc here, as you are the admin you already know this list of host-names so just put them in yourself and save everyone the hassle, more importantly you may notice that few of these hosts actually can't/shouldn't send outbound email and you may notice many of these listed can be further reduced by the next principlea:example.com
where example.com is the sender, thus telling people to lookup example.com's ip(s) and substitute them here (normally the ip of your webserver), as you are example.com you already know these ip(s) (and if they actually can send email) so just put them in yourself and save everyone the hassle, ditto for a:something.example.comthere is one exception discussed later when an
a:somename-within-your-own-domain
can be used to compress an spf recordinclude:
SPF record to use instead is worthwhilea:somename-within-your-domain
but if domain-name + spf-txt > 450 characters its gotten too long for a single record
remember you can go to 255 characters in a DNS TXT line, and multiple lines in an spf record some dns editors dont allow multiline entries (use a better provider) but all allow 255
if your provider allows multiline strings then if length-of-domain-name + length-of-string1 + length-of-string2 <450 your SPF record will fit in a 512 byte response and get back to even the oldest most badly setup DNS servers behind the worst broken firewalls
if you have more host address's than can fit in a single record you can chain records via include or redirect, but do it smartly
would the record be short enough without them?
move them to an a: record as described above up to 30 per A record textually longest first ;)
v=spf1 include:sub-recordA include:sub-recordB -all
Good Chaining:
v=spf1 .............................................................................contents-of-subrecord-a..................................................................... include:sub-recordB -all
basically fill the first record to bursting point leaving only enough room for 1 include or redirect to the next, do simmilar with next
spf is not just for envelope sender
- setup SPF records for all HELO/EHLOs in use
- if you own/operate any of the mailservers in use sending email secure their HELO/EHLO idenity names with SPF records also
- setup SPF records for all non email names in your zone
- all names not used in helo/ehlo and envelopes of emails should have null spf records, '
v=spf1 -all
'
avoid conflicts with poeple who mistakenly still check sender-id (everyone with MS-Exchange/office365)
sender-id (a horrible failed microsoft experiment) abused SPF records as sender-id policies if an explicit sender-id record was not found.
Obviously issues arose because sender-id checks both the envelope-sender AND against the Resent-Sender/Resent-From/Sender/From: header(s) , so an email recieved via a mailinglist/SRS-compliant-forwarder/any indirect method, with a correct envelope of listname@example.net will have the resenders ip checked erroniously against your SPF record if the from: is you@yourdomain.
To avoid having your SPF record mis-used this way you SHOULD define a permissive sender-id policy for PRA , optionally a complete sender-id (but I wouldn't as it further extends the usefull life of the should be dead sender-id protocol and clients)
If you use microsoft exchange disable sender-id 'feature'
if your spf record for example.com states
v=spf1 ip4:20.40.60.0/25 include:_spf.google.com -all
this is equivalent to a sender ID mail envelope from policy
spf2.0/mfrom ip4:20.40.60.0/25 include:_spf.google.com -all
but to avoid it causing mailing list mail to fail you must define a non failing (ending ?all) pra policy
spf2.0/pra ip4:20.40.60.0/25 include:_spf.google.com ?all
in other words positive pass mail from your ips but treat as neutral mail from other ips (don't break mailinglists/forwarders/legit partners/esps)
the best option is just have a open policy for people checking sender-id pra, and ignore other use cases
spf2.0/pra ?all
< < < < < < < < This is what I reccomend all domains configure alongside their SPF only
or the tempting option to make all sender-id users filtering fail (but I wouldn't advise it)
spf2.0 +all
aka 'if checking sender-id just accept all forgeries from everyone'
* Trust : can extend beyond machines you own/operate if you trust the owner/operator. example you send via a smarthost(s) ip(s) in providernameX as you already trust the provider and must assume they will assist to stop their other customers from forging email sent as you via this/these same smarthost(s) it is equally safe to trust the providers server netblock (if provider suggests/says no others operate machines within it) as it gives them the ability to move/replace/expand, and gives you no greater attack surface in real terms
Last updated Sept. 2017 Alan DohertyPlease feel free to donate Pizza/Beer/Candy/IoT gadget money to me if any of the free software or advice given was worthwhile to you.