What You Need To Know About Email Authentication: SPF, DKIM, rDNS and DMARC records

Author:
phil
Created:
Thursday, August 17th, 2017
Last Updated:
Saturday, October 07th, 2017

Disclaimer: Accessing the information on this page means you agree to the Sites Terms of Service


I've been in the computer industry for quite some time and I'll be the first to admit, I don't know everything. Email has always been a bit of a weak area of expertise and while I had heard about SPF, DKIM and DMARC records, I was oblivious to what they are and what they actually do.

I got an email one day that customers weren't receiving their order confirmation emails from a site I maintain. A few weeks prior, I walked a customer through the email password reset process, only they weren't receiving the password reset email. I chalked it up to the ISP email they were using and forgot about it. But when I got the email that multiple customers weren't receiving their order confirmation emails, I knew there was something amiss so I started looking into it. That's when I stumbled on the need for SPF and DKIM records needed at the very least, to properly authenticate email.

It took me a little while to wrap my head around these protocols and the "official" documentation is the typical "You need this, and here's how to do it" written by people that are really smart, but too stupid to actually make sense except to the 1% of people who think like them. It'd be easier to teach a dog how to train a monkey...

Anywho, we'll walk through each one from the standpoint of being clueless to what they are and why they're needed, and hopefully get you up to speed to better understand how and why to create each one. I won't dive into the specifics of each protocol, only the necessary bits to get you familiarized with making it work.

There is a LOT of information out there on each one, but no one really explains it in a dumb-down manner. That's what I'll try to do. I'm still new to it too as of this writing, so if I get a few things wrong, you'll know why.

Fore-warning: You need to have a basic understanding of DNS. If you don't know anything about DNS, this isn't going to be easy... If you can at least hop on Godaddy or 1and1 or your hosting DNS Zone editor and change an A record or create a CNAME, you'll be fine. Not hard at all.

Common Info

All of the records, SPF, DMARC and DKIM records are setup in the DNS zone of your domain as a TXT record. How each is setup is a bit different from each other, but they are all setup there. That means you have to have access to the authoritative nameserver of your domain. If you use Godaddy to handle all of your domain records, then that's where you set it. If you use a hosting server for the web, and you told Godaddy to give DNS control over to that hosting server (by changing the name servers) then you setup the records over on the hosting server. If you aren't sure, figure out where your name servers are located first.

If you're using a 3rd party hosting server with cPanel and pointed your nameservers over to the hosting server, they've got some pretty cool stuff in cPanel that will automatically take care of the DKIM and SPF records for you. Otherwise, you'll have to set it up manually in the DNS Zone.

SPF Records

SPF stands for Sender Policy Framework. Like you, that meant absolutely nothing to me. What an SPF record does, is tells the recipient email server that an email they just received, is legit "if" it comes from w.x.y.z IP address OR xy.z domain. This information tells the recipient that the email MUST be somewhat legit, because it came from the IP or domain that is in the SPF record. You have to have access to the DNS Zone records to set the SPF record in the first place, so if you have access to the DNS Zone, you "MUST" be legit because you manually added an IP address of the mail server. That allows the recipient to have a better trust of the email and gives it a lower spam score on the spam filters.

Let's say your server sends an email without an SPF record. The recipient server looks at it and says: "You just sent me an email from acme.com and you came from 1.2.3.4 IP address. I have no idea if the ip 1.2.3.4 is actually CONTROLLED by acme.com, so since I can't tell.... eh... we'll throw it to the wolves and protect our user who was supposed to receive it by sending it to a black hole. Or, they might actually pass it through if the content of the email doesn't seem spamy. It can really go either way and it's all up to the recipient.

To fix this, you would create an SPF record in the DNS zone for acme.com, to tell the recipient that the email you just sent from ip 1.2.3.4, is in fact controlled by acme.com.

Things to Know

Several things you need to know about formatting and syntax of SPF records.

1) The "Record" is always TXT

2) The "host" can be pretty much anything. In other words, there's no specific host / subdomain parameter (unlike DKIM and DMARK that have specific host parameters). You can use _spf.acme.com, spf1.acme.com, myblocks.acme.com, netblocks.acme.com, _netblocks.acme.com, etc.

3) Always start the record value with v=spf1. (If the protocol gets updated in the future, you'll want to change this...)

4) Always separate the syntax with a space and semi-colons are NOT needed to separate the syntax (unlike dmarc and dkim records that require semi-colons)

5) Even though the SPF is setup and correct, some recipients will still reject your message if rDNS isn't setup (more on this later)

