Post

Demystifying DMARC: A guide to preventing email spoofing

Learn how the SPF, DKIM, DMARC email authentication standards work together to prevent unauthorized email spoofing — and how to use open source tools to deploy DMARC for free

Demystifying DMARC: A guide to preventing email spoofing

DMARC can stop spoofed spam and phishing from reaching you and your customers, protecting your information security and your brand. However, complexity and misconceptions deter many organizations from ever deploying it. Part mythbusting, part implementation guide, this post explains the shortcomings of SPF and DKIM, what DMARC is, how to deploy DMARC properly, and how to respond to DMARC reports - all without the need for an additional vendor , thanks to open source software!

Modern email authentication relies on a combination of three standards: SPF, DKIM, and DMARC. These standards help ensure that a message came from a server related to the domain owner and was not spoofed.

Sender Policy Framework (SPF)

SPF was the first widely adopted standard for combating email spoofing. Despite its limitations in preventing spoofing, most email recipients expect you to have it deployed on your domain. For example, Gmail/G-Site/Google will throttle incoming emails from domains that do not have a valid SPF record.

How SPF works

SPF is defined in RFC 7208. It works by checking for a specially formatted DNS TXT record in the domain of the mail from header in the SMTP transaction. This SPF record describes which servers are authorized to send as that domain by using mechanisms to identify authorized IP addresses and hostnames, or even include the SPF records of other domains.

Every SPF record is a TXT record at the root of a domain or subdomain that starts with v=spf1. From there, mechanisms are used to describe mail servers are allowed (or not allowed) to send email as that domain or subdomain. A domain or subdomain can only have one SPF record, but each subdomain can have its own SPF record.

Some mechanisms like a, mx, include, and redirect use additional DNS lookups to work. SPF has a maximum DNS lookup limit of 10, including any included records. Any SPF record that would require more than 10 DNS lookups to resolve is invalid! This is a common mistake to make when deploying SPF.

To work around this limit, send email from different subdomains. Each subdomain needs its own SPF record and has its own set of limits for that record. For example, you could send newsletters from news.example.com, and invoices from billing.example.com.

You might not even need to include every vendor in your SPF records anyway. If the vendor supports DKIM signing, you can rely on that to pass DMARC, even if the sender is not in your SPF record. Just make sure you are using ~all in your SPF record.

MechanismDescription
ip4Describes an ipv4 address or CIDR block of addresses.
ip6Describes an ipv6 address or block of addresses.
mx

Describes the servers listed in the mx record of the domain.

Counts towards the DNS lookup limit.

mx The servers listed in the mx records of its own domain
mx:example.com The servers listed in the mx records of example.com
a

Describes the servers listed in the A and/or AAAA records of the domain.

Counts towards the DNS lookup limit.

a The IP addresses listed in the domains’ own A/AAAA records
a:example.com The IP addresses listed in the A/AAA records of example.com
include

Includes the SPF record from the domain after the colon (it does not include the all modifier, if any)

Counts towards the DNS lookup limit.

redirect

Stops processing the SPF record, and continues at the specified domain’s SPF record (including the all modifier!)

Counts towards the DNS lookup limit.

exists

This mechanism is used to construct an arbitrary domain name that is
used for a DNS A record query. It allows for complicated schemes
involving arbitrary parts of the mail envelope to determine what is
permitted.

Counts towards the DNS lookup limit.

exists = “exists” “:” domain-spec

The <domain-spec> is expanded as per Section 7. The resulting domain name is used for a DNS A RR lookup (even when the connection type is
IPv6). If any A record is returned, this mechanism matches.

Domains can use this mechanism to specify arbitrarily complex
queries. For example, suppose example.com publishes the record:

v=spf1 exists:%{ir}.%{l1r+-}._spf.%{d} -all

The <target-name> might expand to “1.2.0.192.someuser._spf.example.com”. This makes fine-grained
decisions possible at the level of the user and client IP address.

Mechanisms listed in the SPF record have an implicit pass (i.e. +) qualifier in front of them. Possible qualifiers are:

ModifierNameDescription
+passA “pass” result means the client is authorized to inject mail with the given identity. The domain can now, in the sense of reputation, be considered responsible for sending the message. Further policy checks can now proceed with confidence in the legitimate use of the identity.
?neutralA “neutral” result indicates that although a policy for the identity was discovered, there is no definite assertion (positive or negative) about the client. A “neutral” result MUST be treated exactly like the “none” result; the distinction exists only for informational purposes. Treating “neutral” more harshly than “none” would discourage domain managers from testing the use of SPF records. With a “none” result, the SPF verifier has no information at all about the authorization or lack thereof of the client to use the checked identity or identities. The check_host() function completed without errors but was not able to reach any conclusion.
~softfailA “softfail” result ought to be treated as somewhere between “fail” and “neutral”/”none”. The domain manager believes the host is not authorized but is not willing to make a strong policy statement.Receiving software SHOULD NOT reject the message based solely on this result, but MAY subject the message to closer scrutiny than normal.
-failA “fail” result is an explicit statement that the client is not authorized to use the domain in the given identity. Disposition of SPF fail messages is a matter of local policy.

