Sending Emails with Custom Domains (SPF/DKIM/DMARC)
In this post I will go through some concepts and/or actions you should know about when you have to send emails from custom domains like [email protected]
. This is a common requirement when you want to send emails to your users for different kinds of notifications (welcome mails, payment mails, marketing mails, etc.).
I will not go through the concepts in detail but instead link to relevant guides which already does the job really well. So consider this article to be more of a reference to what you must keep in mind when sending emails to your users from custom domains. Interestingly most of the actions you have to take to do this, is around setting up DNS records.
Reverse DNS Zones
A DNS A
record points domain.com
to an IPv4 address like 35.63.132.32
(both are just examples). Generally the DNS records you create in your domain provider’s console/admin ends up in a Forward DNS Zone.
A Reverse DNS Zone on the other hand contains PTR
records that let you lookup the domain against the IP (reverse of forward zones). With this you can point an IP like 35.63.132.32
to a domain like domain.com
. To do this, you setup a PTR record if your ISP/cloud provider allows that (preferably) in a reverse zone. You can’t just go and add a PTR record in your domain provider’s console/admin for your domain.com
(forward) zone.
To point 35.63.132.32
to domain.com
we would need to create a PTR record for 32.132.63.35.in-addr.arpa
with domain.com
as its value. Notice how the octets of the IP address are reversed. We can also setup an entire Reverse DNS zone (if our ISP/cloud provider allows) for say 132.63.35.in-addr.arpa
(representing 35.63.132.0/24
) and then add a bunch of PTR
records under that pointing one or more IPs to multiple domains.
Then if you hit dig PTR 32.132.63.35.in-addr.arpa
or dig -x 35.63.132.32
or host 35.63.132.32
, you will get domain.com
as the answer.
Now why did we talk about reverse DNS lookups? Because some mail providers (like Gmail) might require the sender IP of an email to be resolvable to a domain and also the domain to point to the same IP. This can be achieved with PTR
and A
records.
From one of Gmail’s support page:
Your sending IP address must have a PTR record. PTR records verify that the sending hostname is associated with the sending IP address. Every IP address must map to a hostname in the PTR record. The hostname specified in the PTR record must have a forward DNS that refers to the sending IP address.
Note: Try dig +trace domain.com
and dig +trace <your-ip>.in-addr.arpa
to understand the entire namespace tree for these domains.
Now if you are using third party mail services like Mailgun, Sendgrid, Postmark, Amazon SES, etc. then you do not need to worry about supporing reverse DNS lookups.
Sender Policy Framework (SPF)
SPF is an open standard that details out a method to prevent sender address forgery or spoofing. So for instance, if [email protected]
wanted to send you an email from [email protected]
, he couldn’t do so if yourbank.com
implemented SPF. In fact email service providers like Gmail would completely reject incoming mails that do not pass either SPF or DKIM (discussed below) checks.
Before understanding SPF, it is important to understand that when sending an email the concept of sender email is different from the address used in From
header of the message. Conceptually, SMTP has an envelope that contains details like the sender email (SMTP MAIL FROM
command), recipient email (SMTP RCPT TO
command), etc. to be used by the recipient’s mail server and the actual message that contains the message header and body for usage by the recipient’s mail client. The message header is where the From
email is present that is shown in the recipient’s mail client. Read this SO thread for detailed explanation.
This is why I can send an email from [email protected]
(using a self-hosted mail server or a third party tool like Amazon SES or Mailgun) which is the SMPT MAIL FROM
email (or the sender email) but put [email protected]
in the message’s From
header and [email protected]
in the To
header that in Bar’s email client (say Gmail) would make it seem like it came from [email protected]
and not [email protected]
. Although thankfully good clients like Gmail would show extra information like Mailed-By: codingshower.com
or From [email protected] via codingshower.com
.
Similarly the address to which the email is actually delivered can be different from what is put inside To
header of the message.
Now the envelope sender email is actually added to the email header as a Return-Path
header by the recipient’s mail server, for example yourbank.com
might send you an email from [email protected]
which would lead to the following header getting added by the recipient mail server – Return-Path: [email protected]
.
Now the problem is a malicious person called foo
could send you a spoofed email from [email protected]
. But if yourbank.com
added an SPF TXT
DNS record specifying a whitelist of IPs or domains who were allowed to send emails on their behalf, any legit email client or email service provider like Gmail would either reject the email or mark as spam. An SPF TXT
record looks something like this:
v=spf1 ip4=192.0.2.0 -all
This means that the recipient’s email server will first lookup the TXT record that starts with v=spf1
for the domain in Return-Path
header and check if the sending mail server’s IP is whitelisted in that DNS record. If not the SPF check will fail and the mail will get rejected or moved to spam box.
It is important to note that SPF validation works against the domain in Return-Path
not the From
header in the SMTP message which is what the email client shows as the from
sender when you open an email (in Gmail for instance). This means that with SPF although [email protected]
cannot send you an email whose SMTP sender/Return-Path/envelope sender is [email protected]
but he can still send you an email where the SMTP sender is [email protected]
but the From
header contains [email protected]
tricking your email client and you into thinking that the email was sent from yourbank.com
.
Some clients like Gmail would show such emails as from [email protected] sent via [email protected]
. But the email could still end up in the user’s inbox if it passed SPF and DKIM checks. This spoofing can be prevented by DMARC (covered below).
For in-depth guides on SPF, follow these links:
- What is a DNS SPF record? – Cloudflare
- SPF Guide – Postmark
- Help prevent spoofing and spam with SPF – Gmail
- SPF Record Syntax
- SPF RFC
DomainKeys Identified Mail (DKIM)
DKIM is a method to validate the authenticity of email messages to ensure it has not been tampered with/altered while in transit. It uses the commonly known public/private cryptographic keys to sign the emails on the sender’s mail server and verify on the recipient’s side.
The following guides explains DKIM in detail:
Basically the sender signs the message body along with certain headers with its private key and adds the signature to the DKIM-Signature
header and then the recipient takes the same contents and the signature to verify them using the public key. The public key is available in the sending domain’s DNS TXT
record. The domain to be looked up for this record is available in the d=
tag present in DKIM-Signature
. To understand different tags, try the RFC or this article.
Here is an exampled DKIM-Signature:
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=224i45dv7c2xz3womuasteono;
d=amazonses.com; t=1694240102;
h=From:To:Subject:MIME-Version:Content-Type:Message-ID:Date:Feedback-ID;
bh=scJIe/RS+AXEXnQO3ZK8HTlulMyk+3ibnHhjlk=;
b=ji1NAFx/H60Eizjm6QQBJWYnRnZAX/ZESw9VDdrXj77pnSoJPL+eew0B8 SQoz6QHjBapbkUdzEzDTc
The public key will be available in a TXT
record at <s._domainkey.d>
, which in the above example would be at dig TXT 224i45dv7c2xz3womuasteono._domainkey.amazonses.com
.
Now if DKIM check is passed on the recipient’s mail server, the authenticity of the email is ensured but [email protected]
can still send a valid email with From: [email protected]
header, i.e., spoofed mails. This is fixed using DMARC.
Domain-based Message Authentication, Reporting & Conformance (DMARC)
SPF takes care of spoofing of SMTP sender emails, i.e., an IP can send emails on behalf of another mail server/domain only if it is authorised by them via TXT
record. So SPF protects your domain from being used as the envelope sender/Return-Path
by random people.
DKIM signs mails protecting them from getting tampered in transit but that signed message could just be sent from a random/malicious email to an innocent user with a spoofed From
email header that shows up as the sender in most email clients/providers.
Both SPF and DKIM are powerless against spoofed From
header addresses. This is where DMARC “alignment” comes into picture. DMARC is a DNS record that yourbank.com
will have to set so that whenever an email provider/recipient mail server gets an email with From
header address whose domain is yourbank.com
, it will first require either SPF or DKIM to pass and after that “align” with the domain as well.
For SPF DMARC alignment means that the domain in Return-Path
must be the same as the one in From
header. If they are different then the email will be rejected or marked as spam. For DKIM DMARC alignment, the d=
tag in DKIM-Signature
must match with the From
domain.
Matching of the domains (alignment) can be relaxed (subdomains pass) or strict (subdomains do not pass), i.e., in (default) relaxed mode foo.example.com
and bar.example.com
align but example.com
and anotherexample.com
don’t. In strict mode the latter is true but foo.example.com
and bar.example.com
also do not pass the alignment test.
DMARC also has the concept of reports that the recipient’s mail server sends you from time to time regarding how emails with From
header of your domain is being delivered by them (rejected, marked as spam, etc.). The Gmail guide (linked below) has a detailed walkthrough of this.
Here is an example DMARC TXT
record (always added to _dmarc.[domain]
like _dmarc.google.com
):
v=DMARC1; p=reject; adkim=s; aspf=s;
This record says reject an email if it fails strict alignment with both DKIM and SPF. Do note the way DMARC is designed, either SPF or DKIM has to pass and be aligned (not both) for the email to pass DMARC and be delivered (not rejected or spammed).
For in-depth understanding of DMARC:
- What is a DNS DMARC record? – Cloudflare
- DMARC: What is it and why do you need it? – Postmark
- Help prevent spoofing and spam with DMARC – Gmail
- DMARC Syntax
Useful Resources
Following is a list of some other external links that might be useful FAQ, relevant concepts, guides, etc. around the same topic:
- Why there are two DKIM signatures in email – StackOverflow
- Prevent mail to Gmail users from being blocked or sent to spam
- What is ARC, or Authenticated Received Chain? – Postmark
A note on third party email services like Mailgun, Sendgrid, Postmark, Amazon SES, etc.:
- When using these services, you don’t have to worry about setting up reverse DNS records (
PTR
). - When using these services, they will give you SPF and DKIM records that you should add in your domain as
TXT
records. This not only helps prevent sender email spoofing and email tampering but also ensures your emails with custom domain ([email protected]
) do not get rejected or marked as spam by email service providers nor does it show up asfrom [email protected] sent via mailgun.net
. - When using these services, it is still recommended to setup DMARC on your domain so that random people are unable to spoof the
From
email address with emails of your domain.