DKIM Configuration Complete Guide
DKIM (DomainKeys Identified Mail) adds cryptographic signatures to your emails, allowing receivers to verify authenticity and detect tampering. This guide covers everything from key generation to production deployment.
How DKIM Works
┌─────────────────────────────────────────────────────────────────────────────┐
│ DKIM SIGNING PROCESS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ SENDING SERVER │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 1. Compose Email │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ From: [email protected] │ │ │
│ │ │ To: [email protected] │ │ │
│ │ │ Subject: Important Update │ │ │
│ │ │ Date: Mon, 08 Jan 2025 10:00:00 -0000 │ │ │
│ │ │ │ │ │
│ │ │ Hello, this is the message body... │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 2. Create Hash of Headers + Body │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ Headers to sign: from, to, subject, date │ │ │
│ │ │ Body hash: SHA-256(body) = bh=47DEQpj8HBSa... │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 3. Sign with Private Key │ │
│ │ ┌────────────────────┐ ┌───────────────────────────────┐ │ │
│ │ │ PRIVATE KEY │──▶│ Signature: b=dzdVyOf... │ │ │
│ │ │ (kept secret) │ │ │ │ │
│ │ └────────────────────┘ └───────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 4. Add DKIM-Signature Header │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; │ │ │
│ │ │ d=example.com; s=selector; │ │ │
│ │ │ h=from:to:subject:date; │ │ │
│ │ │ bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=; │ │ │
│ │ │ b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD... │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ RECEIVING SERVER │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 5. Extract Signature Info │ │
│ │ d=example.com s=selector a=rsa-sha256 │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 6. DNS Query for Public Key │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ Query: selector._domainkey.example.com TXT │ │ │
│ │ │ Response: "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG..." │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 7. Verify Signature │ │
│ │ ┌────────────────────┐ ┌───────────────────────────────┐ │ │
│ │ │ PUBLIC KEY │──▶│ Decrypt signature │ │ │
│ │ │ (from DNS) │ │ Compare to computed hash │ │ │
│ │ └────────────────────┘ └───────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌─────────┴─────────┐ │ │
│ │ ▼ ▼ │ │
│ │ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ PASS │ │ FAIL │ │ │
│ │ │ (Authentic) │ │ (Modified │ │ │
│ │ │ │ │ or Forged) │ │ │
│ │ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
DKIM Record Structure
┌─────────────────────────────────────────────────────────────────────────────┐
│ DKIM DNS RECORD │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Record Name: selector._domainkey.example.com │
│ │ │ │ │
│ │ │ └── Your domain │
│ │ └── Fixed subdomain (always _domainkey) │
│ └── Your chosen selector name │
│ │
│ Record Type: TXT │
│ │
│ Record Value: │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA... │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ Tag Breakdown: │
│ ┌──────────┬──────────┬────────────────────────────────────────────────┐ │
│ │ Tag │ Required │ Description │ │
│ ├──────────┼──────────┼────────────────────────────────────────────────┤ │
│ │ v=DKIM1 │ Yes* │ Version (always DKIM1) │ │
│ │ k=rsa │ No │ Key type (rsa default, ed25519 emerging) │ │
│ │ p=... │ Yes │ Public key (base64 encoded) │ │
│ │ t=s │ No │ Testing mode: s=strict, y=testing │ │
│ │ h=sha256 │ No │ Hash algorithm │ │
│ │ s=email │ No │ Service type: * or email │ │
│ │ n=... │ No │ Notes (human-readable) │ │
│ └──────────┴──────────┴────────────────────────────────────────────────┘ │
│ * Technically optional but recommended │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Generating DKIM Keys
Using OpenSSL (Standard Method)
# Generate 2048-bit RSA private key
openssl genrsa -out dkim_private.key 2048
# Extract public key from private key
openssl rsa -in dkim_private.key -pubout -out dkim_public.key
# View the public key (for DNS record)
cat dkim_public.key
Output:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5oIUrFDn4PTAMt5+s6M
3XvPr5L7F5L6hQKMVJjGE8nG3R5F5OKUvM6PTdVLgO4yK4HG4Z5vMQ8dL6R5+s/y
M3n3f3H3h3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3
f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3
f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3
f3L3h3H3f3L3h3QIDAQAB
-----END PUBLIC KEY-----
Format for DNS Record
Remove headers and line breaks to create the DNS value:
# Extract just the key content (remove headers, join lines)
sed -e '/^-/d' dkim_public.key | tr -d '\n'
DNS TXT Record Value:
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5oIUrFDn4PTAMt5+s6M3XvPr5L7F5L6hQKMVJjGE8nG3R5F5OKUvM6PTdVLgO4yK4HG4Z5vMQ8dL6R5+s/yM3n3f3H3h3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3QIDAQAB
Generating 4096-bit Keys (High Security)
# Generate larger key (may need to split in DNS)
openssl genrsa -out dkim_private_4096.key 4096
openssl rsa -in dkim_private_4096.key -pubout -out dkim_public_4096.key
Note: 4096-bit keys exceed DNS TXT record limits (255 chars per string). Most DNS providers handle splitting automatically, but verify your provider supports this.
Ed25519 Keys (Emerging Standard)
# Generate Ed25519 key pair (smaller, faster, equally secure)
openssl genpkey -algorithm ED25519 -out dkim_ed25519_private.key
openssl pkey -in dkim_ed25519_private.key -pubout -out dkim_ed25519_public.key
DNS Record for Ed25519:
v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=
Platform-Specific Configuration
Google Workspace
Admin Console Setup:
- Go to Admin Console → Apps → Google Workspace → Gmail
- Click Authenticate email
- Select your domain
- Click Generate new record
- Select 2048-bit key length
- Note the selector (e.g.,
google) - Copy the TXT record value
DNS Record:
Host: google._domainkey
Type: TXT
Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG...
- Wait 24-48 hours for propagation
- Return to Admin Console and click Start authentication
Microsoft 365
Exchange Admin Center Setup:
- Go to Exchange Admin Center → Mail flow → Rules
- Or use PowerShell:
# Connect to Exchange Online
Connect-ExchangeOnline
# Create DKIM signing config
New-DkimSigningConfig -DomainName example.com -Enabled $true
# Get DKIM CNAME records
Get-DkimSigningConfig -Identity example.com | Format-List Selector1CNAME, Selector2CNAME
DNS Records (CNAME):
Host: selector1._domainkey
Type: CNAME
Value: selector1-example-com._domainkey.example.onmicrosoft.com
Host: selector2._domainkey
Type: CNAME
Value: selector2-example-com._domainkey.example.onmicrosoft.com
Postfix (Linux Mail Server)
Install OpenDKIM:
# Ubuntu/Debian
sudo apt-get install opendkim opendkim-tools
# CentOS/RHEL
sudo yum install opendkim opendkim-tools
Generate Keys:
# Create key directory
sudo mkdir -p /etc/opendkim/keys/example.com
# Generate key pair
sudo opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s mail -v
# Set permissions
sudo chown -R opendkim:opendkim /etc/opendkim/keys
sudo chmod 600 /etc/opendkim/keys/example.com/mail.private
Configure OpenDKIM (/etc/opendkim.conf):
# Basic settings
Syslog yes
UMask 007
Socket local:/run/opendkim/opendkim.sock
# Domain settings
Domain example.com
KeyFile /etc/opendkim/keys/example.com/mail.private
Selector mail
# Signing options
Canonicalization relaxed/relaxed
Mode sv
SubDomains no
# Additional settings
AutoRestart yes
AutoRestartRate 10/1M
Background yes
DNSTimeout 5
SignatureAlgorithm rsa-sha256
Configure Key Table (/etc/opendkim/KeyTable):
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private
Configure Signing Table (/etc/opendkim/SigningTable):
*@example.com mail._domainkey.example.com
Configure Postfix (/etc/postfix/main.cf):
# DKIM signing via OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:/run/opendkim/opendkim.sock
non_smtpd_milters = local:/run/opendkim/opendkim.sock
Start Services:
sudo systemctl enable opendkim
sudo systemctl start opendkim
sudo systemctl restart postfix
Amazon SES
Enable DKIM (AWS Console):
- Go to SES Console → Verified Identities
- Select your domain
- Go to Authentication tab → DKIM
- Click Generate DKIM tokens
- Add the provided CNAME records to DNS
DNS Records (CNAME):
Host: xxxxxxxx._domainkey
Type: CNAME
Value: xxxxxxxx.dkim.amazonses.com
Host: yyyyyyyy._domainkey
Type: CNAME
Value: yyyyyyyy.dkim.amazonses.com
Host: zzzzzzzz._domainkey
Type: CNAME
Value: zzzzzzzz.dkim.amazonses.com
Using AWS CLI:
# Enable DKIM for a verified domain
aws ses verify-domain-dkim --domain example.com
# Get DKIM tokens
aws ses get-identity-dkim-attributes --identities example.com
SendGrid
Enable DKIM (Dashboard):
- Go to Settings → Sender Authentication
- Click Authenticate Your Domain
- Select DNS host and enter domain
- Add the provided DNS records
DNS Records:
Host: s1._domainkey
Type: CNAME
Value: s1.domainkey.uXXXXXX.wlXXX.sendgrid.net
Host: s2._domainkey
Type: CNAME
Value: s2.domainkey.uXXXXXX.wlXXX.sendgrid.net
DKIM Signature Header Explained
┌─────────────────────────────────────────────────────────────────────────────┐
│ DKIM-SIGNATURE HEADER ANATOMY │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; │
│ d=example.com; s=mail; t=1704700000; │
│ h=from:to:subject:date:message-id; │
│ bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=; │
│ b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZ... │
│ │
│ TAG BREAKDOWN: │
│ ┌──────┬────────────────────────────────────────────────────────────────┐ │
│ │ v=1 │ Signature version (always 1) │ │
│ ├──────┼────────────────────────────────────────────────────────────────┤ │
│ │ a= │ Algorithm: rsa-sha256 (recommended) or rsa-sha1 │ │
│ ├──────┼────────────────────────────────────────────────────────────────┤ │
│ │ c= │ Canonicalization: header/body (relaxed/relaxed recommended) │ │
│ ├──────┼────────────────────────────────────────────────────────────────┤ │
│ │ d= │ Signing domain (must match From header for DMARC alignment) │ │
│ ├──────┼────────────────────────────────────────────────────────────────┤ │
│ │ s= │ Selector (used to lookup public key in DNS) │ │
│ ├──────┼────────────────────────────────────────────────────────────────┤ │
│ │ t= │ Timestamp (Unix epoch when signed) │ │
│ ├──────┼────────────────────────────────────────────────────────────────┤ │
│ │ x= │ Expiration (optional, Unix epoch when signature expires) │ │
│ ├──────┼────────────────────────────────────────────────────────────────┤ │
│ │ h= │ Headers included in signature (order matters) │ │
│ ├──────┼────────────────────────────────────────────────────────────────┤ │
│ │ bh= │ Body hash (SHA-256 hash of canonicalized body, base64) │ │
│ ├──────┼────────────────────────────────────────────────────────────────┤ │
│ │ b= │ Signature (RSA signature of header hash, base64) │ │
│ └──────┴────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Canonicalization Explained
┌─────────────────────────────────────────────────────────────────────────────┐
│ CANONICALIZATION OPTIONS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Format: c=header/body │
│ │
│ SIMPLE CANONICALIZATION (strict) │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ • No changes to headers (except trailing CRLF) │ │
│ │ • Body: trailing whitespace removed, empty lines at end removed │ │
│ │ • Signature fails if ANY modification occurs in transit │ │
│ │ • NOT recommended (forwarding often breaks signature) │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ RELAXED CANONICALIZATION (recommended) │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ Headers: │ │
│ │ • Unfold multi-line headers │ │
│ │ • Convert names to lowercase │ │
│ │ • Collapse multiple spaces to single space │ │
│ │ • Remove trailing whitespace │ │
│ │ │ │
│ │ Body: │ │
│ │ • Collapse multiple spaces to single space │ │
│ │ • Remove trailing whitespace from lines │ │
│ │ • Remove empty lines at end │ │
│ │ │ │
│ │ Survives minor modifications by mail relays │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ EXAMPLE TRANSFORMATION (relaxed): │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ Original: │ │
│ │ Subject: Test Email │ │
│ │ (continued) │ │
│ │ │ │
│ │ Canonicalized: │ │
│ │ subject: Test Email (continued) │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ RECOMMENDATION: Always use c=relaxed/relaxed │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Key Rotation
Rotation Process
┌─────────────────────────────────────────────────────────────────────────────┐
│ DKIM KEY ROTATION PROCESS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Day 0: Prepare New Key │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ 1. Generate new key pair with NEW selector │ │
│ │ openssl genrsa -out new_private.key 2048 │ │
│ │ │ │
│ │ 2. Choose new selector name (e.g., mail2024, s2, key2) │ │
│ │ │ │
│ │ DNS State: │ │
│ │ mail._domainkey.example.com → OLD public key (active) │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ Day 1: Publish New Key │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ 3. Add new public key to DNS (keep old key) │ │
│ │ │ │
│ │ DNS State: │ │
│ │ mail._domainkey.example.com → OLD public key (active) │ │
│ │ mail2024._domainkey.example.com → NEW public key (ready) │ │
│ │ │ │
│ │ 4. Wait for DNS propagation (24-48 hours) │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ Day 3: Switch to New Key │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ 5. Update mail server to sign with new selector/key │ │
│ │ │ │
│ │ Mail Server Config: │ │
│ │ Selector: mail2024 (was: mail) │ │
│ │ KeyFile: /path/to/new_private.key │ │
│ │ │ │
│ │ DNS State: │ │
│ │ mail._domainkey.example.com → OLD public key (for emails │ │
│ │ still in transit/queues) │ │
│ │ mail2024._domainkey.example.com → NEW public key (active) │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ Day 33: Remove Old Key │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ 6. Remove old public key from DNS (after 30+ days) │ │
│ │ │ │
│ │ DNS State: │ │
│ │ mail2024._domainkey.example.com → NEW public key (only key) │ │
│ │ │ │
│ │ 7. Archive/destroy old private key │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Rotation Script
#!/bin/bash
# DKIM key rotation script
DOMAIN="example.com"
OLD_SELECTOR="mail"
NEW_SELECTOR="mail$(date +%Y)"
KEY_DIR="/etc/opendkim/keys/${DOMAIN}"
# Generate new key
opendkim-genkey -b 2048 -d ${DOMAIN} -D ${KEY_DIR} -s ${NEW_SELECTOR} -v
# Display new DNS record
echo "Add this DNS record:"
cat ${KEY_DIR}/${NEW_SELECTOR}.txt
# After DNS propagation, update OpenDKIM config
echo ""
echo "After DNS propagates, update these files:"
echo "KeyTable: ${NEW_SELECTOR}._domainkey.${DOMAIN} ${DOMAIN}:${NEW_SELECTOR}:${KEY_DIR}/${NEW_SELECTOR}.private"
echo "Then restart: systemctl restart opendkim"
Testing and Verification
Verify DNS Record
# Using dig
dig +short TXT mail._domainkey.example.com
# Using nslookup
nslookup -type=TXT mail._domainkey.example.com
# Using host
host -t TXT mail._domainkey.example.com
Test with Email
Send a test email to a major provider (Gmail, Outlook) and check headers:
Authentication-Results: mx.google.com;
dkim=pass [email protected] header.s=mail header.b=dzdVyOf;
spf=pass (google.com: domain of [email protected] designates ...
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com
Online Testing Tools
- mail-tester.com - Send email, get detailed report
- dkimvalidator.com - Check DNS record format
- mxtoolbox.com/dkim.aspx - DNS lookup and validation
Command-Line Testing
# Test DKIM signing (Postfix + OpenDKIM)
echo "Test message" | mail -s "DKIM Test" [email protected]
# Check OpenDKIM status
systemctl status opendkim
# View OpenDKIM logs
journalctl -u opendkim -f
# Test with opendkim-testkey
opendkim-testkey -d example.com -s mail -vvv
Troubleshooting
Common Errors
| Error | Cause | Solution |
|---|---|---|
dkim=neutral (no key) | DNS record missing or not propagated | Check DNS, wait for propagation |
dkim=fail (bad signature) | Key mismatch or message modified | Verify key pair match, check intermediaries |
dkim=fail (body hash) | Body modified in transit | Use relaxed canonicalization |
dkim=temperror | DNS timeout | Check DNS server availability |
dkim=permerror | Malformed DNS record | Fix syntax errors in TXT record |
Debug Checklist
┌─────────────────────────────────────────────────────────────────────────────┐
│ DKIM TROUBLESHOOTING CHECKLIST │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ DNS Issues │
│ [ ] TXT record exists at selector._domainkey.domain.com │
│ [ ] Record starts with v=DKIM1 │
│ [ ] Public key (p=) is present and correctly formatted │
│ [ ] No extra whitespace or line breaks in record │
│ [ ] DNS has propagated (check from multiple locations) │
│ │
│ Key Issues │
│ [ ] Private key matches public key in DNS │
│ [ ] Private key file has correct permissions (600) │
│ [ ] Key pair was generated correctly (not corrupted) │
│ [ ] Using supported key type (RSA or Ed25519) │
│ │
│ Configuration Issues │
│ [ ] Selector in config matches DNS record name │
│ [ ] Domain in config matches signing domain │
│ [ ] Mail server is using the signing milter/filter │
│ [ ] Signing service is running and accessible │
│ │
│ Signature Issues │
│ [ ] DKIM-Signature header is being added to outgoing mail │
│ [ ] Signed headers include From, To, Subject, Date │
│ [ ] Using relaxed/relaxed canonicalization │
│ [ ] Body hash (bh=) is being computed correctly │
│ │
│ Delivery Issues │
│ [ ] No intermediaries modifying signed content │
│ [ ] Mailing lists preserving DKIM signature │
│ [ ] Forwarding not breaking signature │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Best Practices
Security Recommendations
- Use 2048-bit RSA keys minimum - 1024-bit is deprecated
- Rotate keys annually - More frequently for high-security
- Protect private keys - Restrict file permissions, consider HSM
- Use relaxed canonicalization - Better survivability
- Sign important headers - from, to, subject, date, message-id
- Monitor DMARC reports - Detect misconfigurations early
Selector Naming Conventions
| Convention | Example | Use Case |
|---|---|---|
| Service-based | google, sendgrid | Third-party email services |
| Date-based | 2024q1, mail2024 | Key rotation tracking |
| Sequential | s1, s2, key1 | Simple rotation |
| Environment | prod, staging | Multiple environments |
Multiple Sender Configuration
┌─────────────────────────────────────────────────────────────────────────────┐
│ MULTI-SENDER DKIM SETUP │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ DNS Records: │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ google._domainkey.example.com → Google Workspace public key │ │
│ │ sendgrid._domainkey.example.com → SendGrid public key │ │
│ │ mail._domainkey.example.com → Your mail server public key │ │
│ │ mailchimp._domainkey.example.com → Mailchimp public key │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ Each service signs with its own selector, all for example.com │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Related Resources
- Email Authentication Complete Guide - Hub article
- SPF Record Syntax Guide - Complete SPF reference
- DMARC Deployment Guide - Tie SPF + DKIM together
- Email Header Analysis - Interpret results
Tools
- DKIM Record Generator - Create DKIM keys and DNS records
- DNS Lookup - Verify your DKIM DNS record
- DMARC Record Generator - Complete your email authentication