SPF and DMARC Configuration: Complete Email Authentication Guide

Introduction

Email authentication has become essential for modern mail servers. While DKIM provides cryptographic signing, two other critical protocols complete the authentication trinity: SPF (Sender Policy Framework) and DMARC (Domain-based Message Authentication, Reporting, and Conformance).

SPF allows domain owners to specify which mail servers are authorized to send email on behalf of their domain. When a receiving server gets an email claiming to be from your domain, it checks your SPF record to verify the sending server is authorized. This simple but powerful mechanism prevents spammers from spoofing your domain.

DMARC builds on both SPF and DKIM by adding policy enforcement and reporting capabilities. It tells receiving mail servers what to do when SPF or DKIM checks fail, and provides detailed reports about who is sending email using your domain. This visibility is crucial for identifying legitimate mail flow and detecting abuse.

Together, SPF, DKIM, and DMARC provide comprehensive email authentication that:

  • Dramatically improves email deliverability
  • Protects your domain from spoofing and phishing
  • Provides visibility into your email ecosystem
  • Meets requirements of major email providers
  • Builds and maintains sender reputation

This comprehensive guide walks you through configuring SPF and DMARC for your domain, implementing best practices, monitoring authentication results, and troubleshooting common issues.

Prerequisites

Before configuring SPF and DMARC, ensure you have:

Domain Requirements

  • A registered domain name (e.g., example.com)
  • Access to your domain's DNS management panel
  • Understanding of your current email infrastructure
  • Knowledge of all legitimate mail sources for your domain

Email Server Requirements

  • Working mail server sending email
  • DKIM configured and operational (strongly recommended)
  • List of all IPs and services that send email for your domain
  • Access to mail server logs

Knowledge Prerequisites

  • DNS record management experience
  • Basic understanding of email headers
  • Familiarity with SPF, DKIM, DMARC concepts
  • Ability to read and interpret authentication results

Understanding SPF

What is SPF?

Sender Policy Framework (SPF) is an email validation system that detects and prevents email spoofing. It works by allowing domain owners to publish a list of authorized mail servers in DNS.

How SPF Works

  1. Publication: You publish an SPF record in your DNS as a TXT record
  2. Email Sent: Someone sends email claiming to be from your domain
  3. SPF Check: Receiving server queries DNS for your SPF record
  4. IP Comparison: Receiving server compares sender's IP against authorized IPs
  5. Result: SPF passes, fails, or returns neutral/softfail
  6. Action: Receiving server acts based on SPF result

SPF Results

  • Pass: Sender IP is authorized
  • Fail: Sender IP is not authorized (hard fail)
  • SoftFail (~all): IP not authorized but don't reject
  • Neutral: No policy statement
  • None: No SPF record found
  • TempError: Temporary DNS problem
  • PermError: SPF record has errors

Understanding DMARC

What is DMARC?

DMARC (Domain-based Message Authentication, Reporting, and Conformance) is an email authentication protocol that uses SPF and DKIM results to determine message authenticity and provides policy enforcement and reporting.

How DMARC Works

  1. Policy Publication: You publish a DMARC policy in DNS
  2. Authentication Check: Receiving server checks SPF and DKIM
  3. Alignment Check: Verifies domain alignment
  4. Policy Application: Applies your policy (none/quarantine/reject)
  5. Reporting: Sends aggregate and forensic reports to you

DMARC Policies

  • none: Monitor only, don't reject (recommended for initial deployment)
  • quarantine: Move failing messages to spam/junk folder
  • reject: Reject failing messages entirely

DMARC Alignment

DMARC requires either SPF or DKIM to pass AND align:

  • SPF Alignment: Return-Path domain matches From domain
  • DKIM Alignment: DKIM signature domain matches From domain
  • Relaxed Alignment: Subdomains allowed (default)
  • Strict Alignment: Exact domain match required

Step 1: Analyze Your Email Infrastructure

Before creating SPF records, identify all legitimate email sources:

Identify Mail Servers

# Check your mail server's IP
dig mail.example.com A +short

# Check MX records
dig example.com MX +short

