SPF, DKIM, DMARC? Demystifying Sender Authenticated Domains

 

Do you know how to secure your email sending domain? This is an imporant step in the implementation of any marketing automation system or email server. Did you ever wonder what SPF, DKIM and DMARC stand for and how it helps your emails reach the inbox of your subscribers?

General Information

It is far more convenient to type “markus.codes” into your browser rather than “46.101.151.122”, right?! That’s what the Domain Name System (DNS) allows you to do. If you wonder what this has to do with sending authenticated emails - all of the above mechanisms (SPF, DKIM, DMARC) are based on the Domain Name System (DNS) and specific entries to a so called “zone” which basically represents a distinct part of the domain namespace, so essentially this could be an entire domain like “markus.codes” or a subdomain like “email.markus.codes”.

There are multiple DNS servers across the globe that each manage a subset of all DNS information that is out there. Your computer uses a specific DNS server (for example 8.8.8.8 which is one of Google’s DNS servers) for all the name resolutions. If this server doesn’t have this information it contacts another DNS server, which can either answer or ask another server. So DNS is a global hierarchical and decentralized system.

If you use a Marketing Automation system like Salesforce Marketing Cloud it is very likely that you need to configure those records during setup or your entire domain is delegated to the vendor. For Marketing Cloud customers this is the case when configuring a “Private Domain” or a “Sender Authentication Package”. However, these configurations add a couple of other things to your DNS records that are necessary for other functionality of the platform. Marketing Cloud’s Sender Authentication Package for example also adds entries to ensure a consistent branding across the platform/business unit by using a subdomain of your designated sender domain for link-wrapping in emails, hosting CloudPages, hosting portfolio assets like images via a CDN, etc. Even if you let your provider or IT department configure those records it is vital to understand the impact of those records and which directives are necessary to ensure the authentication measures have the desired effect and how you can gain insights into the use of your domain.

But now let’s dive into the specific measures that are relevant for sending authenticated emails.

Sender Policy Framework (SPF)

The Sender Policy Framework allows domain owners to define which IP addresses and hostnames (representing email servers) are allowed to send emails using the domain in question as sender in the “envelope from” address. These addresses are put into an SPF record that is published in the DNS and requested by email servers that receive an email from that domain. However, this isn’t mandatory, but most modern email servers and all of the most widely used email providers do check them.

Composition of a SPF record

A SPF record basically is a TXT-record published in the DNS, that contains the following information:

  • version of the spf record (e.g. v=spf1)
  • allowed IP addresses (e.g. ip4:46.101.151.122)
  • allowed hosts (e.g. include:cust-spf.exacttarget.com)
  • policy to be applied (either -all, ~all or +all), indicating if non authorized emails should be blocked, accepted but marked as failed or allowed to be delivered

An example record could look like this:

v=spf1 ip4:46.101.151.122 include:cust-spf.exacttarget.com -all

Benefits of using SPF

  • Improved inbox deliverability
  • Reduced risk of maliciously using your domain (spoofing/phishing)

Domain Keys Identified Mail (DKIM)

This authentication mechanism adds the possibility to let the recipient server verify if an email has been cryptographically signed correctly. In order to do so the public key of the digital signature is placed in a TXT entry in the DNS and every server that is authorized to send emails from that domain needs to be aware of that signature key pair’s private key. The email is then signed and the signature added to the email without being visible to the recipient unless the raw email is viewed. If multiple systems are used there is the possibility to add selectors to the DKIM records so the private keys don’t need to be shared amongst the systems. As with SPF checking DKIM signatures isn’t mandatory but all of the leading email service providers do check all emails they receive for a valid DKIM signature.

Composition of a DKIM record

As already mentioned, a DKIM record basically is a TXT-record published in the DNS. The most important parts are:

  • version of the protocol (e.g. v=DKIM1)
  • base64 encoded public key (e.g. p=MIGfMA0GCSqGSIb3DQE…)
  • cryptographic mechanism used to decode the signature (e.g. k=rsa)

An example entry could look like this:

v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQ...

Benefits of using DKIM

  • Improved inbox deliverability
  • Reduced risk of maliciously using your domain (spoofing/phishing)
  • Ensures the email content hasn’t been tempered with

Domain-based Message Authentication, Reporting and Conformance (DMARC)

DMARC is a system that works on top of SPF and DKIM and lets you define a policy how a email service provider should handle emails that don’t comply with both SPF and DKIM. But in my opinion the best thing about DMARC is the added reporting capabilities. It lets you define recipients for reports of domain use and misuse, so you or an admin in your organization is informed about who is sending email on your behalf. As you might have guessed, email providers don’t have to take DMARC records into account, but most of them do. There are two report types that come with DMARC:

RUA - Aggregated reports

  • a daily digest
  • overview of email traffic
  • includes IP addresses of systems who tried to send on your behalf

Example of a RUA-report:

In the “report metadata” at the top, you can see information about the time range the report is about and who submitted it to you. The “policy published” section tells you which policy the submitter knows for your domain so basically this is everything that the email provider fetched from DNS. This should be exactly the same as you configured in your records - however due to the nature of how DNS works your upates could take up to 48 hours until they are visible for all email service proviers globally.

The records section then shows all the reults that are reported by the provider containing the source ip, from header and the resuts of the authentication check.

