In this post, I will share my best practices for getting a handle on your SPF record.
Why it makes sense to have a good SPF procedure in place
In a previous blog post, I explained the limitations of SPF and how it works with DKIM and DMARC. It’s crucial to have a well-structured SPF procedure to avoid future problems, especially since exceeding the DNS lookup limit of 10 can cause issues, such as:
- Your domain is vulnerable to spoofing on the P1 sender domain (
RFC5321.MailFrom
) - Your domain authentication or validation may fail (
spf=PermError
) - Your emails will be undeliverable without any warning
Around the globe you will find an answer to bypass the DNS lookup limit with SPF flattening. This approach converts hostnames to IP addresses, which don’t count in the DNS lookup count.
The dangers of SPF flattening
The problem with SPF flattening is that email service providers can change or add IP addresses without notifying you. As a result, your SPF record becomes inaccurate, leading to complications with email delivery. Yes, there are paid tools available to automate this process. However, SPF flattening also increases the likelihood of forgetting to remove entries that are no longer needed, resulting in over-authorization.
From a security perspective, over-authorization of unnecessary SPF entries creates a potential attack vector. If an adversary gains access to any infrastructure listed in an SPF record, they can bypass your SPF and DMARC to send DMARC-compliant email.
When you segment your vendors and email streams, there is no need for SPF flattening, as subdomain segmentation creates dedicated domains for specific email streams, each with its own 10 DNS lookups. Subdomain segmentation can be implemented in two ways: either by directly using subdomain addresses, such as news@news.yourdomain.com
, or by using an SPF macro that uses a subdomain for a static sender, allowing you to continue sending from your main domain (e.g., news@yourdomain.com
). These subdomain segmentation options can be combined, as covered in this blog. Adopting SPF segmentation increases control, reduces attack surfaces, and mitigates the impact of potential cyber incidents.
SPF flattening attempts to work around the “too many DNS lookups” problem without addressing its underlying causes. Avoiding SPF record flattening will help you get a handle on your SPF record.
How to get a handle on your SPF record
A quick win on how to handle your SPF record:
- Not using entries like
a
andmx
, these mechanisms are often useless and probably should not be included in your SPF record (and other duplicate SPF mechanisms).
For the long term:
Imagine your organization has an SPF record on yourdomain.com
with 9 of the 10 allowed DNS lookups, such as:
v=spf1 ip4:11.222.33.444 ip4:44.33.222.111 ip4:22.33.444.555 ip4:55.66.777.8 ip4:88.99.999.99 ip4:99.88.777.66 mx include:spf.protection.outlook.com include:_spf.salesforce.com include:mail.zendesk.com include:_spf.app1.com include:_spf.app2.com -all
Calculation of DNS lookups:
DNS Lookup | Count |
---|---|
include:spf.protection.outlook.com |
1 DNS Lookup |
include:_spf.salesforce.com |
2 DNS Lookups |
include:mail.zendesk.com |
1 DNS Lookup |
include:_spf.app1.com |
2 DNS Lookups |
include:_spf.app2.com |
2 DNS Lookups |
mx (your MX record) |
1 DNS Lookup |
Total: | 9 DNS Lookups |
Effective segmentation of your email streams is essential to have a handle on the above.
In today’s world, we’re surrounded by numerous SaaS applications that use our primary domain for email correspondence. But is it really necessary for these applications to send through your primary domain when they could just as easily use a separate subdomain with its own SPF TXT
record?
Cut your SPF record
Given the information provided, determine which SaaS applications can be restricted to sending email from a specific address using an SPF macro. Also, determine which services are required to send email through your primary domain from multiple addresses, such as Microsoft 365, and which services are not subject to such restrictions and can send through a subdomain. A helpful approach is to create a list of your SPF record entries and specify the desired behavior for each entry, as shown in the example below:
Look up | Outcome |
---|---|
include:spf.protection.outlook.com |
Used multiple email addresses and must send through the primary domain yourdomain.com |
include:_spf.salesforce.com |
Must send through the primary domain, but can be restricted to send from a specific address invoices@yourdomain.com using an SPF macro |
include:mail.zendesk.com |
Must send through the primary domain, but can be restricted to send from a specific address support@yourdomain.com using an SPF macro |
include:_spf.app1.com |
Used multiple addresses and can send through a subdomain with a new SPF TXT record for app1.yourdomain.com |
include:_spf.app2.com |
Used multiple addresses and can send through a subdomain with a new SPF TXT record for app2.yourdomain.com |
mx |
Duplicate mechanisms, can be removed. When using Microsoft 365, the MX endpoint IP is already listed in include:spf.protection.outlook.com |
If you look at the example above, we have 2 DNS lookups left after cutting the current SPF record for the primary domain:
Look up | Count |
---|---|
include:spf.protection.outlook.com |
1 DNS Lookup |
include:%{l}._spf.yourdomain.com |
1 DNS Lookup, using an SPF macro for both Salesforce and Zendesk |
IP address management in your SPF record
So we cleaned up 7 DNS lookups from the previous 9 DNS Lookups, good job! But what about the IP addresses in the SPF record? IP addresses don’t cost any DNS lookups because we’re not talking to the DNS. One disadvantage of using IP addresses in your SPF record is that it will result in an unmanageable and too long record. So, we can add a new include with the cost of 1 DNS lookup, such as include:_spf.yourdomain.com
.
- In the SPF record for
yourdomain.com
, add the following DNS lookup:
include:_spf.yourdomain.com
- Now we create a new
TXT
record in the DNS zone ofyourdomain.com
listing the IP addresses.
Host | Type | Value |
---|---|---|
_spf.yourdomain.com |
TXT |
v=spf1 ip4:11.222.33.444 ip4:44.33.222.111 ip4:22.33.444.555 ip4:55.66.777.8 ip4:88.99.999.99 ip4:99.88.777.66 -all |
CAUTION: When the SPF record for your IP addresses reaches its limit of two strings of 255 characters, it becomes inaccurate. You should avoid including too many IP addresses. While you can add another include, such as
_spf1.yourdomain.com
, at the cost of another DNS lookup, it is advisable to start segmenting this into subdomains. Also, get into the habit of documenting all of your IP addresses that send mail on behalf of your domain.
NOTE: There is also an SPF macro for IP addresses,
%{i}
, this macro replace the IP address of the SMTP client that submitted the message. However, using two separate SPF macros (because this blog already uses the macro%{l}
) is not advisable due to the limit of two allowed void lookups (NXDomain
). Even if you stay within the limit, there is still a risk of DNS timeouts due to slow DNS responses. Exceeding the limit will result in SPFpermerror
. Publishing an SPF policy that refers to data that does not exist in DNS is a poor practice and raises security concerns (see RFC7208 Section 4.6.4.).
Use an SPF macro to restrict a third-party service to send from a specific address
As described above, third-party services like Salesforce and Zendesk are mostly limited to sending from a single email address, such as invoices@yourdomain.com
and support@yourdomain.com
.
So it is unnecessary to have include:_spf.salesforce.com
and include:mail.zendesk.com
cost 3 DNS Lookups in the SPF record on yourdomain.com
.
Calculate the DNS Lookups from include:_spf.salesforce.com
in yourdomain.com
:
DNS Lookup | Count |
---|---|
include:_spf.salesforce.com |
1 DNS Lookup |
exists:%{i}._spf.mta.salesforce.com |
1 DNS Lookup (child lookup) |
Total: | 2 DNS Lookups |
Calculate the DNS Lookup from include:mail.zendesk.com
in yourdomain.com
:
DNS Lookup | Count |
---|---|
include:mail.zendesk.com |
1 DNS Lookup |
Total: | 1 DNS Lookup |
In order to bring this 3 DNS Lookups to 1 DNS Lookup, you can follow the steps below.
- In the SPF record for
yourdomain.com
, add the following DNS lookup at a cost of 1 DNS Lookup:
include:%{l}._spf.yourdomain.com
The SPF macro
%{l}
replaced with the local-part of the sender’s email address.
- Now we will create two new
TXT
records in the DNS zone ofyourdomain.com
to restrict Salesforce to only send frominvoices@yourdomain.com
and Zendesk to only send fromsupport@yourdomain.com
.
Host | Type | Value |
---|---|---|
invoices._spf.yourdomain.com |
TXT |
v=spf1 include:_spf.salesforce.com -all |
support._spf.yourdomain.com |
TXT |
v=spf1 include:mail.zendesk.com -all |
After setting up the above, Salesfroce’s sending servers can only send from invoices@yourdomain.com
and Zendesk can only send from support@yourdomain.com
.
How the SPF macro %{l} works on the receiving mail server
To summarize what we have done
- The main SPF record is cleaned up by deleting 7 DNS lookups, this with segmenting your email streams with subdomains and using SPF macros.
- We deleted the
mx
DNS lookup because of a duplicate mechanism. - We have set all the IP addresses in a separate include.
- We have restricted a third-party service to send from a specific address using an SPF macro.
Instead of 9 DNS lookups before cleaning, the cleaned SPF record has only 3 DNS lookups with SPF macros:
v=spf1 include:spf.protection.outlook.com include:_spf.yourdomain.com include:%{l}._spf.yourdomain.com -all
Final computation of DNS lookups:
DNS Lookup | Count |
---|---|
include:spf.protection.outlook.com |
1 DNS Lookup |
include:_spf.yourdomain.com |
1 DNS Lookup for the IP addresses |
include:%{l}._spf.yourdomain.comm |
1 DNS Lookup for Salesforce and Zendesk |
Total: | 3 DNS Lookups |
Lastly
For the future of your SPF record, add IP addresses using the separate include, and carefully decide whether a SaaS application should be sent through a subdomain or a static address instead of any address from your primary domain. In addition, make it a habit to monitor your SPF record frequently and document each sender you list.