Most SPF records (except for those that are designed to be included in other SPF records) end with an all modifier. The all modifier consists of the word all with a qualifier in front of it. The all modifier states how emails should be treated that do not match any of the listed mechanisms.

SPF’s weakness: Relying on SMTP headers

It is a common misconception that SPF stops email spoofing. At best, it makes things a tiny bit more difficult on an attacker.

Remember, SPF checks for an SPF record at the domain in the mail from header in the SMTP transaction (also known as the envelope from), not the message from header that the receiving mail client sees, The SMTP transaction are not visible to the end client, even when viewing the message headers.

This means that an attacker can use SMTP headers to direct the target’s mail server to check a domain that the attacker controls, which contains an authorizing mechanism for the mail server the attacker is using, while spoofing a completely different domain for the target to see in the message from header!

In the example telnet screenshot below, the attacker is able to get the receiving email server to check the SPF record of a domain that the attacker controls (i.e. infosecspeakeasy.org), while spoofing the target’s own domain (i.e. cincykitchenandbath.com) in the message from header, which is the from address that the target user will see.

A screenshot showing how SPF can be bypassed by spoofing the SMTP mail from header A screenshot showing how SPF can be bypassed by spoofing the SMTP mail from header

This sort of domain mismatch occurs legitimately when a mailbox rule forwards a message from another domain. The message from domain will stay the same, but the SMTP mail from header will contain the domain of the forwarding mail server.

A process graphic that shows how forwarded email fails SPF alignmentDKIM signatures, on the other hand, are part of the message headers, and survive message forwarding. Therefore DKIM alignment is much more critical than SPF alignment.

Example SPF records

Once you know exactly which email services legitimately send as the domain (DMARC reports will tell you), update the SPF record accordingly, and change the ?all modifier to ~all.

SPF record for domains that send emails from their incoming gateways and are missing SPF records

1
v=spf1 mx ?all

This record explicitly authorized any servers listed in the domain’s MX record, while treating all others as neutral. This is a good temporary SPF record for new domains or newly acquired domains that do not already have a SPF record.

Here are some good examples of SPF records for common cloud email providers:

Office 365

1
v=spf1 include:spf.protection.outlook.com ?all

G-Suite

1
v=spf1 include:_spf.google.com ?all

Proofpoint Essentials

1
v=spf1 a:dispatch-us.ppe-hosted.com a:dispatch-eu.ppe-hosted.com ?all

SPF record for domains that do not send email (e.g. parked domains)

1
v=spf1 -all

This record explicitly states that no mail servers are authorized to send email as this domain.

This must be added to all domains that do not send email, inducing parked domains.

DomainKeys Identified Mail (DKIM)

DomainKeys Identified Mail (DKIM) is a email message authentication standard, defined in RFC 6376. Because DKIM authenticates the message headers rather than the SMTP headers, DKIM authentication survives intact when a message is directly forwarded (e.g. via a mailbox rule).

DKIM message headers

Here’s an example DKIM header

1
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=s1; c=relaxed/simple; l=1234; t=1117574938; x=1118006938; h=from:to:subject:date; bh=MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=;b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZVoG4ZHRNiYzR

Required DKIM header tags

TagValue Description
vSignature version
aSignature algorithm (rsa-sha256 should be used)
dThe domain where the public key can be found
sThe selector pointing to the public key at the domain (an arbitrary string)
hA colon separated list of headers to concatenate when validating the header signature
bThe base64-enoded signature hash of the headers listed in the h tag
bhThe base64-enoded signature hash of the message body

Optional DKIM header tags

TagValue Description
tSignature timestamp in UNIX timestamp format (i.e. the number of seconds from 00:00:00 on January 1, 1970 in the UTC time zone)
xSignature expiration timestamp in UNIX timestamp format (i.e. the number of seconds from 00:00:00 on January 1, 1970 in the UTC time zone)
ccanonicalization algorithm: Defines if/how the receiving the receiving mail server should normalize the message to account for slight variations in whitespace and line breaks that could otherwise invalidate the signature. Relaxed mode is strongly recommended for the header and body canonicalization (i.e. c=relaxed/relaxed).
iIdentity/user-agent of the signer
lNumber of characters from the beginning of the body to use when calculating the body signature (not recommended because someone could append malicious content)
zNot well defined