# Check reverse DNS
dig -x YOUR_IP +short

Common Email Sources to Consider

  1. Your mail server: Primary SMTP server
  2. Backup MX servers: Secondary mail servers
  3. Web servers: Applications sending email
  4. Third-party services:
    • Mailchimp, SendGrid, Amazon SES
    • Google Workspace, Microsoft 365
    • CRM systems, monitoring tools
    • Help desk software
  5. Other infrastructure: Any server running mail-enabled applications

Document Email Sources

Create a list:

Primary mail server: 203.0.113.10 (mail.example.com)
Web server: 203.0.113.20 (www.example.com)
SendGrid: include:sendgrid.net
Google Workspace: include:_spf.google.com

Step 2: Create SPF Record

Basic SPF Syntax

SPF records are published as DNS TXT records with this format:

v=spf1 [mechanisms] [qualifier]all

SPF Mechanisms

  • ip4: Authorize IPv4 address or range
  • ip6: Authorize IPv6 address or range
  • a: Authorize A record of domain
  • mx: Authorize MX records of domain
  • include: Include another domain's SPF record
  • exists: Advanced DNS-based authorization
  • all: Catch-all for everything else

SPF Qualifiers

  • + (Pass): Authorized (default if not specified)
  • - (Fail): Not authorized, hard fail
  • ~ (SoftFail): Not authorized but don't reject
  • ? (Neutral): No policy assertion

Common SPF Examples

Simple mail server:

v=spf1 mx a ip4:203.0.113.10 ~all

With third-party services:

v=spf1 mx a ip4:203.0.113.10 include:_spf.google.com include:sendgrid.net ~all

Multiple IPs:

v=spf1 ip4:203.0.113.10 ip4:203.0.113.20 ip4:203.0.113.30 ~all

IP range:

v=spf1 ip4:203.0.113.0/24 ~all

Strict (reject unauthorized):

v=spf1 mx a ip4:203.0.113.10 -all

SPF Best Practices

  1. Start with ~all: Use soft fail initially, move to -all after testing
  2. Be specific: Only include necessary mechanisms
  3. Avoid too many includes: Maximum 10 DNS lookups allowed
  4. Use IP ranges carefully: Only include IPs you control
  5. Keep it simple: Complex SPF records are harder to maintain

Example SPF for Common Scenarios

Scenario 1: Self-hosted mail server only

v=spf1 mx a ip4:203.0.113.10 ~all

Scenario 2: Mail server + Google Workspace

v=spf1 ip4:203.0.113.10 include:_spf.google.com ~all

Scenario 3: Multiple services

v=spf1 ip4:203.0.113.10 include:_spf.google.com include:servers.mcsv.net include:sendgrid.net ~all

Scenario 4: No mail server (third-party only)

v=spf1 include:_spf.google.com -all

Scenario 5: Mail server + backup MX + SendGrid

v=spf1 mx a ip4:203.0.113.10 ip4:203.0.113.11 include:sendgrid.net ~all

Step 3: Publish SPF Record

Add DNS TXT Record

In your DNS management panel, create a TXT record:

Name/Host: @ (or leave blank for root domain) Type: TXT Value: Your SPF record

Example:

Name: @
Type: TXT
Value: v=spf1 mx a ip4:203.0.113.10 include:_spf.google.com ~all
TTL: 3600

Important Notes

  • Each domain needs its own SPF record
  • Only ONE SPF record per domain (multiple TXT records are OK, but only one can be SPF)
  • Subdomains can have separate SPF records
  • If subdomain has no SPF record, parent domain's record is not used

Verify SPF Publication

# Check SPF record
dig example.com TXT +short | grep spf

# Alternative
host -t TXT example.com | grep spf

# Query specific nameserver
dig @8.8.8.8 example.com TXT +short | grep spf

Expected output:

"v=spf1 mx a ip4:203.0.113.10 ~all"

Step 4: Test SPF Configuration

Online Testing Tools

MXToolbox SPF Check:

https://mxtoolbox.com/spf.aspx

SPF Query Tool:

https://www.kitterman.com/spf/validate.html

