The recipe is simple.
Publish strict sender policies, sign your mail, enforce alignment, and monitor. Below are copy paste DNS records and commands that work across most registrars and DNS hosts.
If you aren’t well-versed in making DNS changes, then don’t follow the steps below. Have you developer do it, or hire us.
Start with a single SPF record at the zone root. Keep it under 10 DNS lookups. List only systems that send on your behalf. End with a hard fail.
Type: TXT
Name: @
Value: v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.25 ip6:2001:db8:abcd::25 -all
TTL: 3600
If you use subdomains for sending, publish SPF there too. Example for news.example.com:
Type: TXT
Name: news
Value: v=spf1 include:mailgun.org -all
Remove old vendors. Replace ~all
with -all
once you are confident in coverage.
Generate and publish a DKIM public key per platform. The selector is chosen by the sender. Below is a 2048 bit placeholder. Replace with your real key material.
Type: TXT
Name: google._domainkey
Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...REPLACE_WITH_REAL_KEY...
TTL: 3600
If you send from a subdomain, publish there as well. Example for s1._domainkey.news.example.com.
Start with monitoring. After two weeks of clean reports, switch to quarantine or reject. Alignment should be strict so that only your exact domain or subdomain passes.
Type: TXT
Name: _dmarc
Value: v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1; adkim=s; aspf=s; pct=100
TTL: 3600
Then enforce:
Type: TXT
Name: _dmarc
Value: v=DMARC1; p=reject; rua=mailto:[email protected]; adkim=s; aspf=s; pct=100
MTA-STS forces TLS for inbound email and thwarts downgrade attacks. Publish both a DNS record and an HTTPS policy file at https://mta-sts.example.com/.well-known/mta-sts.txt
.
Type: TXT
Name: _mta-sts
Value: v=STSv1; id=20250827
Type: CNAME
Name: mta-sts
Value: host.example.com
Example policy file content:
version: STSv1
mode: enforce
mx: mx1.example.com
mx: mx2.example.com
max_age: 604800
Enable TLS reporting so senders can tell you when delivery is not secure.
Type: TXT
Name: _smtp._tls
Value: v=TLSRPTv1; rua=mailto:[email protected]
CAA prevents unauthorized TLS certificates for your domain and mail hostnames. Include a contact method for incident reports.
Type: CAA Name: @ Value: 0 issue "letsencrypt.org"
Type: CAA Name: @ Value: 0 iodef "mailto:[email protected]"
Type: CAA Name: mail Value: 0 issue "letsencrypt.org"
Turn on DNSSEC at your registrar and publish DS records. This protects your TXT records from tampering. After enablement, verify with dig.
$ dig +dnssec example.com TXT @1.1.1.1 | grep ad
Use only your real MX hosts. Remove wildcard MX. Remove MX from parked domains that do not send or receive mail. For domains that never send mail, publish a Null MX and a restrictive SPF.
Type: MX Name: @ Value: 0 .
Type: TXT Name: @ Value: v=spf1 -all
Type: TXT Name: _dmarc Value: v=DMARC1; p=reject; adkim=s; aspf=s
ARC helps preserve authentication across forwarders. BIMI displays your logo in supporting inboxes once DMARC is at quarantine or reject and you host an SVG logo.
Type: TXT
Name: default._bimi
Value: v=BIMI1; l=https://mail.example.com/bimi/logo.svg; a=https://mail.example.com/bimi/vmc.pem
Create a dedicated subdomain per vendor. Align SPF and DKIM on that subdomain. Do not give vendors wildcard access to your apex.
Sender: SendGrid on news.example.com
Type: CNAME Name: s1._domainkey.news Value: s1.domainkey.u123456.wl.sendgrid.net
Type: CNAME Name: s2._domainkey.news Value: s2.domainkey.u123456.wl.sendgrid.net
Type: TXT Name: news Value: v=spf1 include:sendgrid.net -all
Type: TXT Name: _dmarc.news Value: v=DMARC1; p=reject; adkim=s; aspf=s; rua=mailto:[email protected]
# SPF
$ dig TXT example.com +short | grep spf
# DKIM (replace selector)
$ dig TXT google._domainkey.example.com +short
# DMARC
$ dig TXT _dmarc.example.com +short
# MTA-STS TXT and policy
$ dig TXT _mta-sts.example.com +short
$ curl -s https://mta-sts.example.com/.well-known/mta-sts.txt
# TLS-RPT
$ dig TXT _smtp._tls.example.com +short
# MX and STARTTLS check
$ dig MX example.com +short
$ openssl s_client -starttls smtp -crlf -connect mx1.example.com:25
$TTL 3600
@ IN SOA ns1.example.com. hostmaster.example.com. (
2025082701 3600 900 1209600 300 )
IN NS ns1.example.com.
IN NS ns2.example.com.
@ IN MX 10 mx1.example.com.
@ IN MX 20 mx2.example.com.
@ IN TXT "v=spf1 include:_spf.google.com -all"
_dmarc IN TXT "v=DMARC1; p=reject; adkim=s; aspf=s; rua=mailto:[email protected]"
_mta-sts IN TXT "v=STSv1; id=20250827"
_smtp._tls IN TXT "v=TLSRPTv1; rua=mailto:[email protected]"
google._domainkey IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFA..."
@ IN CAA 0 issue "letsencrypt.org"
@ IN CAA 0 iodef "mailto:[email protected]"
Do this once with care and your domain becomes very hard to abuse.