The receiving mail server uses the selector (s=) and domain (d=) tags to look up the public key as a DNS TXT record at

1
._domainkey.

In the above signature example, the receiving server would look for the DKIM key at:

1
TXT s1._domainkey.example.com

DKIM DNS records

DKIM DNS records are formatted as:

1
v=DKIM1; k=rsa; p=;

Lines in DNS TXT records are truncated at 256 characters. If the record is longer, it must be split into separate lines in the same record in order to be valid.

DKIM public key records can be validated for syntax using the DKIM record lookup tool at MX Toolbox.

TagValue Description
vAccording to the RFC, this tag is recommended but not required, with an implicit default value of DKIM1. However, in practice, some recipients don’t follow the RFC exactly, and require this tag to be used anyway. This must be the first tag if used.**Your DKIM public key records should start with v=DKIM1;**
nNotes: Human-readable notes for administrators reviewing DNS records Useful for noting which service uses a selector and key.

Required DKIM DNS record tags

TagValue Description
pPublic key data encoded in base64. Keys must be at least 1024 bytes long. 2048 bit length is strongly recommended.

Optional DKIM record tags

TagValue Description
k Key type: Defaults to rsa. Unrecognized key types must be ignored.
h Acceptable hash algorithms: A colon-separated list of hash algorithms that might be used. Defaults to allowing all algorithms. Unrecognized algorithms must be ignored.

Refer to Section 3.3 for a discussion of the hash algorithms implemented by Signers and Verifiers. The set of algorithms listed in this tag in each record is an operational choice made by the Signer.

s Service Type: Defaults to *

A colon-separated list of service types to which this record applies. Verifiers for a given service type must ignore this record if the appropriate type is not listed. Unrecognized service types must be ignored.This tag is intended to constrain the use of keys for other purposes, should use of DKIM be defined by other services in the future.

Currently defined service types are as follows:

ValueValue Description
*Matches all service types
emailElectronic mail (not necessarily limited to SMTP)
t Flags: A colon-separated list of flags

Defaults to no flags

FlagFlag Description
y This domain is testing DKIM. Verifiers must not treat messages from Signers in testing mode differently from unsigned email, even if the signature fails to verify. Verifiers may wish to track testing mode results to assist the Signer.
s

Any DKIM-Signature header fields using the i= tag must have the same domain value on the right-hand side of the @ in the i= tag and the value of the d= tag.

That is, the i= domain must not be a subdomain of d=.

Use of this flag is recommended unless subdomaining is required.

Notes in DKIM DNS records

The DKIM selector (subdomain) is chosen by the vendor and is often non- descriptive. You can use an arbitrary string in the n (i.e., notes) tag in the DKIM record to make a note of the vendor’s name, so you know which DKIM key is used by which vendor as you audit your DNS records.

For example, if “matketingco” asked you to publish the following DKIM TXT record:

1
randomselector._domainkey.example.com TXT "p=base64Key"

You should create the record this way instead:

1
randomselector._domainkey.example.com TXT "v=DKIM1; n=marketingco; k=rsa; p=base64Key"

DKIM key rotation

It is generally recommended to rotate DKIM keys once per month, or at least after you suspect that the DKIM private key has been compromised. Most email/marketing services will handle key rotation for you when you configure your domains for DKIM, but some almost never rotate their keys.

Unlike web and email certificates, the domain/email address is not part of the PKI. DKIM does not use certificates.. The domain is listed in the d= header tag. Therefore, you do not need a separate public/private key pair for each domain.

You should create two key pairs, and store the public keys under two different selectors, for example:

1
2
s1._domainkey.example.com TXT "v=DKIM1; k=rsa; p=<public key>;"
s2._domainkey.example.com TXT "v=DKIM1; k=rsa; p=<a different public key>;"

With CNAME records, your other domains can use the same selectors and keys:

1
2
s1._domainkey.example.net CNAME s1._domainkey.example.com.
s2._domainkey.example.net CNAME s2._domainkey.example.com.

Third party services will often have you authorize their DKIM keys on your domains using CNAME records and will then validate that those records exist before signing email, so they can handle key changes for you.

If you are using your own keys, it is up to you to manage them, preferably using automation. Start by signing all of your emails using the first selector. When it is time to rotate the keys, sign all outgoing email using the s2 sector. After a week of not using the key at the s1 selector, replace the key at the s1 selector.

When it is time to rotate keys again, start using the s1 selector exclusively, wait a week, then replace they key at the s2 selector with a new key, so it will be ready for the next rotation.