DMARC Analyzer SPF Checker:

https://www.dmarcanalyzer.com/spf/checker/

Command Line Testing

# Basic SPF test
dig example.com TXT +short

# Check if SPF is valid
host -t TXT example.com

Test Email Authentication

Send a test email and check headers:

echo "SPF test email" | mail -s "SPF Test" [email protected]

In Gmail:

  1. Open the email
  2. Click "Show original"
  3. Look for SPF results:
Received-SPF: pass (google.com: domain of [email protected] designates 203.0.113.10 as permitted sender)

Or in Authentication-Results:

Authentication-Results: mx.google.com;
    spf=pass (google.com: domain of [email protected] designates 203.0.113.10 as permitted sender)

Common SPF Test Results

Pass:

Received-SPF: pass

Your IP is authorized, SPF is working correctly.

SoftFail:

Received-SPF: softfail

Your IP not explicitly authorized, check SPF record.

Fail:

Received-SPF: fail

Your IP is not authorized, email may be rejected.

None:

Received-SPF: none

No SPF record found for your domain.

Step 5: Create DMARC Record

Basic DMARC Syntax

DMARC records are published as DNS TXT records at _dmarc.yourdomain.com:

v=DMARC1; p=policy; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1

DMARC Tags

Required:

  • v=DMARC1: Version identifier
  • p=: Policy for domain (none/quarantine/reject)

Recommended:

  • rua=: Aggregate report email address
  • ruf=: Forensic report email address
  • pct=: Percentage of emails to apply policy (default 100)
  • sp=: Policy for subdomains (default: same as p)

Optional:

  • adkim=: DKIM alignment mode (r=relaxed, s=strict)
  • aspf=: SPF alignment mode (r=relaxed, s=strict)
  • fo=: Forensic reporting options
  • rf=: Forensic report format
  • ri=: Aggregate report interval (seconds)

DMARC Policies Explained

p=none (Monitoring mode):

  • No action taken on failures
  • Reports sent for analysis
  • Recommended for initial deployment
  • Learn about your email ecosystem

p=quarantine (Quarantine mode):

  • Failing emails moved to spam/junk
  • Partial enforcement
  • Next step after monitoring
  • Still allows email delivery

p=reject (Reject mode):

  • Failing emails rejected at SMTP level
  • Full enforcement
  • Maximum protection
  • Risk of legitimate mail loss if misconfigured

DMARC Example Records

Level 1: Monitoring (Start here)

v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1; pct=100

Level 2: Partial Enforcement

v=DMARC1; p=quarantine; pct=10; rua=mailto:[email protected]; sp=none

Level 3: Quarantine

v=DMARC1; p=quarantine; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1

Level 4: Full Protection

v=DMARC1; p=reject; rua=mailto:[email protected]; sp=reject; aspf=s; adkim=s; fo=1

With subdomain policy:

v=DMARC1; p=reject; sp=quarantine; rua=mailto:[email protected]

DMARC Tag Details

pct (Percentage):

pct=25    # Apply policy to 25% of email
pct=50    # Apply policy to 50% of email
pct=100   # Apply policy to all email (default)

fo (Forensic Options):

fo=0    # Report if all mechanisms fail (default)
fo=1    # Report if any mechanism fails
fo=d    # Report if DKIM fails
fo=s    # Report if SPF fails

ri (Report Interval):

ri=86400    # Daily reports (default)
ri=3600     # Hourly reports

Step 6: Publish DMARC Record

Add DNS TXT Record

In your DNS management panel:

Name/Host: _dmarc or Name/Host: _dmarc.example.com.

Type: TXT Value: Your DMARC record

Example:

Name: _dmarc
Type: TXT
Value: v=DMARC1; p=none; rua=mailto:[email protected]; fo=1
TTL: 3600

Set Up Report Email Address

Create an email address to receive DMARC reports:

# Add to virtual mailboxes (Postfix)
echo "[email protected]    example.com/dmarc-reports/" | sudo tee -a /etc/postfix/virtual_mailboxes