Something else to keep in mind is your hosting environment. Just because your domain is acme.com and the server IP is 1.2.3.4, doesn't mean that's the same IP address your email is coming from. For example, let's say you're on a shared hosting server. There might be 10 IP's on that server, spread out among 300 domains. But, they all use the same outgoing email server, using the IP of the server itself. What can be tricky, is figuring out exactly what that IP is. The easiest way is to send an email to yourself through your website webform, then inspect the headers of the email. It should tell you what the IP address was that sent the email. Gmail is really good about this. If you look at the "original" message, it has a section for SPF and tells you exactly what the IP is that sent the message.

What becomes even more tricky, is cloud hosting services. Since the hosting isn't contained to any one single server, it can be spread out among all sorts of IP addresses and figuring THAT out can be a bit tedious. For example, I helped a client out who was on bluehost.com. For whatever reason, using bluehosts spf record threw up an error that there were too many DNS lookups, so I decided to condense their list to create my own. I had to dig into their SPF records to find the list of IPs that they specify and only add those IPs to my own SPF record. Sometimes, you'll get lucky if you're on a decent hosting platform and you can simply just point to their pre-defined spf record. Other hosting providers, probably don't make that information easy to find or they have a really bad SPF record because they didn't set it up properly.

Getting the Basics

Overall, SPF records are easy to deal with. You either point to an IP address or you point to a domain.

Imagine being in the DNS zone editor for acme.com with the IP 1.2.3.4. You would create an SPF record to look something like this:

v=spf1 ip4:1.2.3.4 ~all

The "Host" would be @ and the Record would be a TXT. (the @ means acme.com on some hosting providers like Godaddy. Just know that you need to point back to acme.com)

DomainRecordHostValue
acme.comTXT@v=spf1 ip4:1.2.3.4 ~all

What if acme.com IS the IP for the email server?
There's a option you can add to make things super easy. It's simply adding an a to the list. If acme.com is IP 1.2.3.4, you don't need to add ip4:1.2.3.4. Just add a.

v=spf1 a ~all

This says: "look at the public IP address of acme.com".

What if I use the same IPs that are associated with my MX records?
There's an option you can add to look at the mx records for the domain. This usually isn't needed because a lot of times, the MX records will be different than the outgoing server IP in most cases. Even if you had a server running at your home, you'd probably be fine with just using the a option because incoming and outgoing are both on the same server. Either way, you can simply set the mx option as follows:

v=spf1 mx ~all

If you wanted the MX and the primary domain, you would set it like this:

v=spf1 a mx ~all

Ok, but what if I have a bunch of outgoing email servers on different IPs?
Simple. Just list them out, separating each new ip with ip4:

v=spf1 ip4:1.2.3.4 ip4:5.6.7.8 ~all

What if my IP is ipv6?
Just change the ip4: to ip6 and you're golden :-)

Ok, but what if my server has a LOT of IPs?
This depends... Are the IP's all on the same subnet? If so, you can simply add the subnet mask to the end of the ip4: or ip6:

v=spf1 ip4:1.2.3.4/24 ip6:2000:6000:4000::/36 ~all

If the IP's aren't on the same subnet and they're scattered all over the place, it might be time to wrap them into their own SPF record. You can totally have multiple SPF records that chain into each other. You usually want to start with the top most SPF and use that one to daisy chain down into other records. This is where it gets interesting...

What if I don't need an IP, I need a domain because I was told by my email provider to use something like _spf.acme.com
Hold your horses!! We'll get there... Keep reading...

Wrapping SPF Records

Let's say you control 5 different domains on 5 different hosting servers. Each has it's own IP. They're YOUR servers that YOU control, so you trust them and know that each one is totally legit. BUT, you don't want to keep track of IPs for each and every server, to deal with the SPF records for each domain. Choose a domain that you would consider to be the primary domain of them all. Usually, you'll have a domain that kind of "houses" all of the other domains. Use that primary domain to create an SPF record that houses the IP addresses of all the mail servers for the other domains. (This same concept will work if you use 3rd party email services like mail-chimp, or a CRM like salesforce. They generally provide their SPF records for you to point to.)

Let's say the main company is acme.com and acme.com owns the subsidiaries acme-bricks.com, acme-steel.com, acme-wood.com, acme-stone.com etc, and each domain has it's own email server, therefore IP address.

acme.com 1.2.3.4
acme-bricks.com 2.2.2.2
acme-steel.com 3.3.3.3
acme-wood.com 4.4.4.4
acme-stone.com 5.5.5.5

You would create an SPF record on acme.com to look like this:

v=spf1 ip4:1.2.3.4 ip4:2.2.2.2 ip4:3.3.3.3 ip4:4.4.4.4 ip4:5.5.5.5 ~all

Now acme.com houses the IP addresses for each of the different servers, therefore they're all legit. The next thing we need to do, is tell the OTHER domains, to point THEIR SPF record over to acme.com. So instead of adding the IP address in the SPF for each and every domain, you can set it in one place, acme.com and if the email server IP changes for any given domain, you only have to change it on acme.com because all of the other domains point to acme.com.

This is accomplished by using the include: option for the other domains. So effectively the SPF record for each domain would look like this:

acme.com TXT v=spf1 ip4:1.2.3.4 ip4:2.2.2.2 ip4:3.3.3.3 ip4:4.4.4.4 ip4:5.5.5.5 ~all
acme-bricks.com TXT v=spf1 include:acme.com ~all
acme-steel.com TXT v=spf1 include:acme.com ~all
acme-wood.com TXT v=spf1 include:acme.com ~all
acme-stone.com TXT v=spf1 include:acme.com ~all

When an email is sent through acme-bricks.com, the recipient looks at the SPF record which says: "Hey, go look at acme.com for legit servers". So it looks at the TXT SPF record for acme.com which has 2.2.2.2. It's legit! And passes the email through.

You do need to be careful when crafting these types of SPF records though because you can only have 10 DNS lookups per record. If there are too many lookups, the recipient might reject the email.

Let's look at another situation, where you have domains to other email providers, such as Mailchimp for mass email, or Google G Suite for primary email but you also have your own hosting server that sends email through the website. This isn't very many things to keep track of so they would all fit nicely inside a single SPF record, but let's say you're a neat freak and want an SPF record that ONLY holds domains and another SPF record that ONLY holds IP addresses. You would create 3 total TXT records for this, one top one to house the bottom two:

Here's an example

_spf.acme.com

  • _netblocks.acme.com
  • _netdns.acme.com

You would first create an SPF record inside the _spf.acme.com that points to the two lower SPF records:

v=spf1 include:_netblocks.acme.com include:_netdns.acme.com ~all

Then, you setup the respective IP's or domains within each of the bottom spf records:

_netblocks.acme.com
v=spf1 ip4:1.2.3.4 ~all

_netdns.acme.com
v=spf1 include:_spf.mailchimp.com include:_spf.google.com

From here, you set the acme.com SPF record to look at _spf.acme.com, so you can still point your other domains to the central spot include:acme.com:

acme.com
v=spf1 include:_spf.acme.com ~all

So, if acme.com is pointing to _spf.acme.com and _spf.acme.com is pointing to _netblocks & _netdns, when you point acme-bricks.com to acme.com, it then inherits everything that is housed within acme.com (_spf _netblocks & _netdns).

Yup, it's confusing... That's why you need a tool to help you visualize it.

DMARCIAN has a freaking fantastic tool that shows all of the links for an SPF record and they will tell you if you have too many lookups.

https://dmarcian.com/spf-survey/

Take a look at their tool against google.com: https://dmarcian.com/spf-survey/google.com

Additional Reading

google
https://support.google.com/a/answer/33786?hl=en

OpenSPF
http://www.openspf.org/
http://www.openspf.org/SPF_Record_Syntax
http://www.openspf.org/FAQ/Common_mistakes

Reverse DNS (rDNS)

Just because you setup the SPF keys and your email SPF is passing, doesn't necessarily mean your email is going to be accepted by the recipient. Some email providers, such as Comcast, will explicitly REJECT any and all mail that doesn't have Reverse DNS setup.

For example, your domain acme.com has the IP 1.2.3.4, but the server sends out email from acme.com on IP 6.7.8.9. Since your domains IP 1.2.3.4 doesn't match the IP the email came from (6.7.8.9) the rDNS fails. This means email going to Comcast along with other select email providers, don't like this. They want email from acme.com to match the IP for acme.com.

So, what is Reverse DNS?
Reverse DNS is the backwards looking IP for a Domain, known as a Pointer or PTR record. It's the primary domain associated with a specific IP. For example, you can look at acme.com and see 1.2.3.4 or you can look at acme-bricks.com and see 1.2.3.4. But if you look at what's on 1.2.3.4, you may see: acmemail.com which is considered the "primary domain" for IP 1.2.3.4. Even though other IP's point to 1.2.3.4, they aren't the main domains when looking back at 1.2.3.4.

Two Types of Reverse DNS with Email