Unless a key is known to have been compromised, it is important to wait a week (i.e., 7 days) before replacing it, as some receiving mail servers will cache the public key at a given selector for up to a week.

Using this ping-pong key rotation scheme, you ensure that email is always signed with a valid, secure key.

  1. Start exclusively signing with the other selector.
  2. Wait 7 days.
  3. Replace the key at the old selector so it is ready for the next rotation.
  4. Go to step 1.

DKIM’s weakness: arbitrary d= values

Without DMARC, the d= value in a DKIM signature header is not required to match the same domain that the user sees in the message From header. An attacker can place a valid DKIM signature header in an email with a d= value that points to a domain the attacker controls, allowing DKIM to pass while still spoofing the from address to the user.

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

Domain-based Message Authentication, Reporting, and Conformance (DMARC) is defined in RFC 7489. DMARC ensures that the SPF and DKIM authentication mechanisms actually authenticate against the same base domain that the end user sees.

In order to be useful, a DMARC DNS record must be published by a domain owner, and email recipients must honor this record, including its enforcement policy, and at least send back aggregate reports if requested by the domain owner.

A message passes a DMARC check by passing DKIM or SPF, as long as the related indicators are also in alignment with the message’s from address.

DKIMSPF 
PassingThe signature in the DKIM header is validated using a public key that is published as a DNS record of the domain name specified in the signatureThe mail server’s IP address is listed in the SPF record of the domain in the SMTP envelope’s mail from header.
AlignmentThe signing domain aligns with the base domain in the message from header.The domain in the SMTP envelope’s mail from header aligns with the base domain in the message’s from header.

DKIM alignment is more important than SPF, because only DKIM remains aligned when a message is forwarded via a mailbox rule.

DMARC reports

DMARC has two report types: aggregate and forensic. email recipients that honor DMARC send these reports back to domain owners in emails sent to addresses listed in the domain’s DMARC record. There reports contain very useful information for debugging message alignment and identifying malicious spoofing campaigns.

Report typeDescription
Aggregate (rua)Compressed XML files sent at least once per day by recipient domains to the URIs listed in the rua DMARC tag. Records number of messages sent from an IP address, and the SPF and DKIM status. These reports are sent regardless of a success or failure, so that domain owners have a view of all mail authentication of messages appearing to be from their domain.
Failure/Forensic (ruf)An email with an email that failed the DMARC check attached (RFC 822/.eml format) sent to the URIs listed in the ruf DMARC tag. These can be very useful for DMARC troubleshooting and phishing investigations. However, most email recipients do not send forensic reports, or may only supply the message headers for privacy**reasons.**

DMARC policies

DMARC requires domain owners to set a policy (p=) tag in their DMARC record. This policy tells recipients how they should react to an email that appears to come from that domain based on the message from header but does not pass DMARC alignment.

PolicyDescription
noneThe Domain Owner requests no specific action be taken regarding delivery of messages. Use this first to ensure your messages are DMARC compliant before switching to quarantine or reject.
quarantineThe Domain Owner wishes to have email that fails the DMARC mechanism check be treated by Mail Receivers as suspicious. Depending on the capabilities of the Mail Receiver, this can mean “place into spam folder”, “scrutinize with additional intensity”, and/or “flag as suspicious”.
rejectThe Domain Owner wishes for Mail Receivers to reject email that fails the DMARC mechanism check. Rejection SHOULD occur during the SMTP transaction.

Even if a domain has a DMARC policy set to p=none, mail services may still display warnings to their users in the event of a DMARC failure, as shown in this screenshot of a valid email from a retail credit service, displayed in ProtonMail and Gmail.

A screenshot of ProtonMal showing a DMARC failure warning

A screenshot of a DMARC failure warning in Gmail

Authentication-Results headers

As an email gateway evaluates SPF, DKIM, and DMARC, it adds the Message- Authentication headers to the email. Users and administrators can use these headers to determine which checks passed or failed, and why.

In the example above, the mail server mail17i.protonmail.ch added the following headers to the email:

1
2
3
Authentication-Results: mail17i.protonmail.ch; dmarc=fail (p=none dis=none) header.from=[redacted].com
Authentication-Results: mail17i.protonmail.ch; spf=pass smtp.mailfrom=noreply_[redacted]_portal=[redacted].com__0-28eb251z589s1s@zihu5s1p6odwjt9p.s3cycftqbacrhjk9.hf76qay.3-1ffzneao.na45.bnc.salesforce.com
Authentication-Results: mail17i.protonmail.ch; dkim=none

Email headers are added and read from the bottom to the top.

First, the server notes that the message has not been DKIM signed.

