Email Authentication Guide
Setting up SPF, DKIM, and DMARC that actually works
The Email Authentication Problem
If you've ever spent hours fighting with email servers, getting DKIM signatures to work, or wondering why your perfectly legitimate emails end up in spam folders, you're not alone. Email authentication is one of those things that should be straightforward but turns into an absolute nightmare when you actually try to implement it properly.
This guide covers the complete process of setting up SPF, DKIM, and DMARC authentication, with a focus on the real-world problems you'll encounter - particularly with DKIM signing in Exim4 environments using SMTP relays.
What You'll Learn
- How SPF, DKIM, and DMARC actually work together
- Setting up DKIM signing with Exim4 (the painful way and the right way)
- Configuring authentication with SMTP relays
- Troubleshooting the most common configuration problems
- DNS record configuration that actually works
SPF Records: The Foundation
SPF (Sender Policy Framework) is the simplest of the three authentication methods. It tells receiving mail servers which IP addresses are allowed to send email for your domain.
Basic SPF Setup
Create a TXT record for your domain:
v=spf1 ip4:192.0.2.1 include:_spf.google.com ~all
This example allows a specific IPv4 address and Google's mail servers to send email for your domain. The ~all
means "soft fail" - suspicious but not rejected.
SPF Gotchas
- DNS lookup limits: SPF has a 10 DNS lookup limit. Too many includes will break it.
- Multiple SPF records: You can only have one SPF record per domain. Multiple records will cause failures.
- IPv6 support: If you use IPv6, you'll need to add
ip6:2001:db8::1
or a similar entry for your sending server.
DKIM: The Nightmare
DKIM (DomainKeys Identified Mail) is where things get properly complicated. It involves cryptographic signatures, DNS records, and mail server configuration that has to work perfectly together.
The DKIM Process
DKIM works by:
- Your mail server signs outgoing emails with a private key
- The signature and selector information is added to email headers
- Receiving servers look up your public key in DNS
- They verify the signature matches the email content
DKIM with Exim4: The 8-Hour Nightmare
Here's where it gets interesting. If you're using Exim4 with an SMTP relay, there are several places where DKIM configuration can go wrong:
Problem 1: Wrong Transport Configuration
The most common issue is configuring DKIM on the wrong transport. Check your logs to see which transport is being used:
grep "T=your_transport" /var/log/exim4/mainlog
Problem 2: Tainted Filename Errors
Modern Exim versions won't read files when the path contains user-supplied data (like domain names from email addresses). You'll see errors like:
Tainted filename '/etc/exim4/domains/yourdomain.com/dkim.pem'
unable to open file for reading
Solution: Use a fixed path or proper validation in your DKIM configuration.
Problem 3: Mismatched Public/Private Keys
This one's a killer. Your private key generates one public key, but your DNS record contains a completely different one. Verify they match:
# Extract public key from private key
openssl rsa -in /etc/exim4/domains/yourdomain.com/dkim.pem -pubout -outform DER | openssl base64 -A
# Check DNS record
dig +short TXT mail._domainkey.yourdomain.com
Proper DKIM Configuration for Exim4
Here's a working DKIM setup for Exim4 with SMTP relay:
1. Generate DKIM Keys
mkdir -p /etc/exim4/domains/yourdomain.com
openssl genrsa -out /etc/exim4/domains/yourdomain.com/dkim.pem 2048
chown Debian-exim:Debian-exim /etc/exim4/domains/yourdomain.com/dkim.pem
chmod 640 /etc/exim4/domains/yourdomain.com/dkim.pem
2. Configure Exim4 Macros
In /etc/exim4/exim4.conf.template
(for non-split config):
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
DKIM_SELECTOR = mail
DKIM_PRIVATE_KEY = /etc/exim4/domains/${dkim_domain}/dkim.pem
DKIM_CANON = relaxed/simple
DKIM_STRICT = 0
3. Configure the Correct Transport
Make sure DKIM is configured on the transport that's actually being used:
smtp_relay_smtp:
driver = smtp
hosts_require_auth = $host_address
hosts_require_tls = $host_address
dkim_domain = DKIM_DOMAIN
dkim_selector = DKIM_SELECTOR
dkim_private_key = DKIM_PRIVATE_KEY
dkim_canon = DKIM_CANON
dkim_strict = DKIM_STRICT
4. DNS Configuration
Extract your public key and create the DNS record:
openssl rsa -in /etc/exim4/domains/yourdomain.com/dkim.pem -pubout -outform DER | openssl base64 -A
Create a TXT record for mail._domainkey.yourdomain.com
:
v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY_HERE
DMARC: Tying It All Together
DMARC (Domain-based Message Authentication, Reporting and Conformance) uses SPF and DKIM results to make policy decisions about email delivery.
Basic DMARC Policy
Start with a monitoring-only policy:
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; ruf=mailto:dmarc@yourdomain.com
Once you're confident everything is working, you can enforce stricter policies:
v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com
Testing and Troubleshooting
Verification Tools
- MXToolbox: Test SPF, DKIM, and DMARC records
- Gmail Show Original: Check authentication results in received emails
- Mail-tester.com: Send test emails and get detailed reports
Common Issues and Solutions
DKIM Signature Present but Failing
- Check public/private key match
- Verify DNS record syntax
- Check for DNS propagation delays
- Ensure correct selector in both config and DNS
No DKIM Signature at All
- Check which transport is actually being used
- Verify DKIM configuration is on the correct transport
- Check file permissions on private key
- Look for "tainted filename" errors in logs
SPF Hard Fail
- Verify all sending IPs are included
- Check for DNS lookup limit exceeded
- Ensure only one SPF record exists
The Bottom Line
Email authentication isn't rocket science, but it is finicky. The key is methodical troubleshooting:
- Start with SPF - it's the easiest to get right
- Get DKIM working on a test domain first
- Use monitoring-only DMARC until you're confident
- Check your logs religiously - they tell you everything
- Test with real emails, not just online tools
When it finally works, you'll see beautiful results like:
Authentication-Results: gmail.com;
spf=pass smtp.mailfrom=yourdomain.com;
dkim=pass header.d=yourdomain.com;
dmarc=pass header.from=yourdomain.com
And your emails will actually end up in inboxes instead of spam folders.
Need help with email authentication or other server configuration challenges? Get in touch - we've been through this pain so you don't have to.