# Add to Dovecot users
NEW_PASSWORD=$(doveadm pw -s SHA512-CRYPT -p 'ReportPassword')
echo "[email protected]:$NEW_PASSWORD" | sudo tee -a /etc/dovecot/users

# Rebuild maps
sudo postmap /etc/postfix/virtual_mailboxes
sudo systemctl reload postfix dovecot

Or use a third-party DMARC reporting service:

Verify DMARC Publication

# Check DMARC record
dig _dmarc.example.com TXT +short

# Alternative
host -t TXT _dmarc.example.com

# Query Google's DNS
dig @8.8.8.8 _dmarc.example.com TXT +short

Expected output:

"v=DMARC1; p=none; rua=mailto:[email protected]; fo=1"

Step 7: Test DMARC Configuration

Online Testing Tools

MXToolbox DMARC Check:

https://mxtoolbox.com/dmarc.aspx

DMARC Analyzer:

https://www.dmarcanalyzer.com/dmarc/dmarc-check/

EasyDMARC:

https://easydmarc.com/tools/dmarc-lookup

Send Test Email

echo "DMARC test email" | mail -s "DMARC Test" [email protected]

Check email headers for DMARC results:

Authentication-Results: mx.google.com;
    dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=example.com

Result meanings:

  • dmarc=pass: SPF or DKIM passed with alignment
  • dmarc=fail: Neither SPF nor DKIM passed with alignment
  • p=NONE: Your policy is monitoring only
  • p=QUARANTINE: Your policy requests quarantine
  • p=REJECT: Your policy requests rejection

Step 8: Configure for Subdomains

Option 1: Explicit Subdomain Records

Create separate SPF and DMARC for each subdomain:

# SPF for subdomain
subdomain.example.com.  TXT  "v=spf1 ip4:203.0.113.10 ~all"

# DMARC for subdomain
_dmarc.subdomain.example.com.  TXT  "v=DMARC1; p=quarantine; rua=mailto:[email protected]"

Option 2: Use Subdomain Policy

In main DMARC record:

v=DMARC1; p=reject; sp=quarantine; rua=mailto:[email protected]
  • p=reject: Policy for main domain
  • sp=quarantine: Policy for subdomains

Option 3: Block Unused Subdomains

If you don't send email from subdomains:

# SPF for subdomains
*.example.com.  TXT  "v=spf1 -all"

# DMARC for subdomains
_dmarc.*.example.com.  TXT  "v=DMARC1; p=reject"

This prevents attackers from sending email as [email protected].

Step 9: Monitor DMARC Reports

Aggregate Reports (RUA)

Sent daily by most email providers, contains:

  • Number of messages received
  • SPF results
  • DKIM results
  • DMARC pass/fail statistics
  • Source IPs

Format: XML file attached to email

Forensic Reports (RUF)

Sent when authentication fails, contains:

  • Full headers of failed message
  • SPF/DKIM/DMARC failure reasons
  • More detailed than aggregate reports

Format: RFC 5322 format (email message)

Reading DMARC Reports

Reports are XML, which is hard to read. Options:

1. Online parsers:

2. DMARC reporting services:

  • DMARC Analyzer
  • Postmark DMARC
  • dmarcian

3. Self-hosted:

Sample Report Analysis

<record>
  <row>
    <source_ip>203.0.113.10</source_ip>
    <count>100</count>
    <policy_evaluated>
      <disposition>none</disposition>
      <dkim>pass</dkim>
      <spf>pass</spf>
    </policy_evaluated>
  </row>
  <identifiers>
    <header_from>example.com</header_from>
  </identifiers>
  <auth_results>
    <dkim>
      <domain>example.com</domain>
      <result>pass</result>
    </dkim>
    <spf>
      <domain>example.com</domain>
      <result>pass</result>
    </spf>
  </auth_results>
</record>

This shows:

  • 100 emails from IP 203.0.113.10
  • Both SPF and DKIM passed
  • DMARC passed
  • No action taken (policy=none)

Step 10: Progressive DMARC Deployment

Don't jump straight to p=reject. Follow this timeline:

Phase 1: Monitoring (Week 1-4)