Then, SPF is checked, with a SMTP mail from header value of noreply_[redacted]_portal=[redacted].com__0-28eb251z589s1s@zihu5s1p6odwjt9p.s3cycftqbacrhjk9.hf76qay.3-1ffzneao.na45.bnc.salesforce.com, and SPF passed. A salesforce.com address was used so that Salesforce can keep track of bouncebacks, and avoid sending to invalid email addresses in the future. SPF passed.

Finally, DMARC is checked, which fails, because the message is not DKIM signed, and the base of the SMTP mail from domain used by SPF (salesforce.com) does not match the base domain in the message from header ([redacted].com). dis=none (short for message disposition) indicates that the message was still delivered, because the mail server noted that [redacted].com has a DMARC policy of p=none.

The retail credit service should resolve the DMARC failures by configuring Salesforce to DKIM sign the messages, and then publish the DKIM public key as a DNS TXT record on [redacted].com.

Note : If you route your incoming email from one gateway service to another, such as from an IronPort to Office 365, by the time an email reaches a user’s mailbox, the information from Office 365 in the Authentication- Results header will always show that SPF and DMARC passed, since the IronPort is authorized to send as your domains when messages are forwarded to Office 365. The results of the original IronPort check that occurs before the message reaches Office 365 are stored in the Authentication-Results-Original header.

DMARC policy DNS records

DMARC policy DNS records are placed at a TXT record at the _dmarc subdomain. Subdomains of the TLD/base domain automatically inherit this DMARC policy record, or they can have their own record at their own_dmarc subdomain.

Here is an example DMARC policy DNS record

1
_dmarc.example.com TXT "v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]"

Required DMARC policy DNS record tags

TagDescription
vDMARC version (e.g., v=DMARC1)
pDMARC policy

These tags tell recipients where and how to send reports.

Tag Value Description
v

According to the RFC, this tag is recommended but not required, with an implicit default value of DKIM1.

However, in practice, some recipients don’t follow the RFC exactly, and require this tag to be used anyway. This must be the first tag if used.Your DKIM public key records should start with v=DKIM1;

n Notes: Human-readable notes for administrators reviewing DNS records

Useful for noting which service uses a selector and key.

TagDescription
spDefault mirrors the p tag’s value Sets the policy for all subdomains. Setting this tag could allow the spoofing of any arbitrary subdomain. Add a separate policy record for each subdomain as needed instead.
pctDefault is 100 Sets the percentage of mail to apply the DMARC policy to. Set p=none when testing instead to ensure all mail is treated equally
adkimDefault is relaxed (r) In relaxed mode, the Organizational Domains of both the DKIM-authenticated signing domain (taken from the value of the “d=” tag in the signature) and that of the RFC 5322 From domain must be equal if the identifiers are to be considered aligned.
aspfDefault is relaxed (r) In relaxed mode, the SPF-authenticated domain and RFC5322 From domain must have the same Organizational Domain. In strict mode, only an exact DNS domain match is considered to produce Identifier Alignment.
rfA list separated by colons of one or more report formats as requested by the Domain Owner to be used when a message fails both SPF and DKIM tests to report details of the individual failure. Only “afrf” (the auth-failure report type) is currently supported in the DMARC standard.
riDefault is 86400 Indicates a request to Receivers to generate aggregate reports separated by no more than the requested number of seconds. DMARC implementations MUST be able to provide daily reports and SHOULD be able to provide hourly reports when requested. However, anything other than a daily report is understood to be accommodated on a best-effort basis.

DMARC authorization DNS records

If an email address in rua or ruf has a different base domain than the domain of the policy record, an authorization record must be added to the base domain of the email address to indicate that it accepts reports about that domain. For example, if [email protected] also needed to accept reports for example.net, the poly record for example.net would look like this:

1
_dmarc.example.net TXT "v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]"

Because example.net is a different base domain than example.com, the following record needs to be added to example.com to indicate that it accepts reports about example.com:

1
example.net._report._dmarc.example.com TXT "v=DMARC1"

DMARC deployment steps

  1. Configure email gateways to honor DMARC records and send aggregate DMARC reports.
  2. Inventory domains.
  3. Deploy SPF.
  4. Deploy DKIM.
  5. Set up mailbox for receiving DMARC reports.
  6. Deploy DMARC DNS records.
  7. Monitor incoming DMARC reports.
  8. Adjust SPF, DKIM signing, and DMARC policies as needed.

Calendar invites forwarded by Outlook violate DMARC

Calendar events from DMARC protected domains forwarded by outsiders using Outlook will fail DMARC. Unfortunately, unlike a normal forwarded email, calendar events forwarded using Outlook are “sent on behalf of” the meeting organizer. Instead of using the address of the person who forwarded the email in the from header, Outlook uses the address of the meeting organizer. The address of the person who did the forwarding is placed in the Sender header, which DMARC does not use.