<?xml version="1.0" encoding="UTF-8" ?>
<feedback>
  <report_metadata>
    <org_name>google.com</org_name>
    <email>noreply-dmarc-support@google.com</email>
    <extra_contact_info>https://support.google.com/a/answer/2466580</extra_contact_info>
    <report_id>12345678912345678900</report_id>
    <date_range>
      <begin>1595894400</begin>
      <end>1595980799</end>
    </date_range>
  </report_metadata>
  <policy_published>
    <domain>markus.codes</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>reject</p>
    <sp>reject</sp>
    <pct>100</pct>
  </policy_published>
  <record>
    <row>
      <source_ip>xxx.xxx.xxx.xxx</source_ip>
      <count>1</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>pass</dkim>
        <spf>pass</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>markus.codes</header_from>
    </identifiers>
    <auth_results>
      <dkim>
        <domain>markus.codes</domain>
        <result>pass</result>
        <selector>50dkim1</selector>
      </dkim>
      <spf>
        <domain>markus.codes</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
</feedback>

RUF - Immediate forensic reports

  • sent in real time
  • only sent for emails that failed authentication
  • includes message headers
  • includes original message (only true for some email service providers)

Composition of a DMARC record

As with all of the mechanisms described in this article, DMARC as well is a TXT-record published in the DNS. The most important parts are:

  • version of the protocol (e.g. v=DMARC1)
  • policy to be applied to mails that fail SPF and/or DKIM (e.g. p=reject)
    • none: DKIM is just used for reporting
    • quarantine: most providers deliver the email to junk/spam folders
    • reject: tell providers to reject the message (-> bounce; no inbox delivery)
  • recipient of rua reports (e.g. rua=mailto:domainadmin@markus.codes)
  • recipient of ruf reports (e.g. ruf=mailto:domainadmin@markus.codes)
  • percentage of emails to apply DMARC-rules on (e.g. pct=100 - this setting defaults to 100%, if you implement DMARC for already running systems you might want to gradually increase that value)

An example entry could look like this:

v=DMARC1; p=reject; rua=mailto:domainadmin@markus.codes; ruf=mailto:domainadmin@markus.codes; pct=100

Benefits of using DMARC

  • all the benefits of SPF and DKIM (if those records are configured properly)
  • additional directions for email service provides
  • reporting of domain use and misuse

Recommendation

If you have the possibility to automatically process the incoming reports or only have a small email volume (like for a personal email domain), set up rua- as well as ruf-reporting. If you only check the reports manually, ruf might be a better fit for you, as you only receive the report if a send fails authentication, which reduces the risk of missing such important information.

How to check if those records are already set up?

As DNS servers are available globally and everybody is allowed to query them you can easily check those records with your tool of choice. I’ll describe how you can retrieve those records using MacOS/Linux/Unix systems using the dig-command, but when working on a Windows machine this can also be done using slightly different syntax using the nslookup-command.

Check for SPF records

In oder to query a domain for SPF records, open the terminal and enter the following command (replace markus.codes with your domain of choice):

dig markus.codes TXT

The result shows a bunch of information, but the interesting part is contained in the “ANSWER SECTION”:

;; ANSWER SECTION:
markus.codes.		3600	IN	TXT	"v=spf1 include:cust-spf.exacttarget.com -all"

In order to only see the contents of the records, use the following command:

dig markus.codes +short TXT

Keep in mind that all of the TXT records configured for that domain are shown and not only the SPF record.

"v=spf1 include:cust-spf.exacttarget.com -all"

Check for DKIM records

Querying for DKIM entries is a bit more challenging as you are free to choose the selectors. So if you know the selector in use, it is pretty simple and similar to the SPF record query. If you don’t know the selector it is possible to find it out based on the system you use. If a Sender Authentication Package from Marketing Cloud is in use the selector usually looks like this:

[stacknumber]dkim1._domainkey

Some time ago these were TXT records directly, but to ease key rotation this has changed to the use of CNAME records that delegate the record to another host, so Salesforce is able to change the encryption key pair regularly to further enhance security. If the new way is already implemented can be seen from the response. So go ahead and type in the following (again change the domain and selector according to your needs):

dig 50dkim1._domainkey.markus.codes TXT

Again, the interesting part is contained in the “ANSWER SECTION” or if you add the +short-option only the contents of the record are shown:

;; ANSWER SECTION:
50dkim1._domainkey.markus.codes. 3600 IN CNAME	50dkim1._domainkey.s50.exacttarget.com.
50dkim1._domainkey.s50.exacttarget.com.	300 IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQ..."

In the first line of the answer you can see the delegation to Salesforce/ExactTarget and in the second line you can see the DKIM record itself.

Check for DMARC records

Reviewing DMARC records is as easy as SPF records again as we know the whole domain to query in that case. Therefore enter the following command (replace markus.codes with your domain of choice):

dig _dmarc.markus.codes TXT

Again, check the “ANSWER SECTION” of the result or use the +short option:

;; ANSWER SECTION:
_dmarc.markus.codes.	3600	IN	TXT	"v=DMARC1; p=reject; rua=mailto:domainadmin@markus.codes; ruf=mailto:domainadmin@markus.codes; pct=100"