When you're dealing with email, there are two types of Reverse DNS you need to consider:

1) The IP of the "Received from:" header of the email
When a server sends out an email, it sends out headers that tell the recipient what it is and what to do with it. Within those headers, is the IP address of server that sent the email. If the IP doesn't match the domain the email came from, then the message is rejected. Here's what the header would look like:

Received: from acme.com (acmemail.com. [1.2.3.4])

2) The actual reverse lookup
When a recipient receives an email, it looks at the domain that sent it and does a reverse lookup on the domain to find the IP. It then does a forward lookup on the domain to see what the IP is. If the two don't match, meaning acme.com -> 1.2.3.4 and 1.2.3.4 -> acmeserver.com, the message is rejected.

The only place to change your reverse DNS or PTR record as they are called, is through your ISP. It is very rare that you will have control over the domain for the reverse lookup address. Usually you must call the ISP that owns the IP. Some hosting companies, give you access through their billing interface to change it yourself. It just depends.

One nice thing about the actual reverse dns lookup, is that the domains don't have to match each other. Like the example above, if acme.com sent the email from IP 1.2.3.4, as long as when you ping the host that is found IP 1.2.3.4 (in this case acmemail.com) points to 1.2.3.4, then it's a match. This is how you get around shared hosting. The actual reverse DNS isn't as picky as the reverse lookup on the email IP header, which DO have to be an exact match between the IP and the sending domain.

What if I can't specify the IP address my email comes from for the email headers?
Well, that basically means it's time to make a decision:

1) Know that email will get rejected if sent to certain providers.

If you're going to send email out through your webserver to a single email address, such as collecting contact forms generated on the website, then chances are you're fine as long as the email address isn't rejecting based off the rDNS. (So, you can't use Comcast as the email your contact forms go to.) This is bad though, if you have an e-commerce website and you want ALL of your customers to receive their order confirmation emails.

2) Upgrade your hosting to a VPS or equivalent service that will allow you to set the outgoing IP address.

If you move over to a VPS or Dedicated server, you can then set the outgoing IP address to match the domain. cPanels WHM has the option to "Send mail from account’s dedicated IP address" in the EXIM configuration. If you're the only person handling the box, turn this on and forget about it.

I've learned through experience that companies like Hostgator, will NOT turn this type of feature on or enable it on the server. I tried contacting them and their response was that they couldn't do it because the email "routes through too many internal gateways". Their fix? Upgrade hosting to a VPS. Pretty lame if you ask me considering it has nothing to do with the "routing" of the email, but rather the server that sent the originating email.

DKIM Records

DKIM records are a public / private signing method between the sender and the recipient. There's lots of technobabble about how it works, why it works, when it works etc and I'm not going to go into that... All you need to know is that the DKIM record authenticates your domain against a public / private signing key pair. You send a message with the DKIM info and the recipient takes a look at the key and does a check against your domains DKIM record. Then it does a lookup to make sure the matches and if so, passes the email through. It's like getting a ticket to a movie and handing that ticket over to the ticket guy. Sure, anybody can have a ticket they purchased at any time, but the job of the ticket taker is to make sure the info on the movie ticket matches the list of movies that are currently playing. If not, you aren't getting in.

At first glance, DKIM looks pretty easy. There aren't many pieces to the syntax and for the most part, everyone says to "copy and paste". Don't let that fool you though. You need to understand some things about DKIM, especially if you plan to run in a cPanel type of environment.

If I can get anything to stick in your head, like really pound it in there, I want you to make sure you know and understand that you MUST have a unique key for each email server, and each domain. "What's that mean?" Let's say for example, you have two domains and need email on 1) a Webserver with a contact form 2) Email through Zoho or G Suite and 3) MailChip for email lists. This adds 3 different email servers (SMTP) into the mix and you have your two domains for each server, so you would need 6 different key pairs. Each server, must have the private key loaded onto the server per domain so when the request comes in on the public key, the server can send the response that says "Yup, that's legit!". Unless YOU have direct control over the root access of the various servers, you aren't setting up a DKIM key... Fortunately, the good email platforms, already have key generators setup on their end and all you have to do is generate the key and create the new DNS TXT record. This means you don't have to come up with your own key pair, then try to get MailChip to use YOUR key... They already provide you with one and have it stored in the right place on the server to make it easy for you.

While we're on the topic of having the 3 different services and say, 2 domains, hopefully you can kind of see why you need 6 unique DKIM keys. You can't exactly get Google or MailChip to use your own generated private key and they aren't going to just go off and give you their private key... Because it's private... and that's the whole point...!!!! So that means one part of the key pair is stored on the server, the other part of the key pair is stored in your DNS TXT record, and this is multiplied across each and every top-level domain and sub-domain that needs email signing.