A screenshot of a draft forward of a calendar event in Microsoft Outlook

If the domain of the meeting organizer has an enforced DMARC policy (i.e., p=quarantine, or p=reject), and the recipient mail server honors DMARC, the message will not be delivered, because DMARC does not allow an unauthorized mail server (i.e., the forwarding mail server) to send an email as the organizer’s domain.

This is a known problem with Outlook that Microsoft has so far not addressed. In the meantime, tell anyone who wants to forward calendar events to do so by clicking on the three dots, and clicking Forward as Attachment, instead of clicking on the usual Forward button.

A screenshot showing how to forward a calendar invite as an attachment in Outlook

On Outlook for macOS, calendar events must be forwarded by clicking on Message> Forward as Attachment in the Menu Bar.

A screenshot of the Forward as attachment menu item in Outlook for macOS

FAQs

How can I check a DKIM signature?

Send an email to a Gmail account. They have a nice UI that shows the DKIM status of a message.

A screenshot showing how DKIM signature alignment can be verified using Gmail's UI A screenshot showing how DKIM signature alignment can be verified using Gmail’s UI

What if a third-party sender can’t support DMARC?

  1. Some vendors don’t know about DMARC yet; ask about SPF and DKIM/email authentication. Check if they can send through your email relays instead of theirs.

  2. Do they really need to spoof your domain? Why not use the display name instead?
  3. Worst case, have that vendor send email as a specific subdomain of your domain (e.g. [email protected]), and then create separate SPF and DMARC records on news.example.com, and set p=none in that DMARC record.

Do not alter the p or sp values of the DMARC record on the Top-Level Domain (TLD) - that would leave you vulnerable to spoofing of your TLD and/or any subdomain.

Further reading on this problem.

How can I get more forensic reports?

Often, you will find a service that sends email that passes SPF alignment, but not DKIM alignment, but you might not know which email workflow has the problem, because you won’t get many forensic reports, since at SPF is aligned.

Try setting fo=1 in your DMARC policy record.

By default, fo is implicitly set to 0. DMARC failure/forensic reports are only sent if all authentication mechanisms (i.e., SPF and DKIM) fail to produce an aligned “pass” result.

Setting fo=1 in the DMARC policy record will provide forensic/failure reports if any authentication mechanisms fail.

This is noisy, but very useful for troubleshooting DKIM when SPF is passing, Remove the fo tag, or set it to 0 once troubleshooting is complete.

What about mailing lists?

When you deploy DMARC on your domain, you might find that messages relayed by mailing lists are failing DMARC, most likely because the mailing list is spoofing your from address, and modifying the subject, footer, or other part of the message, thereby breaking the DKIM signature.

Mailing list best practices

Ideally, a mailing list should forward messages without altering the headers or body content at all. Joe Nelson does a fantastic job of explaining exactly what mailing lists should and shouldn’t do to be fully DMARC compliant. Rather than repeat his fine work, here’s a summary:

Do

  • Retain headers from the original message.
  • Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of adding unsubscribe links to the body.

    1
    
      List-Unsubscribe:
    
  • Add RFC 2919 List-Id headers instead of modifying the subject.

    1
    
      List-Id: Example Mailing List
    

Modern mail clients and webmail services generate unsubscribe buttons based on these headers.

Do not

  • Remove or modify any existing headers from the original message, including From, Date, Subject, etc.
  • Add to or remove content from the message body, including traditional disclaimers and unsubscribe**footers.**

In addition to complying with DMARC, this configuration ensures that Reply and Reply All actions work like they would with any email message. Reply replies to the message sender and Reply All replies to the sender and the list.

Even without a subject prefix or body footer, mailing list users can still tell that a message came from the mailing list, because the message was sent to the mailing list post address, and not their email address.

Configuration steps for common mailing list platforms are listed below.

Mailman 2 best practices

Navigate to General Settings, and configure the settings below

SettingValue
subject_prefix 
from_is_listNo
first_strip_reply_toNo
reply_goes_to_listPoster
include_rfc2369_headersYes
include_list_post_headerYes
include_sender_headerNo

Navigate to Non-digest options, and configure the settings below:

SettingValue
msg_header 
msg_footer 
scrub_nondigestNo

Navigate to Privacy Options> Sending Filters, and configure the settings below:

SettingValue
dmarc_moderation_actionAccept
dmarc_quarentine_moderation_actionYes
dmarc_none_moderation_actionYes

Mailman 3 best practices

Navigate to Settings> List Identity

Make Subject prefix blank.

Navigate to Settings> Alter Messages

Configure the settings below:

