Why your Marketing Email will Land in my Spam Folder ? The Non-marketing Guide: DKIM, SPF & DMARC

Aymen El Amri
Startups & Venture Capital
7 min readSep 10, 2017

--

Investing time and money, then land in your customer’s spam folder just like a spammer? Not a good idea !

You will find a LOT of blog posts that deal with the same topic I am exposing here, but not in the same manner.

To make a good emailing campaign :

  • Make people happy and send them what they want to read
  • Ensure you’re sending emails to users who requested it
  • It’s preferable to have a double opt-in process
  • ..etc

I think these practices are already used by most marketing professionals.

Most of the blog posts, at least what I’ve been seeing in the last years, are teaching readers the same things: ABC's of email marketing.

From a technical point of view, emailing is tricky and the best practices should include some technical tips. This is the purpose of this article.

Domain Keys Identified Mail

Your domain should have a good reputation and one of the things that you should absolutely consider is authentification it with DKIM.

DKIM (or Domain Keys Identified Mail) is an email authentication standard that uses a public/private encrypted key to authenticate the domain sending emails.

If you’re sending an email using an address like hello@myproduct.com, it is recommended to set up its DKIM.

When you send an authenticated email:

  • You should generate the key pair (public/private) to sign the outgoing email
  • Publish the public key to your DNS zone in a TXT record
  • Your private key will be used to create a signature for each outgoing email. Using a security algorithm, the content of the email is combined with this key and a signature header is generated as a result.

For more technical details, this is the official explanation taken from DKIM website:

More formally, the algorithm for the signature is as follows:

body-hash = hash-alg(canon_body)
header-hash = hash-alg(canon_header || DKIM-SIG)
signature = sig-alg(header-hash, key)

where

  • sig-alg is the signature algorithm specified by the “a=” tag,
  • hash-alg is the hash algorithm specified by the “a=” tag,
  • canon_header and canon_body are the canonicalized message header and body (respectively) as defined in Section 3.4 (excluding the DKIM-Signature header field), and DKIM-SIG is the canonicalized DKIM-Signature header field sans the signature value itself, but with body-hash included as the “bh=” tag.

Tags (like a=) are explained here.

The public key, however, should be set in the TXT record.

Example:

1505000725.myproduct._domainkey.myproduct.com. IN TXT (
"v=DKIM1;t=s;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCywF+6HiUIwHRoteLxFoSYLyxT"
"WnKB/u9t8HB7kTwy6F5LYqeg6DZp8X6psgKxbrIdxw9Eyhs7xworO+126K+0Xb/r"
"ch7fDgaBSz4PsEW6IA/vDMIgQIKBLH+i/NlMVoPWcjwM1+Jl7fVezKjzjuNOCUFN"
"iD2vFpj29wYX9II/EQIDAQAB"
)

This could be checked using the dig command, but you should already know in advance your record:

dig TXT 1505000725.myproduct._domainkey.myproduct.com.

These are some technical details. What you should keep in mind is that authentication is important.

Let’s see how

Your customer is using an SMTP server to receive your email.

If you enabled DKIM, this server will detect the authentication in the header of the sent email and will ask the sending domain about its DNS, more specifically about the TXT record.
This allows the SMTP server to get your public key because it allows anyone actually to check if the email was sent from your domain or not.

Even when not exposing the private key, just using the signature with the public key, a system can tell if your private key was used to generate this signature or not.

This allows the receiving server to know also if message headers and content have not been altered during transit.

This is a typical check when sending regular campaigns STMP servers of companies like Google, Yahoo or any other email provider will automatically check the signature.

If the check fails or if the signature doesn’t exist, your email will be flagged and at a larger scale considered as a spam and you could get your IP blacklisted.

Not using DKIM increases the chance of landing in the spam folder.

Sender Policy Framework

When you send an email, you are using a FROM address which is in the last example: hello@myproduct.com

SPF is a standard to tell which servers have the right to use to send an email using the right part of the email (hello).

SPF helps on detecting email spoofing by detecting if the incoming mail from a server is authorized by the domain’s administrator or not.

Using SPF is first of all a protection for you before even thinking if your email will land in the spam folder or not.

If your domain administrator publishes the SPF records, a spammer is less likely to pretend to be from the same domain because email filters will check the SPF and know that it comes from a spammer, not you. Even spammers are less likely to use SPF-protected domains.

Let’s use google.com as an example. SPF is published using the TXT record:

dig google.com TXT; <<>> DiG 9.10.3-P4-Ubuntu <<>> google.com TXT
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28158
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.com. IN TXT
;; ANSWER SECTION:
google.com. 3514 IN TXT "v=spf1 include:_spf.google.com ~all"
;; Query time: 10 msec
;; SERVER: 127.0.1.1#53(127.0.1.1)
;; WHEN: Sun Sep 10 02:34:12 CEST 2017
;; MSG SIZE rcvd: 87

Includes: References the policy of another domain, that’s why I’ll check _spf.google.com domain policy:

dig _spf.google.com TXT; <<>> DiG 9.10.3-P4-Ubuntu <<>> _spf.google.com TXT
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39308
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_spf.google.com. IN TXT
;; ANSWER SECTION:
_spf.google.com. 300 IN TXT "v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all"
;; Query time: 38 msec
;; SERVER: 127.0.1.1#53(127.0.1.1)
;; WHEN: Sun Sep 10 02:35:44 CEST 2017
;; MSG SIZE rcvd: 160

I have 3 domains to check in this case:

dig _netblocks.google.com  TXT; <<>> DiG 9.10.3-P4-Ubuntu <<>> _netblocks.google.com TXT
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49054
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_netblocks.google.com. IN TXT
;; ANSWER SECTION:
_netblocks.google.com. 3432 IN TXT "v=spf1 ip4:64.18.0.0/20 ip4:64.233.160.0/19 ip4:66.102.0.0/20 ip4:66.249.80.0/20 ip4:72.14.192.0/18 ip4:74.125.0.0/16 ip4:108.177.8.0/21 ip4:173.194.0.0/16 ip4:207.126.144.0/20 ip4:209.85.128.0/17 ip4:216.58.192.0/19 ip4:216.239.32.0/19 ~all"
;; Query time: 15 msec
;; SERVER: 127.0.1.1#53(127.0.1.1)
;; WHEN: Sun Sep 10 02:36:49 CEST 2017
;; MSG SIZE rcvd: 304
eon01@eonSpider0x1 ~ $ dig _netblocks2.google.com TXT; <<>> DiG 9.10.3-P4-Ubuntu <<>> _netblocks2.google.com TXT
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4559
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_netblocks2.google.com. IN TXT
;; ANSWER SECTION:
_netblocks2.google.com. 3600 IN TXT "v=spf1 ip6:2001:4860:4000::/36 ip6:2404:6800:4000::/36 ip6:2607:f8b0:4000::/36 ip6:2800:3f0:4000::/36 ip6:2a00:1450:4000::/36 ip6:2c0f:fb50:4000::/36 ~all"
;; Query time: 16 msec
;; SERVER: 127.0.1.1#53(127.0.1.1)
;; WHEN: Sun Sep 10 02:36:56 CEST 2017
;; MSG SIZE rcvd: 218
eon01@eonSpider0x1 ~ $ dig _netblocks3.google.com TXT; <<>> DiG 9.10.3-P4-Ubuntu <<>> _netblocks3.google.com TXT
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19684
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_netblocks3.google.com. IN TXT
;; ANSWER SECTION:
_netblocks3.google.com. 3600 IN TXT "v=spf1 ip4:172.217.0.0/19 ip4:108.177.96.0/19 ~all"
;; Query time: 16 msec
;; SERVER: 127.0.1.1#53(127.0.1.1)
;; WHEN: Sun Sep 10 02:37:02 CEST 2017
;; MSG SIZE rcvd: 114

This is the list of the IP addresses that Google uses to send you an email:

ip4:64.18.0.0/20 
ip4:64.233.160.0/19
ip4:66.102.0.0/20
ip4:66.249.80.0/20
ip4:72.14.192.0/18
ip4:74.125.0.0/16
ip4:108.177.8.0/21
ip4:173.194.0.0/16
ip4:207.126.144.0/20
ip4:209.85.128.0/17
ip4:216.58.192.0/19
ip4:216.239.32.0/19
ip6:2001:4860:4000::/36
ip6:2404:6800:4000::/36
ip6:2607:f8b0:4000::/36
ip6:2800:3f0:4000::/36
ip6:2a00:1450:4000::/36
ip6:2c0f:fb50:4000::/36
ip4:172.217.0.0/19
ip4:108.177.96.0/19

Domain-based Message Authentication, Reporting & Conformance

Domain-based Message Authentication, Reporting & Conformance or simply DMARC is also and email authentication standard and reporting protocol.

It builds on SPF and DKIM protocols and it’s a kind of complement to these protocols.

DMARC sends the results of the authentication of mailings in the main operators (Gmail, Hotmail, AOL, etc.) to the sender and to the recipient to allow him to know how to handle messages that have not passed the authentication test. The manner to handle unauthenticated emails is a policy that should be configured by the domain administrator.

DMARC records are published in DNS with a subdomain label _dmarc, for example:

_dmarc.myproduct.com

This is a good example taken from Wikipedia:

"v=DMARC1;p=none;sp=quarantine;pct=100;rua=mailto:dmarcreports@example.com"

Here,

v is the version,

p is the policy,

sp the subdomain policy,

pct is the percent of "bad" emails on which to apply the policy,

rua is the URI to send aggregate reports to.

In this example, the entity controlling the example.com DNS domain intends to monitor SPF and/or DKIM failure rates, and doesn't expect emails to be sent from subdomains of example.com. Note that a subdomain can publish its own DMARC record; receivers must check it out before falling back to the organizational domain record.

dmarc is an additional security and insurance for your emailing campaigns

Connect Deeper

At eralabs, we help companies in securing and setting up cloud-based emailing servers and solutions, that’s why I wanted through this article to highlight some of the best practices and share some technical tips about what we do.

If you liked this post, please recommend it and share it with your followers.

--

--