Ok. I think we're good. Hopefully... Because now you need to understand how this impacts a lot of 3rd party hosting companies. Which can get a bit confusing, unless you've read this whole explanation, and since I make mud look clear as mud, you'll be good to go after this.

cPanel Instruction & Other "Hosting Made Easy" Platform Info

When I first started messing with DKIM records, I honestly thought you generated your own key, put the public key info out in the TXT record and somehow, because you generated a key, the other side (whichever that may be) would automajically pull the private key out of thin air. Yeah, it doesn't work that way... That private key has to be somewhere and usually, it's automatically generated on your website hosting platform. For you. Easy Peasy. Or is it... ? You'll find that some hosting providers don't provide the ability to enable DKIM. They've got you on a super old setup that doesn't even expose email authentication. If that's the case, seriously, go find a new hosting provider. Your current one isn't worth the money you're paying them.

I'm going to discuss cPanel because it's what I'm familiar with. Hopefully I give enough insight that can help you on non-cPanel platforms.

cPanel, a few years back, introduced the ability to enable DKIM globally for your entire account, from the cPanel interface (Email -> Authentication). This enables DKIM on all of the the domains for your account which is super awesome because it creates the private key and stores it for you in the background, then takes it a step further and adds the necessary TXT records into it's local DNS system on the server. This can be super good, if you're using the hosting platforms nameservers, but it can be super-duper confusing if you're hosting your nameservers elsewhere.

If you pointed your nameservers to the hosting server, you're golden. Sit back and relax because your emails are now being signed (assuming nothing else went wrong)! You can basically forget everything blow this point (for the DKIM stuff) and bask in the fact that you can remain blissfully ignorant. Yes, I'm jealous.

However... and this is a big HOWEVER, if you're using the nameservers elsewhere, on say... Godaddy, you have some work to do. I'm going to assume you have half a brain to figure out what I'm about to say, since you're hosting the nameservers elsewhere. cPanel did the heavy lifting for you and generated both keys and stored the private key and they even went so far as to update it's local DNS records for your account. Great. From here, it could get a bit fuzzy. You might be able to access the DNS Zone Editor to pull the public key out, you might not. It all depends on whether your hosting provider gives you access to the "Advanced Zone Editor". If you DO have access to it, then you can basically copy and paste the key and be done with it. But if you don't have access to it through the interface, you'll have to SSH into the server, dive into the directory /var/named and view the DNS zone .db file for each and every domain to pull out the TXT record so you can enter it on your domain registrar or nameserver.

In other words, you'll have to go find the public key that resides on your hosting server, so you can use it to create the record on your nameserver provider.

Things to Know

1) The "Record" is always TXT

2) The host must always have a minimum of _domainkey before the main domain. (ex: _domainkey.acme.com)

3) Always start the record value with v=DKIM1;

4) DKIM record syntax is always separated with a semi-colon ; and left off of the very last syntax option.

5) You "may" need to escape the semi-colon depending on your DNS editor. (probably not though...) For example k=rsa\;

6) Not all DNS providers are the same!! Some providers may require you to separate the key, within the record. This can be done by quoting the various pieces to create 255 characters between the first set of quotes, then finishing the last part of the record off with the second set of quotes. I'll explain this a bit later.

7) Some DNS providers might have buggy front-end or backend software! This translates to mean that even though you enter in a correct DKIM record (Bluehost) a 2048 bit key doesn't get translated to the backend DNS server software properly, or the DNS server software is outdated and doesn't understand how to chunk the value. In the case of Bluehost, chunking the key value did absolutely nothing... It's a problem on their end though.

Getting the Basics

Adding DKIM records are, for the most part, pretty easy. You have the statement that tells what the protocol is designated with v, the key type designated with k and the key itself designated by p.

Let's put it all together:

v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkArcXi9GwuT2Hm0VO/bDU58BFhmaol1Wv+lAgx+fcKGyF+dQHhB63A0+UBW6nyiejCelMjPU5LpcSGKUTfCmIpG3eSF3nSONz6lDIQYeujnzifXy9nvei25g26Jrtme3q5POoSv6RMpEyHieMfVglZbazasyrOszRUxmRTrZZud6msDiVuSwrSPA1tT80olSUX5V9LWYxVjLcj5SYe7PRoHD5iyjmfioLUgAo/IznpXpnf9tIgr8kwAqFFV4/EzxTbh6/vV1sa5qSVZprhdZHBFLbWj4iMOESghXhOVZV1U4WLIa+l/abAlklAXn6sxo4aGkKCIvVtYTZecslXVwIDAQAB