v=DMARC1; p=none; rua=mailto:[email protected]; fo=1

Actions:

  • Collect reports for 2-4 weeks
  • Identify all legitimate mail sources
  • Fix any SPF/DKIM issues
  • Document email ecosystem

Phase 2: Partial Quarantine (Week 5-8)

v=DMARC1; p=quarantine; pct=10; rua=mailto:[email protected]

Actions:

  • Apply quarantine to 10% of mail
  • Monitor for false positives
  • Gradually increase pct (10% → 25% → 50% → 100%)
  • Fix any discovered issues

Phase 3: Full Quarantine (Week 9-12)

v=DMARC1; p=quarantine; pct=100; rua=mailto:[email protected]

Actions:

  • Monitor for legitimate mail in quarantine
  • Ensure all sources properly authenticated
  • Collect data on remaining failures

Phase 4: Reject (Week 13+)

v=DMARC1; p=reject; rua=mailto:[email protected]; sp=reject

Actions:

  • Full protection enabled
  • Continue monitoring reports
  • Maintain SPF/DKIM configuration
  • Regular audits

Troubleshooting Common Issues

Issue 1: SPF Hard Fail

Symptoms: Legitimate email failing SPF

Check:

# Verify SPF record
dig example.com TXT +short | grep spf

# Test from your server
echo "Test" | mail -s "SPF Test" -r [email protected] [email protected]

# Check headers in received email

Solutions:

  • Add missing IPs to SPF record
  • Include third-party service SPF
  • Change -all to ~all for testing
  • Verify IP in SPF matches sending server

Issue 2: Too Many DNS Lookups

Symptoms: SPF returns PermError

Cause: SPF limit is 10 DNS lookups

Check:

# Count includes in your SPF
dig example.com TXT +short | grep -o "include:" | wc -l

Solutions:

  • Replace includes with ip4/ip6 where possible
  • Consolidate multiple includes
  • Use IP ranges instead of individual IPs
  • Remove unnecessary includes

Example fix:

# Before (11 lookups - too many)
v=spf1 include:_spf.google.com include:sendgrid.net include:servers.mcsv.net include:spf.protection.outlook.com mx a ~all

# After (fewer lookups)
v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.10 ~all

Issue 3: DMARC Alignment Failure

Symptoms: SPF/DKIM pass but DMARC fails

Cause: Domain mismatch between From header and SPF/DKIM domains

Check email headers:

From: [email protected]
Return-Path: <[email protected]>
DKIM-Signature: d=mail.example.com

Solutions:

For SPF alignment: Ensure Return-Path domain matches From domain:

# In Postfix main.cf
smtp_helo_name = example.com

For DKIM alignment: Ensure DKIM signature domain matches From domain:

# In OpenDKIM signing.table
*@example.com default._domainkey.example.com

Use relaxed alignment:

v=DMARC1; p=none; aspf=r; adkim=r; rua=mailto:[email protected]

Issue 4: No DMARC Reports Received

Symptoms: Not receiving any reports

Check:

# Verify DMARC record
dig _dmarc.example.com TXT +short

# Test email address works
echo "Test" | mail -s "Test" [email protected]

Reasons:

  • Email address doesn't exist or unreachable
  • Not enough email volume (reports sent daily if volume exists)
  • DNS record incorrect
  • Receiving provider doesn't send reports (not all do)

Solutions:

  • Verify email address receives mail
  • Wait 24-48 hours for first reports
  • Send more test emails to major providers
  • Use third-party reporting service

Issue 5: Legitimate Mail Quarantined/Rejected

Symptoms: Valid email not delivered with p=quarantine or p=reject

Diagnosis:

  1. Check DMARC reports for failing sources
  2. Verify SPF record includes all sources
  3. Confirm DKIM signing all mail
  4. Check domain alignment

Solutions:

  • Add missing IPs to SPF
  • Configure DKIM for all mail sources
  • Fix Return-Path domain
  • Temporarily reduce policy: p=none or p=quarantine with pct=10

Best Practices

1. Start Conservative

  • Begin with p=none
  • Use ~all for SPF initially
  • Monitor reports thoroughly
  • Gradually increase enforcement