SettingValue
Convert HTML to plaintextNo
Include RFC2369 headersYes
Include the list post headerYes
Explicit reply-to address 
First strip reply-toNo
Reply goes to listNo munging

Navigate to Settings> DMARC Mitigation

Configure the settings below

SettingValue
DMARC mitigation actionNo DMARC mitigations
DMARC mitigate unconditionallyNo

Create a blank footer template for your mailing list to remove the message footer. Unfortunately, the Postorius mailing list admin UI will not allow you to create an empty template, so you’ll have to create one using the system’s command line instead, for example:

1
touch var/templates/lists/list.example.com/en/list:member:regular:footer

Where list.example.com the list ID, and en is the language.

Then restart mailman core.

Mailing list workarounds

If a mailing list must go against best practices and modify the message (e.g., to add a required legal footer), the mailing list administrator must configure the list to replace the from address of the message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC.

Configuration steps for common mailing list platforms are listed below.

Mailman 2 workaround

Navigate to Privacy Options> Sending Filters, and configure the settings below

SettingValue
dmarc_moderation_actionMunge From
dmarc_quarentine_moderation_actionYes
dmarc_none_moderation_actionYes

Note

Message wrapping could be used as the DMARC mitigation action instead. In that case, the original message is added as an attachment to the mailing list message, but that could interfere with inbox searching, or mobile clients.

On the other hand, replacing the from address might cause users to accidentally reply to the entire list, when they only intended to reply to the original sender.

Choose the option that best fits your community.

Mailman 3 configuration

In the DMARC Mitigations tab of the Settings page, configure the settings below:

SettingValue
DMARC mitigation actionReplace From: with list address
DMARC mitigate unconditionallyNo

Note

Message wrapping could be used as the DMARC mitigation action instead. In that case, the original message is added as an attachment to the mailing list message, but that could interfere with inbox searching, or mobile clients.

On the other hand, replacing the From address might cause users to accidentally reply to the entire list, when they only intended to reply to the original sender.

Choose the option that best fits your community.

LISTSERV

LISTSERV 16.0-2017a and higher will rewrite the from header for domains with a DMARC quarantine or reject policy.

Some additional steps are needed for Linux hosts.

DMARC deployment guides

SPF and DMARC record validators

  • checkdmarc - A Python module and CLI tool I wrote to validate and parse SPF and DMARC records
  • trustymail - By DHS; checks for compliance with BOD 18-01, including SPF, DMARC, and STARTTLS
  • DNS Checker - Check DNS propagation worldwide

DMARC report processing services

DMARC adoption

DMARC compliant services

Blackbaud

Payment and CRM solutions for non-profits

Constant Contact

Cvent

Cvent planner supports alignment via SPF and DKIM.

Add the following to your SPF record:

include:cvent-planner.com

Contact Cvent support to set up DKIM signing as your domain.

Emma

Elastic Email

Reasonably priced, fully DMARC compliant marketing and transactional email.

GlobalCert SecureMail Gateway

HealthcareSource

Healthcare talent management SaaS. Contact support and let them know that you need SPF and DKIM set up for DMARC alignment.

Highspot

Highspot supports DKIM signing as their customer’s domains. Contact their support to get started.

HubSpot

Good option if a full Customer Relationship Management (CRM) platform is needed.

JangoMail

Full-featured email marketing.

Add include:jangomail.com to your SPF record.

JangoSMTP

Transactional email service used by IBM Phytel (see separate entry below) and others.

Add include:jangomail.com to your SPF record.

MailChimp

Extremely cheap bulk marketing email; extremely expensive transactional email.

Mandrill

A MailChimp add-on service for transitional email

Mailgun

Mailjet

Email and SMS marketing.

Net-Results

Marketing automation

OnSolve Mir3

Mass notification system for employees, contractors, students, etc.

Mir3 supports DKIM alignment via DKIM.

Contact your Mir3 account manager to have them set up DKIM signing/email whitelabeling.

Phytel (sent via JangoSMTP)

IBM Phytel is used by healthcare providers to send appointment reminders and other information to their patients. Emails are relayed through JangoSMTP.

Add include:jangomail.com to your SPF record.

Contact IBM Phytel support and ask them to configure DKIM signing.

Poppulo (Formerly Newsweaver)

Poppulo/Newsweaver supports DKIM alignment. Contact their support to begin the process.

Safe Pay Services

A payment processor that supports DMARC alignment via SPF and DKIM.

Add a:mail.safepayservices.com to your SPF record.

Contact support for details.

Salesforce Marketing Cloud

SendGrid

Sendinblue

Not as cheap as Elastic Email, but cheaper than SendGrid and Mandrill, with options for SMS.