So where do you get the key?
If you read upto this point, you'll know that keys are generally provided by your various hosting or email providers. If you know how, you can generate your own key and add it to your server, but otherwise, I don't recommend going that route.

The _domainkey Policy Route

When adding the DKIM record, it's very similar to the SPF record. You use a TXT record to hold the information, but instead of pointing the host to the main domain (@), you need to have _domainkey as the host. It's like a CNAME record or subdomain.

For example:

DomainRecordHostValue
acme.comTXT_domainkeyv=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9....... (the rest of the key)

This would end up looking something like _domainkey.acme.com TXT v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9....... (the rest of the key)

Some websites will state that you can simply use _domainkey as the host and while this may be true, you're actually supposed to use a selector at the beginning of the host to designate a specific record. _domainkey is the "Policy Record" where the selector is the "Selector Record".

Ok, what does that mean?
If you want to tell the recipient what kind of policy YOU want for your signed emails, you use the _domainkey without a selector with a value of v=DKIM1 o=~ or v=DKIM1 o=-. This tells the the recipient that "o=~" SOME of the emails are signed by acme.com or "o=-" ALL emails are signed by acme.com. If you don't use the policy record (the _domainkey without a selector) then it just defaults to "o=~". I've got a handful of domains without the policy record and it's signing emails just fine...

The Selector Record

Selector are added to the beginning of the _domainkey, followed with a period.

It looks like this:

[selector]._domainkey and put together with the domain, it ends up like [selector]._domainkey.acme.com.
That doesn't really give a good realworld, so let's call our selector dkim for simplicity. It would look like this:

dkim._domainkey.acme.com

The selector can be anything that is alphanumeric. I'm not sure if it can be uppercase or not, but I'd stick with lowercase personally and I'm not sure if it can start with a number... From what I've seen though, the number comes at the end of the selector, such as dkim1 or key2.

So, let's say you setup your selector to be key1, the record would end up looking something like this:

key1._domainkey.acme.com TXT v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9....... (the rest of the key)

Now that you've got a decent understanding about the keys, let's talk about separating the keys to fit within the TXT record. Some providers like Godaddy, will let you enter the full key record because they split it up for you on the backend. RFC for the TXT records dictates that you can only have 255 characters maximum, which means harder-to-use domain providers, will want you to separate the key with quotes.

Here, it's easier if I just show you:

"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3wneU8W5M72g3ZJy4qG4QU2y+yiYbCTDZ09wAYAD4qlQWAmc15fFJEYTgIWkvmcro1VEYGKEVbUXhDQHCwFPBFuLlKvS7D8uRhO746FhwK0frmxg0j0f8Sx5EWh0q5QCw6OktqmKFLLzZ5KUunyAaoOWCWLEbIonDfRs/iNIOsc3MJHaHs/Egrgwkdd" "QVZGsSVS41gDAyPdxml/7bkWwsHYgaiLdIcSg3vvAjpSk5mDZIxzyOPIYMRfqmhVeziw0dBjP0fXbtj/f7VeIK+TXcvW64j9qPncBHM9yToGqvqNzCE5roZZNAucieEXM+wCwEsgLvmeMJfAMvExUpDSinwIDAQAB;"

So "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQ...[+215 more characters = 255]" "[the rest of the key]...xUpDSinwIDAQAB;"

By separating with quotes, then a space between groups, you essentially create line break within the DNS system with each block containing upto 255 characters. (because DNS servers are smart enough to figure THAT out, but not when to count to 255 and separate them automatically...)

That's it with DKIM keys. They're really pretty simple to implement, just an absolute headache if you don't know "I need the public key from each and every one of my service providers! DKIM Generators won't do squat for me unless I'm a superguru! And I need a different DKIM key for each and every domain!" If you can't tell, I hit my head against the email wall for about a week trying to sort this out...

Additional Info

Validators
https://dmarcian.com/dkim-inspector/
https://www.mail-tester.com/spf-dkim-check
https://mxtoolbox.com/dkim.aspx
http://dkimcore.org/tools/keycheck.html

Documentation
http://www.dkim.org/
http://www.dkim.org/info/dkim-faq.html

DMARC Records

DMARC records are basically an authentication blowback mechanism. If an email gets rejected by a recipient because it doesn't have SPF or DKIM setup, usually the recipient server will just discard the message as spam and won't notify anyone about it. DMARC fixes this by telling the recipient "Hey, if you're going to throw it away, at least send it over to my email so I can look at why you threw it away."

