Claude
Skills
Sign in
Back

email-infrastructure

Included with Lifetime
$97 forever

Email deliverability and DNS-based email authentication covering SPF, DKIM, DMARC, MX, PTR, and BIMI records, SMTP relay service configuration (SendGrid, SES, Postmark, Mailgun), self-hosted Postfix relay basics, and deliverability testing. USE WHEN: - Setting up or auditing email DNS records (SPF, DKIM, DMARC, MX, PTR) - Configuring a transactional email relay service (SendGrid, Amazon SES, Postmark) - Rolling out a DMARC policy from p=none to p=reject - Debugging emails landing in spam or being rejected - Generating DKIM key pairs for a custom domain - Setting up Postfix as a smart relay host - Checking email blacklists and Google Postmaster Tools DO NOT USE FOR: - Building a full mail server (Dovecot IMAP, Postfix + Dovecot stack — scope is relay/deliverability) - Marketing email platform setup (Mailchimp, Klaviyo campaign workflows) - Email template design or HTML email rendering - Inbound email parsing pipelines (use SendGrid Inbound Parse, Mailgun Routes, etc.)

Ads & Marketing

What this skill does


# Email Infrastructure — Deliverability and DNS Authentication

## Why Email Authentication Matters

Without SPF + DKIM + DMARC, any server can forge `From: [email protected]`. Major providers (Google, Microsoft, Yahoo) now reject or spam-folder unauthenticated email. As of 2024, Gmail and Yahoo require DMARC for bulk senders.

| Record | What It Does | Where Set |
|--------|-------------|-----------|
| MX | Where to deliver inbound email | DNS |
| SPF | Which servers are authorized to send for this domain | DNS (TXT) |
| DKIM | Cryptographic signature verifying message origin | DNS (TXT) + mail server |
| DMARC | Policy for SPF/DKIM failures + reporting | DNS (TXT) |
| PTR | Reverse DNS for sending IP | Hosting provider |
| BIMI | Brand logo in inbox (requires DMARC reject) | DNS (TXT) |

---

## MX Records

```dns
; Priority lower = higher preference (10 < 20)
example.com.    3600    IN    MX    10    mail1.example.com.
example.com.    3600    IN    MX    20    mail2.example.com.
```

For relay-only setups (all outbound, no self-hosted inbound), set MX to your relay provider's receiving servers or use a catch-all:
```dns
; SendGrid inbound parse MX
example.com.    3600    IN    MX    10    mx.sendgrid.net.
```

Test MX records:
```bash
dig MX example.com
nslookup -type=MX example.com
# From MXToolbox:
# https://mxtoolbox.com/MXLookup.aspx
```

---

## SPF (Sender Policy Framework)

### SPF Mechanisms

| Mechanism | Meaning |
|-----------|---------|
| `ip4:1.2.3.4` | Authorize single IPv4 address |
| `ip4:1.2.3.0/24` | Authorize IPv4 CIDR range |
| `ip6:2001:db8::/32` | Authorize IPv6 CIDR |
| `include:spf.example.com` | Include another domain's SPF (counts as 1 lookup) |
| `a` | Authorize the domain's A record IP |
| `mx` | Authorize the domain's MX server IPs |
| `~all` | Softfail — treat unauthorized as suspicious (recommended during testing) |
| `-all` | Hardfail — reject unauthorized senders (use only with DMARC p=reject live) |
| `?all` | Neutral — no policy (avoid in production) |
| `+all` | Allow all — completely useless and dangerous, never use |

### SPF Record Examples

```dns
; Basic SPF for domain using only SendGrid
example.com.    3600    IN    TXT    "v=spf1 include:sendgrid.net ~all"

; Multiple authorized senders
example.com.    3600    IN    TXT    "v=spf1 ip4:203.0.113.10 include:sendgrid.net include:amazonses.com ~all"

; Include your hosting provider's IP range + relay
example.com.    3600    IN    TXT    "v=spf1 ip4:203.0.113.0/24 include:spf.mailgun.org ~all"
```

### SPF Lookup Limit

SPF allows a maximum of **10 DNS lookups** during evaluation. `include:`, `a`, `mx`, `ptr`, `exists` each count as a lookup. Exceeding 10 causes `permerror`, which DMARC treats as a failure.

```bash
# Check SPF record and count lookups
dig TXT example.com | grep spf

# Use spf-tools to flatten (replace includes with raw IPs)
# pip install pyspf
python3 -m spf example.com
```

SPF flattening: replace `include:sendgrid.net` with the actual IPs from SendGrid's SPF record. Must be re-flattened when SendGrid rotates IPs — use automation or a flattening service.

---

## DKIM (DomainKeys Identified Mail)

### DKIM Key Generation

```bash
# Generate 2048-bit RSA key pair
openssl genrsa -out dkim_private.key 2048
openssl rsa -in dkim_private.key -pubout -out dkim_public.key

# Extract public key content for DNS TXT record
openssl rsa -in dkim_private.key -pubout -outform der 2>/dev/null | base64 -w0
```

### DKIM DNS TXT Record Format