2. Maintain Complete Records

Document all email sources:

Mail server: 203.0.113.10 (mail.example.com)
Web server: 203.0.113.20 (www.example.com)
SendGrid: include:sendgrid.net
Monitoring: 203.0.113.30 (monitor.example.com)

3. Regular Audits

Monthly tasks:

# Check SPF
dig example.com TXT +short | grep spf

# Check DMARC
dig _dmarc.example.com TXT +short

# Review reports
# Check for new sources or failures

4. Protect Subdomains

Even unused subdomains:

*.example.com.  TXT  "v=spf1 -all"
_dmarc.*.example.com.  TXT  "v=DMARC1; p=reject"

5. Monitor Continuously

  • Review DMARC reports weekly
  • Set up alerts for authentication failures
  • Track pass/fail rates over time
  • Investigate any sudden changes

6. Coordinate with Teams

  • Inform marketing team before enforcement
  • Document all third-party email services
  • Test before deploying new services
  • Maintain update procedures

Advanced Configuration

Multiple Report Addresses

rua=mailto:[email protected],mailto:[email protected],mailto:[email protected]

External Report Addresses

To send reports to external domains, the external domain must authorize it:

At example.com:

v=DMARC1; p=none; rua=mailto:[email protected]

At external.com:

example.com._report._dmarc.external.com.  TXT  "v=DMARC1"

Percentage-Based Policy

v=DMARC1; p=reject; pct=25; rua=mailto:[email protected]

Applies reject policy to 25% of failing mail, allowing gradual rollout.

Strict Alignment

v=DMARC1; p=reject; aspf=s; adkim=s; rua=mailto:[email protected]

Requires exact domain match (not subdomains) for SPF and DKIM.

Monitoring Script

Create automated monitoring:

sudo nano /usr/local/bin/check-spf-dmarc.sh

Add:

#!/bin/bash

DOMAIN="example.com"

echo "=== SPF and DMARC Check ==="
echo ""

echo "SPF Record:"
dig $DOMAIN TXT +short | grep spf

echo ""
echo "DMARC Record:"
dig _dmarc.$DOMAIN TXT +short

echo ""
echo "SPF Test:"
host -t TXT $DOMAIN | grep spf

echo ""
echo "DMARC Reports (last 7 days):"
find ~/Maildir/cur -type f -name "*" -mtime -7 | xargs grep -l "dmarc-reports" | wc -l

Make executable:

sudo chmod +x /usr/local/bin/check-spf-dmarc.sh

Conclusion

You now have complete SPF and DMARC configuration, providing comprehensive email authentication alongside DKIM. Your domain is protected from spoofing, and your email deliverability is significantly improved.

Key Accomplishments

  1. SPF Configured: Authorized mail servers published in DNS
  2. DMARC Implemented: Policy and reporting active
  3. Progressive Deployment: Safe rollout strategy in place
  4. Monitoring Active: Reports being received and analyzed
  5. Best Practices: Following industry standards

Complete Authentication Stack

With SPF, DKIM, and DMARC all configured:

  • SPF: Validates sending server IP
  • DKIM: Cryptographically signs messages
  • DMARC: Enforces policy and provides reporting

Next Steps

  1. Monitor reports weekly: Review DMARC aggregate reports
  2. Progress to stricter policy: Move from none → quarantine → reject
  3. Configure subdomains: Protect all subdomains
  4. Set up automated alerts: Be notified of issues
  5. Regular audits: Quarterly review of configuration
  6. Team education: Train staff on email authentication

Important Reminders

  • Never skip monitoring phase: Always start with p=none
  • Review reports before changing policy: Understand your email ecosystem
  • Document all sources: Keep inventory of legitimate senders
  • Test thoroughly: Verify each policy change
  • Communicate changes: Inform relevant teams

With SPF, DKIM, and DMARC properly configured, you have industry-leading email authentication that protects your domain, improves deliverability, and provides visibility into your email infrastructure. Continue monitoring and maintaining these systems to ensure ongoing protection and optimal email performance.