Using an email within the DMARC isn't necessary to keep track of the rejects, but it helps give you a much better understanding of what's happening to your email when you get a customer calling up complaining because they "never received an order confirmation letter."

DMARC is designed as a way to prevent hackers from spoofing your domain and sending email on your behalf, without you knowing about it. The DMARC record gives YOU the control, to tell the recipient what to do with the email if the SPF and(or) DKIM don't pass. It pretty much says that if SPF fails or DKIM fails, then quarantine or reject the email. Quarantine leaves the decision up to the recipients spam filters, but this can be seen AS spam and they might block you over time. Reject on the other hand, flat out denies the message. Eventually, telling the recipient to "reject" email is the ultimate goal of where you want your email setup to be.

Things to Know

1) The "Record" is always TXT

2) The "host" must always have _dmarc at the minimum, before the main domain. (ex: _dmarc.acme.com)

3) Always start the record value with v=DMARC1;

4) Like DKIM record values, the DMARC record values must be separated by a semi-colon ; except for the last item in the value.

You can setup a single domain email, that spans across multiple domains. I'll explain this in a bit.

Getting Started

DMARC records are just like SPF and DKIM records. They live within TXT records. While there's a handful of syntax options you can choose from, there's really only 3 syntax you need to worry about to make it pass, with the 4th being an optional setting:
1) The protocol version: v | Which is currently DMARC1 -> v=DMARC1
2) What to do with it: p | Options are none (do nothing), reject (dumps it), or quarantine (sends holds onto it for a while for further investigation by the sender)
3) Where to send it: rua | MUST have mailto: -> rua=mailto:authreports@acme.com
4) How often to report: pct | is a percentage of email to send to the reporting email, for example p=75 is 75% percent of the email gets sent back for review.

Diving In

Like the DKIM record, you have to use a specialized "host" to designate it as a dmarc, which is _dmarc

Put together with the domain and you end up with:
_dmarc.acme.com

Pretty simple.

DomainRecordHostValue
acme.comTXT_dmarcv=DMARC1; p=quarantine; rua=mailto:authreports@acme.com

When you look at it in the editor, you get something like:

_dmarc.acme.com TXT v=DMARC1; p=quarantine; rua=mailto:authreports@acme.com

One Email, Multiple Domains

So let's say you control 5 different domains. (we'll refer back to the acme.com domains in the SPF Records area) You want each domain, to send all rejected email, back to mailauth@acme.com. It's totally possible, but it requires a special host be setup within the DNS of the primary email domain, in this case acme.com.

You first setup all of the DMARC records on the various domains, for example:
_dmarc.acme.com TXT v=DMARC1; p=quarantine; rua=mailto:authreports@acme.com
_dmarc.acme-bricks.com TXT v=DMARC1; p=quarantine; rua=mailto:authreports@acme.com
_dmarc.acme-steel.com TXT v=DMARC1; p=quarantine; rua=mailto:authreports@acme.com
_dmarc.acme-wood.com TXT v=DMARC1; p=quarantine; rua=mailto:authreports@acme.com
_dmarc.acme-stone.com TXT v=DMARC1; p=quarantine; rua=mailto:authreports@acme.com

Next, you need to add a pointer for each of the extra domains, back to acme.com with a record that uses the domain, with ._report, with ._dmarc. Notice there's a period before ._report and a period before ._demarc. They're subdomains, so they must be treated as such.

So, for acme-bricks.com, your host should look something like this:
acme-bricks.com._report._dmarc.acme.com

so-on and so-forth:
acme-bricks.com._report._dmarc.acme.com
acme-steel.com._report._dmarc.acme.com
acme-wood.com._report._dmarc.acme.com
acme-stone.com._report._dmarc.acme.com

The value for these, is super easy. Just add the protocol to the value. You end up with it looking like this:

RecordHostValue
TXTacme-bricks.com._report._dmarcv=DMARC1
TXTacme-steel.com._report._dmarc.acme.comv=DMARC1
TXTacme-wood.com._report._dmarc.acme.comv=DMARC1
TXTacme-stone.com._report._dmarc.acme.comv=DMARC1

Additional Info

Validation
There are quite a few validators out there, but my favorite is:
http://www.valimail.com/dmarc/domain-checker#/

Tags & Purpose