Selector naming convention: use `<year><month>` or service name (e.g., `sg2024`, `ses1`, `mail`).

```dns
; Full format: <selector>._domainkey.<domain>
sg2024._domainkey.example.com.    3600    IN    TXT    (
    "v=DKIM1; k=rsa; p="
    "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
    "...rest of public key in base64..."
)
```

Split into multiple strings (DNS TXT records max 255 chars per string):
```bash
# Split public key for DNS (many DNS providers do this automatically)
openssl rsa -in dkim_private.key -pubout 2>/dev/null | \
  grep -v "^-" | tr -d '\n' | \
  fold -w 200
```

### DKIM Configuration in Relay Providers

**SendGrid:** Domains → Add Domain → CNAME records provided (SendGrid manages keys). Custom DKIM requires dedicated IP.

**Amazon SES:** Email Identities → Verify Domain → DKIM section → Create DKIM (SES manages 2048-bit keys). Three CNAME records provided.

**Postmark:** Sender Signatures → Add Domain → DKIM TXT records provided.

Test DKIM record:
```bash
dig TXT sg2024._domainkey.example.com

# Send a test email and check headers for:
# DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=sg2024; ...
# Authentication-Results: dkim=pass header.d=example.com
```

---

## DMARC (Domain-based Message Authentication, Reporting & Conformance)

### DMARC Record Structure

```dns
_dmarc.example.com.    3600    IN    TXT    (
    "v=DMARC1;"
    "p=quarantine;"           ; none | quarantine | reject
    "rua=mailto:[email protected];"    ; Aggregate reports (daily)
    "ruf=mailto:[email protected];"  ; Forensic reports (per-failure)
    "pct=100;"                ; Percentage of messages to apply policy to
    "adkim=s;"                ; DKIM alignment: s=strict, r=relaxed
    "aspf=r;"                 ; SPF alignment: s=strict, r=relaxed
    "sp=reject;"              ; Subdomain policy
    "fo=1"                    ; Forensic options: 0=fail both, 1=fail either, d=DKIM, s=SPF
)
```

**Alignment modes:**
- `relaxed` (default): `example.com` DMARC aligns with `mail.example.com` DKIM/SPF — useful for subdomains
- `strict`: Must be exact domain match

### DMARC Rollout Sequence

**Step 1: Monitor (week 1–4)**
```dns
"v=DMARC1; p=none; rua=mailto:[email protected]; pct=100"
```
Collect aggregate reports. Use dmarcian.com or Postmark DMARC Digests to parse reports. Identify all legitimate senders failing DMARC.

**Step 2: Fix Sending Sources**
- Ensure all authorized mail goes through DKIM-signed relay
- Add any missed senders to SPF
- Remove unknown/unauthorized sending sources

**Step 3: Quarantine (week 4–8)**
```dns
"v=DMARC1; p=quarantine; rua=mailto:[email protected]; pct=10"
```
Start at 10% — only 10% of failing mail goes to spam. Increase `pct` by 10% each week while monitoring reports.

**Step 4: Full Quarantine**
```dns
"v=DMARC1; p=quarantine; rua=mailto:[email protected]; pct=100"
```

**Step 5: Reject (week 8–12)**
```dns
"v=DMARC1; p=reject; rua=mailto:[email protected]; pct=10"
```
Again, ramp `pct` up weekly.

**Step 6: Full Enforcement (target)**
```dns
"v=DMARC1; p=reject; rua=mailto:[email protected]; ruf=mailto:[email protected]; pct=100; adkim=s; aspf=r"
```

---

## PTR (Reverse DNS)

PTR is a reverse DNS record: `<reversed-IP>.in-addr.arpa.` → `hostname`.

Mail servers check PTR of the sending IP and compare to the `From:` or EHLO hostname. PTR mismatch is a strong spam signal.

```bash
# Check PTR for an IP
dig -x 203.0.113.10
nslookup 203.0.113.10

# Check what your IP's PTR resolves to
curl ifconfig.me   # Get your outbound IP
dig -x $(curl -s ifconfig.me)
```

To set PTR: contact your hosting provider or VPS control panel (e.g., DigitalOcean: Droplet → Settings → rDNS; Hetzner: Server → Networking → IP settings). PTR must match the EHLO hostname your mail server uses.

---

## BIMI (Brand Indicators for Message Identification)

Requires: DMARC `p=reject` + a Verified Mark Certificate (VMC from DigiCert/Entrust).

```dns
; BIMI record (hosted SVG logo + VMC certificate URL)
default._bimi.example.com.    3600    IN    TXT    (
    "v=BIMI1;"
    "l=https://cdn.example.com/logo.svg;"
    "a=https://cdn.example.com/vmc.pem"
)
```

SVG requirements: SVG Tiny PS format, square, brand-safe, publicly accessible HTTPS URL.

---

## Complete DNS Record Set: SendGrid Integration

```dns
; ── MX Records (using SendGrid inbound parse) ──────────────────────────────────
example.com.              3600    IN    MX     10    mx.sendgrid.net.

; ── SPF Record ────────

Related in Ads & Marketing