Enhancing Email Security: Stop Sender Fraud with SPF, DKIM, and DMARC
July 23, 2015
11 minute read
There’s no filtering out the truth: You need to protect your company’s email.
In 2013, more than 100 billion business emails were sent and received each day. Just one in five of all emails sent in 2013 were legitimate, and 92% of all illegitimate emails included links to potentially malicious content.
There are signs of improvement however; this month is the first in the last 12 years where less than half of Symantec’s clients’ emails were spam.
You can thank three email security standards (and other initiatives) for the reduction in spam: SPF, DKIM, and DMARC. Still, security risks are prevalent. I was recently told a story about a CFO who was subject to a phishing attempt. The attempt failed, but if it had succeeded, it would have cost the organization $50,000.
As for these email standards, there’s still a great deal of confusion surrounding them. I hope I can provide some clarity with this post, as well as walk you through how to implement SPF, DKIM, and DMARC.
Sender Policy Framework (RFC 4408)
Sender Policy Framework, or SPF, is the old man at the email authentication party. SPF is an open standard that specifies a method for preventing sender address forgery, according to openspf.org. It isn’t about stopping spam; it’s about controlling and stopping attempted sender forgeries.
SPF enables you to identify your domain’s legitimate mail sources and prevents unauthorized sources from sending thousands—or even millions—of illicit emails from your domain.
There are four types of email abuse commonly associated with email sender forgery:
- Spam (unsolicited bulk email & unsolicited commercial email)
- Fraudsters (419 scams)
- Malware (adware, zero days, viruses, trojans, etc.)
- Phishers (spear-phishing)
You don’t want your organization’s domain associated with any of these for obvious reasons. SPF will help to make sure your organization’s emails are actually coming from you.
DomainKeys Identified Mail (RFC 6376, replaces RFC 4871 and RFC 5672 which are now obsolete)
DKIM, or DomainKeys Identified Mail, is a TXT record published in your Domain Name System (DNS). It involves something that all IT admins should learn to love: keys—public keys to be specific.
Before we dive into DKIM, it’s important we understand what keys are and how they work. Keys, in this case, public-key cryptography, consists of a public (known to everyone) and private (often referred to as secret) keys. Public and private keys are mathematically linked to one another, making secure communication over public channels possible.
These keys are like a tamper-evident seal on a transparent envelope. You’re not necessarily hiding the message; you’re only authenticating with 100% certainty both the sender and the message.
Now, back to DKIM.
“Technically DKIM provides a method for validating a domain name identity that is associated with a message through cryptographic authentication,” according to dkim.org. In other words, DKIM uses keys to make sure an email sender is who they say they are.
With DKIM, public and private key pairs are generated to keep mail servers and communications authenticated. Each outgoing Simple Mail Transfer Protocol (SMTP) server needs the right private key and prefix in order to match a public DNS record that the receiving mail server then verifies.
Ever wonder why the lock icon shows up in Gmail when you get messages from eBay, Paypal, or your bank? That’s DKIM and a little bit of DMARC (which we’ll cover shortly). Below, mailed-by shows the SPF match and signed-by shows the DKIM match. DKIM and DMARC aren’t essential just yet, but like IPv6, it’s moving quickly from test-lab to better-have.
Domain-based Message Authentication, Reporting, and Conformance (RFC 7489)
DMARC, or Domain-based Message Authentication, Reporting, and Conformance, helps senders and receivers work together to create more secure email communications. DMARC was created by a group of organizations to limit email-based abuse “by solving a couple of long-standing operational, deployment, and reporting issues related to email authentication protocols,” according to dmarc.org.
DMARC enables the message sender to indicate that their messages are protected with SPF and/or DKIM. A DMARC policy applies clear instructions for the message receiver to follow if an email does not pass SPF or DKIM authentication—for instance, reject or junk it.
Also, DMARC sends a report back to the sender about messages that PASS and/or FAIL DMARC evaluation.
How to Implement SPF, DKIM, and DMARC
Now that we have a better understanding of each of these three standards (and why they’re important), let’s take a look at how you can improve your email security by implementing them.
Note: For the sake of this step-by-step walkthrough, let’s pretend you’re the IT lead at 301 Moved, a small web design firm that uses Google Apps.
Recently, you’ve been having some trouble with Russian spam bots. Your end users have been complaining about receiving email bounce notifications from addresses they’ve never seen or sent messages to. You realize that someone is clearly sending fraudulent emails from your domain.
So how do you stop them?
Note: I’m including the standard BIND format in plain text and a screenshot of how the record looks in GoDaddy DNS. In GoDaddy, all records for the top-level domain 301Moved.com use the host “@,” your host will likely be different. For the purpose of this exercise, I’ll only be discussing outbound mail, not how we treat these standards in relation to inbound mail from external senders.
Implementing SPF
Step One: Google’s guide to configuring SPF records to work with Google Apps is a good place to start. Following those instructions, we add a new TXT record to our Public DNS.
301Moved.com. IN TXT “v=spf1 include:_spf.google.com ~all”
301 Moved also uses Zendesk, a ticketing system that sends out email directly from your domain. You need to make sure no spam is being sent from there either.
Step Two: Find and add Zendesk’s SPF record.
301Moved.com. IN TXT “v=spf1 include:mail.zendesk.com include:_spf.google.com ~all”
It’s important to note that we aren’t adding a second SPF record, that will break things; instead, we’re combining them into a single record, making it longer as more senders are added.
Note: You can only add one SPF record per domain or subdomain.
You also know that 301 Moved has an old email gateway on premises that handles some legacy stuff, so let’s add their IP block as well. 301 Moved uses the “IP4” mechanism to define the IP block it owns—198.51.100.0/24 (192.51.100.0-254).
Use Dmarcian’s SPF Surveyor to view your SPF records.
Step Three: Add single IPv4 addresses on their own, and netblocks in Classless Inter-Domain Routing (CIDR) notation. 198.51.100.0 for a single IP address (don’t need a /32) and 198.51.100.0/24 for subnets.
301Moved.com. IN TXT "v=spf1 ip4:198.51.100.0/24 include:mail.zendesk.com include:_spf.google.com ~all"
Adding the old email gateway will ensure outgoing email from the gateway will be SPF authorized.
The mechanisms above are the most commonly used, but there are eight in total—including the weird and deprecated. These mechanisms only define the scope of the match, not the actions themselves.
The qualifiers in the next section are where PASS, SOFTFAIL and FAIL can be defined—a match would result in one of the three (PASS, SOFTFAIL and FAIL) actions being triggered.
- ALL: Matches anything not already defined by another mechanism will match the all mechanism
- A: If the domain name has an address record (A or AAAA) that can be resolved to the sender’s address, it will match.
- IP4: If the sender is in a given IPv4 address range, it will match.
- IP6: If the sender is in a given IPv6 address range, it will match.
- MX: If the domain name has an MX record resolving to the sender’s address, it will match (i.e. the mail comes from one of the domain’s incoming mail servers).
- PTR: If the domain name (PTR record) for the client’s address is in the given domain and that domain name resolves to the client’s address (forward-confirmed reverse DNS), match. This mechanism is deprecated and should no longer be used.
- EXISTS: If the given domain name resolves to any address, it will match (no matter the address it resolves to). This is rarely used. Along with the SPF macro language it offers more complex matches like DNSBL-queries.
- INCLUDE: If the included (a misnomer) policy passes the test this mechanism matches. This is typically used to include policies of more than one ISP.
Next up are the qualifiers. There are a million ways to combine these with a blacklist and/or a whitelist model, but for our purposes here, we’re going to include only the three lookup mechanisms we mentioned above with a single qualifier at the end to make a whitelist. Our four qualifiers are:
- + for a PASS result. This can be omitted; e.g., +mx is the same as mx.
- ? for a NEUTRAL result interpreted like NONE (no policy).
- ~ (tilde) for SOFTFAIL, a debugging aid between NEUTRAL and FAIL. Typically, messages that return a SOFTFAIL are accepted but tagged.
- – (minus) for FAIL, the mail should be rejected (see below).
Step Four: Apply the SOFTFAIL policy.
For now, 301 Moved uses the tilde for SOFTFAIL. By using the tilde, all mail not matching Google, Zendesk or the IP block mentioned would SOFTFAIL. Mail will still be delivered, but it will likely be sent to the Spam or Junk folder. However, this is entirely up to the recipient’s mail server. It is not defined by any standards.
A “–” (minus) in this situation would FAIL (and likely bounce) non-matching mail entirely. You can flip that on once you start getting more visibility into your outbound mail (wait for DMARC), and once you get more comfortable with your mail infrastructure.
SPF is great because there’s no modification of the mailservers themselves. Headers stay the same. Just a simple TXT record (the actual, dedicated SPF record type was never that popular and is now deprecated) and you can instruct most of the mailservers in the world who should be flashing your name around.
At the end of the day, the receiving SMTP server checks the sender IP against your SPF record that it queried, it then applies the policy based on your instructions. In other words, you’re authorizing yourself, and your providers, to send (mostly) trusted mail because you’re publishing an access control list (ACL) to the public.
However, messages can still be modified in transit, and crafty forgers and phishers can sneak around SPF in some interesting ways (maybe a topic for another day). It’s SMTP: End-to-end TLS isn’t guaranteed, so we must always assume cleartext. Messages can be tampered with or forged.
But enter stage right…
Implementing DomainKeys Identified Mail
When mail is sent, 301Moved.com signs (without encrypting) mail with the private key. From now on, any modification to the message, including body, headers or attachments will break the signature and render the message invalid. Again, we look to Google, using their article Authenticate email with DKIM
Step Five: Add the public key to your DNS record.
google._domainkey.301Moved.com IN TXT “v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsC1iZ3D7AR3FrKtBYfnoKztCGgExFIReC0b1MPY1rpGZa9aTBYq7cDV6F8lzDVr8/K+z9Xt1gUV4P7tT8wuwgacR4oqiAWaUprbnINAxinJr4ohB1TIW3diX2fEA2t5kyUGCGziJFlHicZyJbk5QEaVLcSFD4V8R9f0Voz4P4jQIDAQAB”
Each DKIM record has a unique selector prefix, meaning we can publish more than one. Instead of combining them to a single record, like we did with SPF, you can use unique selectors and publish as many public keys as you need. This allows us to add a large number of DKIM authorized servers without any upper limits.
You’ll notice that the prefix above is “google,” the default that Google Apps uses when generating a DKIM record for you to publish. You can change this in Google, and most other setups, so if you wanted the prefix “dkimawesome,” there’s nothing stopping you.
Some cloud providers do it differently. Instead of generating unique key pairs for each cloud tenant, they sign all outgoing mail for all domains with the same key—while having you publish a Canonical Name (CNAME) instead for their key.
Zendesk does this, we CNAME two different keys on our DNS to their DNS. Zendesk has a great help article- Digitally signing your email with DKIM or DMARC (Plus and Enterprise)
Step Six (if applicable): CNAME the keys on your DNS to their DNS. Any DNS query looking for zendesk1._domainkey.301Moved.com will be redirected by your DNS to zendesk1._domainkey.zendesk.com. Zendesk then serves the DKIM keys directly.
zendesk1._domainkey.301Moved.com IN CNAME zendesk1._domainkey.zendesk.com zendesk2._domainkey.301Moved.com IN CNAME zendesk2._domainkey.zendesk.com
We can see what this looks like to other servers by using the nslookup tool (for Unix or Windows) locally.
Not all outgoing senders support DKIM. Google Apps obviously does, but your legacy mail servers may not.
Implementing Domain-based Message Authentication, Reporting, and Conformance
DMARC, or Domain-based Message Authentication, Reporting, and Conformance, is the final tool we have to combat malicious email. For mail servers that listen, DMARC, relays how to treat SPF and DKIM, as well as how to report back to you, giving you much-needed visibility into your delivery rates and record compliance.
And yes, DMARC is another TXT record.
Step Seven: Set up a DMARC policy, identify the mailto address, set up the alignment mode, and identify the percentage of messages that the policy should be applied to (don’t worry, this is simpler than it sounds).
301Moved.com. IN TXT "v=DMARC1; p=none; rua=mailto:postmaster@301moved.com; adkim=r; aspf=r; pct=100; sp=none"
The policy above is designated as p=none. We’re not modifying mail flow at all yet—simply setting up the policy and it’s relevant reporting. The address that the XML reports of DMARC status will be sent to is designated with rua=.
Receiving mail servers will send XML attachments showing how messages from—and those claiming to be from—your domain stacked up against the SPF, DKIM and DMARC gauntlet most modern mail servers impose.
These reports show, on a per envelope basis, whether SPF passed, failed or softfailed. They show whether DKIM failed, failed alignment or succeeded—and how the above policies were applied.
Lastly, these reports show the final delivery disposition of the message. There are some great tools out there to help you parse these. Even if you’re not applying policies to messages, it’s like firewall, DNS and IDS/IPS logs—it’s always good to have something that you can go back and look at.
The adkim=r specifies relaxed DKIM alignment mode, “r” is for relaxed and “s” is for strict. Relaxed mode allows authenticated DKIM d= domains within a common Organizational Domain in the mail header-From: address to PASS the DMARC check. Strict mode requires a perfect match between the DKIM d= domain and an email’s header-From address. Think subdomains, if you use them.
aspf=r does the exact same thing, except for SPF checks.
The pct=100 is the percentage of messages that are actually treated to the DKIM policy. Chosen at random, the receiving mail server will enforce policy on this percentage of messages from your domain. We’re using 100 for now because we’re not applying a policy, yet.
Before we apply a policy, we will throttle this down to five so that only one in 20 messages have policy applied as we turn the p= policy flag onto quarantine or reject. This way, if we totally screw this up 95% of our email will still be delivered, instead of 0% delivered if we started at pct=100.
Messages failing the DMARC check, or your adkim= and aspf= alignment modes that we set above are then soft bounced, like above, for a quarantine policy, or bounced entirely when set to reject.
It’s very important to note that DMARC will PASS the message if either SPF or DKIM passes, and only FAIL the message if both SPF and DKIM FAIL. That way SPF-only and and DKIM-only messages can PASS DMARC, but messages without either SPF/DKIM will always FAIL. This is great news if you have mail systems the support only SPF, or only DKIM.
Use Dmarcian’s DMARC Inspector to check out view your DMARC records.
Dmarcian is a paid tool that allows you to manage your DMARC reports easily, there are many others, but Dmarcian happens to be my favorite.
Update: We’ve received a few (DMARC compliant!) emails asking about the subdomain policy sp=none. With a policy that includes sp=none you aren’t specifying a DMARC policy for any subdomains. This is done manually by setting up an appropriate DMARC record for each specific subdomain or included in the main DMARC record with a sp=quarantine or sp=reject.
Minimum Config
If you want to try this out, I recommend that you start very open and stay simple until you have enough DMARC reports to start enforcing anything.
301Moved.com. IN TXT "v=spf1 ip4:198.51.100.0/24 include:mail.zendesk.com include:_spf.google.com MX ?all"
Define big providers with an “include:” and any IP blocks you may send mail from with an “IP4”or “IP6.” Use “MX” to authorize your incoming mail servers. And unless you send mail directly from the same box/server that hosts your website (bad, bad practice by the way) you can skip the “A” mechanism that was mentioned above. The “?” applies no policy to your messages, but gets your SPF record out there so DMARC can recognize it.
google._domainkey.301Moved.com IN TXT “v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsC1iZ3D7AR3FrKtBYfnoKztCGgExFIReC0b1MPY1rpGZa9aTBYq7cDV6F8lzDVr8/K+z9Xt1gUV4P7tT8wuwgacR4oqiAWaUprbnINAxinJr4ohB1TIW3diX2fEA2t5kyUGCGziJFlHicZyJbk5QEaVLcSFD4V8R9f0Voz4P4jQIDAQAB”
Get the correct selector, “google” in this case, and the right key. Remember, you can publish more than one.
Note: Please don’t publish this actual key or I’ll be able to DKIM-sign your mail.
301Moved.com. IN TXT "v=DMARC1; p=none; rua=mailto:postmaster@301moved.com; adkim=r; aspf=r; pct=5; sp=none"
For DMARC, we have no policy applied, we’re in relaxed mode, but we are asking for the XML reports to be sent to a mailbox we can access. From there, DMARC gives us fairly rapid (not real time) feedback into how we can tighten down the different policies in all three records.
But Wait, What About TLS?
Transport Layer Security, or TLS, isn’t part of the DMARC standard, and it isn’t a DNS record.
Instead, TLS is just a grown-up Secure Socket Layer (SSL) that mail servers can use to submit messages to each other over public connections. It’s SMTP wrapped in TLS, like you can do many other things inside/over TLS—SNMP over TLS and FTP over TLS being common examples. TLS only encrypts messages in transit, not at rest.
If we send a DKIM-signed message over TLS, it’s signed for its entire life, but only encrypted as it hops from your Google Apps to their Cisco Ironport, or wherever your mail transits. TLS most certainly does not protect messages at rest, although it’s also used for your HTTPS:// session to webmail as you’re reading that same message, but again, that’s in transit.
TLS is something you should use wherever possible, but also be ready to speak cleartext to other public mail systems. Even in 2015 some mail servers do not support STARTTLS (serverspeak for beginning the TLS handshake).
You can enforce the usage of TLS with certain external domains in Google Apps with a simple configuration change. It’s a good thing to turn on for associated external businesses, partners, and other organizations, but only enforce TLS once you’re sure it’s reliable and supported by all mail servers on that specific domain.
The Importance of Email Security and Avoiding Sender Fraud
Whether you’re a veteran IT administrator or just starting out, these three standards hold the same importance. Admittedly, what each of them do, and how they work together can get a bit cluttered, but implementing them is relatively straightforward—and the benefits are well worth your time.