Email Authentication Guide

Setting up SPF, DKIM, and DMARC that actually works

Published: January 2025 • 15 min read

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:

  1. Your mail server signs outgoing emails with a private key
  2. The signature and selector information is added to email headers
  3. Receiving servers look up your public key in DNS
  4. 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:

  1. Start with SPF - it's the easiest to get right
  2. Get DKIM working on a test domain first
  3. Use monitoring-only DMARC until you're confident
  4. Check your logs religiously - they tell you everything
  5. 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.