Simplee

B2C medical billing

According to Simplee support as of 2019-05-23, in order to support DKIM signing, they need to purchase a domain authentication package from Salesforce, with the cost passed on to the customer, and have the Simplee customer delegate a domain or subdomain to Salesforce via NS records:

  • ns1.exacttarget.com
  • ns2.exacttarget.com
  • ns3.exacttarget.com
  • ns4.exacttarget.com

Costs include:

  • One-time setup fee: $350 for Simplee to cover implementation and setup costs
  • Annual Fee: $1,500 per year per domain (pass-through expense via Salesforce) + $39 Salesforce Purchase Order Fee

For for information, contact Simplee support at https://support.simplee.com/hc/en-us/requests/new

Symantec MessageLabs

Services that must use your SMTP relays to be fully DMARC compliant

Incompatible services

Some services do not do any DKIM signing, or use their own domain came in the DKIM d= tag, making the signature unaligned with the message from address domain they are spoofing.

There are different two ways to work around this problem, each with its own benefits and drawbacks:

  1. Have the vendor send emails from their domain instead of yours
  2. Configure the service to use a specific subdomain of your domain in the message from address. Then, create a separate DMARC record with p=none under that specific subdomain.

By having a service send as its own domain, you loose branding in the from email address, but it will not cause additional complexity or risk.

Publishing a DMARC p=none policy on a specific subdomain allows spoofing of that specific subdomain, without weakening DMARC enforcement for other subdomains, or the top level domain. This allows you to keep your domain in the from address, but also opens up that specific subdomain to spoofing from anyone.

Archer Risk Management

Archer Risk Management does not currently support SPF or DKIM alignment of third-party domains, so customers of Archer should configure all of their Archer emails to use a from address at the archerirm.us domain.

UL PureSafety

DKIM signing as customer domains is not currently supported by UL PureSafety OHM. Most outbound email notifications in OHM are configured by the customer, including the From address they will be sent with. The user(s) should go through the screens where they have set them to various customer addresses and change them to a generic puresafety.com address, such as “[email protected].” They should also update the Body of each email template to include appropriate contact information.

Volgistics

Volgistics does not currently support DKIM signing, so the account administrator will need to complete the following steps to configure Volgistics to send email as Volgistics.com:

  1. Choose Setup from the menu in the account
  2. Expand Messages
  3. Click the “Ground Rules” link
  4. In the “From address” section, select the “Use [email protected] as the from address (recommended)” option
  5. Click the Save button

Bonus steps

These steps aren’t required to deploy DMARC, but they can help to make your email more secure.

Verify TLS

TLS ensures that messages are encrypted on their way to your mail servers. STARTTLS allows email clients to upgrade from a plain text connection to an encrypted one.

To check STARTTLS, run:

openssl s_client -connect mail.example.com:25 -starttls smtp

To check the standard secure SMTP port, run:

openssl s_client -connect mail.example.com:465

You can also check SMTP TLS using MX Toolbox or Check TLS.

checkdmarc also checks for TLS and STARTTLS.

Brand Indicators for Message Identification (BIMI)

Brand Indicators for Message Identification (BIMI) is a standard for verified branding in email When a mail client uses BIMI, it first checks to see if the message passed DMARC alignment. If the DMARC policy is set to enforcement (i.e., p=quarantine or p=reject) and DMARC alignment has passed, the mail/webmail client then checks for a BIMI assertion record at the message from domain. This record points the client to a SVG file publicly hosted on a web server, which is then displayed in the client UI, next to the message from information.

Screenshots of an email with and without BIMI in Outlook webmail (Credit: Returnpath)

In order to set up BIMI you need 5 things:

  1. A logo that is a registered trademark, or a non-trademarked logo that has been in use for at least one year
  2. An image of that logo in SVG Portable/Secure (SVG P/S) format
  3. A Verified Mark Certificate (VMC) for trademarked logos, or a Common Mark Certificate (CMC) from a verifying authority (currently Digicert or Entrust) that proves that your organization has the right to use that logo
  4. A BIMI DNS record with HTTPS URLs pointing to the SVG and the VMC or CMC
  5. A DMARC record with an enforced policy (i.e., p=quarantine or p=reject)

A BIMI assertion DNS record looks like this

default._bimi.bankofamerica.com TXT "v=BIMI1; l=https://bimi.entrust.net/bankofamerica.com/logo.svg; a=https://bimi.entrust.net/bankofamerica.com/certchain.pem"

You can validate a BIMI record and logo format at the BIMI inspector, which also gives you nice previews of what your BIMI logo would look like in a mail client.

For more information, see the official implementation guide.

This post is licensed under CC BY 4.0 by the author.