Tag Name
Purpose
Sample
Options List
v
Protocol version
v=DMARC1
DMARC1
pct
Percentage of messages subjected to filtering
pct=20
[0 - 100] (anything between 0 and 100)
ruf
Reporting URI for forensic reports
(any valid email address)
rua
Reporting URI of aggregate reports
(any valid email address)
p
Policy for organizational domain
p=quarantine
none | quarantine | reject
sp
Policy for subdomains of the original domain
sp=reject
none | quarantine | reject
adkim
Alignment mode for DKIM
adkim=s
r (relaxed, default) | s (strict)
aspf
Alignment mode for SPF
aspf=r
r (relaxed, default) | s (strict)

Documentation
https://dmarc.org/2015/08/receiving-dmarc-reports-outside-your-domain/
https://dmarc.org/wiki/FAQ

DMARC Analyzing

Once you have your SPF record, DKIM signing, Reverse DNS and DMARC in place, the next step is to sign up for a DMARC aggregator website that you send all of your DMARC emails to. These services do charge for larger volumes of email, but the benefit is that you don't have to weed through 15+ emails every day with a zip file containing an un-formatted XML file. DMARC Analyzer for example, will put everything together into graphs and gives you a MUCH better idea of what you email is actually doing which is part of the whole point of DMARC records in the first place.

After you begin collecting data, you'll start noticing what your emails are doing. If they are failing or not aligning, check out Agari.com for some details on how to fix those problems: https://www.agari.com/identifier-alignment/

In a situation I ran across, DMARC was failing when sending email to a group email through Google's G Suite. The domain was an alias domain on the G Suite account, so it didn't make sense why it was failing when everything else (SPF & DKIM) were correct. This led me to the agari.com site I mentioned above, which mentions that the "From Domain" address must match. Oddly, G Suite would NOT send the email from domain as the alias on the group, only on the main account domain, causing the failure. I decided to look THAT up and it led me to a serverfault.com answer that describes the problem and fix exactly: https://serverfault.com/questions/779730/why-dont-my-domains-messages-to...

Google Groups will only rewrite the From: header when the DMARC policy of the original sender (you in this case) is set to reject or quarantine.

With DMARC/p=none, DKIM isn't rewritten when sending to a group, but because DMARC is set to "none", it doesn't matter that the group will break DKIM from the point of view of delivery and spam detection - it will still get delivered properly. Unfortunately, it does make it look confusing if you're monitoring your deployment.

In order to see the correct behavior you can switch to p=quarantine and monitor the delivery. Please tell me if there is anything else I can assist you with, I'll be glad to follow up.

I did indeed have the p=none set because I was in the beginning stages of testing the email DMARC rates, so the next step would be a quarantine and eventually reject.

Post Comment

(If you're a human, don't change the following field)
Your first name.
(If you're a human, don't change the following field)
Your first name.

Comments

Hi Phil,

You spoke of your struggles with BlueHost for one of your clients. I'm with Bluehost and was able to set up my SPF records, but I'm struggling to enable DKIM for my domain. I reached out to support and they simply told me they don't set up DKIM for their customers and just told me to visit http://www.dkim.org/... Did you manage to set it up for your customer finally? If so, can you share how you did it?

Hey Nick,

I hate to say it, but I honestly don't remember exactly what the outcome was. (I've slept since then) I want to say the client did get BlueHost to comment on the issue, but I can't remember if they were able to set it up, or if he was told that they don't support it at this time but it was in the works... I'm pretty sure it was the latter.

Considering that the DKIM protocol began around 2004 and was finalized to be the protocol it is today in 2011, I'm going to throw it out there and say that: "Any hosting company that doesn't offer DKIM signing as part of their hosting platform, isn't worth using."

Hosting companies that use the true cPanel platform and let you control everything through the actual cPanel interface, should already be setup to offer DKIM as long as you have access to the "Advanced DNS Zone Editor". Companies like BlueHost or MediaTemple want you to use their own in-house DNS GUI and DKIM isn't really on their radar.

The fact that the customer support at BlueHost sent you over to dkim.org, goes to show how clueless they are about how it actually works. The private keys MUST be setup on the originating server and tied to the email portion of that server.

Given the importance of email authentication, it is flabbergasting how many website and email hosting companies, aren't even setup for it. Intuit's online Quickbooks for example, a billion dollar company, doesn't even offer DKIM keys for when a customer sends an invoice on behalf of their domain.

I wish I had better news for you on the matter, but unfortunately, my ultimate recommendation is to dump BlueHost. I tried to talk my client into moving somewhere else, but wasn't successful :-/

Thanks for your reply. Really loved the article by the way. It was the most succinct summary I could find on e-mail authentication.