# SPF, DKIM and DMARC explained

> What SPF, DKIM, DMARC, MTA-STS, TLS-RPT, DANE and DNSSEC do, how they fit together and what goes wrong.

## The problem

Email by itself does not verify who sent a message: any server can use any sender address, including one at your domain. Encryption between mail servers is optional, and anyone tampering with the connection can suppress it or divert mail.

Seven mechanisms close these gaps through DNS records. SPF, DKIM and DMARC show recipients whether mail using your domain is authorised. MTA-STS and DANE secure the transport of mail to your domain; TLS-RPT reports on it. DNSSEC protects the DNS answers they all rely on.

## Overview

| Mechanism | Protects against | Where it lives |
|---|---|---|
| SPF (RFC 7208) | sending through unauthorised servers | TXT record at the domain |
| DKIM (RFC 6376, RFC 8463) | unnoticed changes to signed parts | TXT record under `selector._domainkey` |
| DMARC (RFC 9989 to 9991, replacing RFC 7489) | forgery of your visible sender domain | TXT record under `_dmarc` |
| MTA-STS (RFC 8461) | delivery without verified encryption | TXT record under `_mta-sts`, policy file over HTTPS |
| TLS-RPT (RFC 8460) | unnoticed transport failures (reports only) | TXT record under `_smtp._tls` |
| DANE (RFC 7672) | as MTA-STS, without certificate authorities | TLSA record at the mail server's name |
| DNSSEC (RFC 4033 to 4035) | forged DNS answers | zone signatures, DS record in the parent zone |

## In detail

### SPF

SPF lists the servers allowed to send for your domain; the recipient compares the delivering server's IP address with it. The check uses the technical sender address (return path), not the one your mail app shows.

```
example.org. IN TXT "v=spf1 ip4:192.0.2.25 include:_spf.example.net -all"
```

**Pitfall:** more than ten terms triggering DNS lookups (such as `include` or `mx`, nested ones counted), or two SPF records at one domain. Either makes the record unusable.

### DKIM

The sending server signs the body and selected header fields of every message. The signing domain publishes the public key in the DNS under a freely chosen selector (here `key1`). Recipients can detect changes and see which domain vouches for the message.

```
key1._domainkey.example.org. IN TXT "v=DKIM1; k=ed25519; p=2jNfm9hFwOt+8YT568bIRZLOU6WflFg++ZYlyT0CTlc="
```

**Pitfall:** a newsletter service sending on your behalf signs with its own domain. The signature is valid but does not count for DMARC.

### DMARC

SPF and DKIM check technical domains, not the visible sender address. DMARC compares them with the visible sender domain; by default, subdomains such as `news.example.org` match too. You also state a preference for failing mail, `none` (monitor only), `quarantine` (treat as suspicious) or `reject` (refuse), and an address for aggregate reports.

```
_dmarc.example.org. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.org"
```

**Pitfall:** setting `reject` before all your own senders pass, so genuine mail fails. Or staying on `none` permanently: reports, but no enforcement.

### MTA-STS

Your domain commits that its mail servers offer TLS with a valid certificate, and names them. In `enforce` mode, senders that honour MTA-STS deliver only on those terms. A TXT record announces the policy:

```
_mta-sts.example.org. IN TXT "v=STSv1; id=20261005"
```

The policy is a text file that `mta-sts.example.org` serves over HTTPS at `/.well-known/mta-sts.txt`:

```
version: STSv1
mode: enforce
mx: mx1.example.org
max_age: 604800
```

**Pitfall:** the mail servers change but the policy still names the old ones. Update the file first, then the `id`, then the MX records.

### TLS-RPT

TLS-RPT protects nothing itself; it shows whether transport encryption works. Participating senders send daily JSON reports to the address you publish.

```
_smtp._tls.example.org. IN TXT "v=TLSRPTv1; rua=mailto:tlsrpt@example.org"
```

**Pitfall:** enforcing MTA-STS or DANE without collecting reports first.

### DANE

DANE publishes in the DNS which key a mail server must present for TLS. Senders that honour DANE then require encryption and deliver only if the key matches this TLSA record. It sits at the mail server's name, so a provider hosting your mail publishes it.

```
_25._tcp.mx1.example.org. IN TLSA 3 1 1 7c9e649aa9ee78f562c3a484163e1747d27f6e4c944ac979f352788a0a45099e
```

**Pitfall:** the server gets a new key while the record stays the same. Add the new record beforehand.

### DNSSEC

DNSSEC signs the records in your zone, so validating resolvers can tell whether an answer is genuine and unchanged. The chain of trust runs through the parent zone, which holds a DS record with your key's fingerprint.

```
example.org. IN DS 63814 13 2 1387cc5c80a36d6686f050ebc31606db4aae3041d788f3c7d637f234cdb2abd4
```

**Pitfall:** after changing DNS provider, the old DS record remains. Validating resolvers then discard every answer; website and mail become unreachable for their users.

## Working together

A message passes DMARC only if SPF or DKIM passes and the domain checked matches the visible sender domain. Forwarding usually breaks SPF while a DKIM signature generally survives; RFC 9989 recommends both. A mailing list that changes the subject or body breaks the signature too.

DANE requires DNSSEC, for your own domain too. MTA-STS is the alternative without DNSSEC: it relies on certificate authorities and HTTPS, but protects only once a sender has fetched the policy undisturbed. TLS-RPT reports on both.

DMARC protects your exact domain, not lookalike domains or display names. The recipient always decides how to treat a message.

## Rollout order

1. List every system that sends with your domain: mailboxes, newsletters, shop.
2. Publish SPF and enable DKIM with your own domain.
3. Publish DMARC with `p=none` and a reporting address; read the reports until every legitimate source passes.
4. Tighten to `quarantine`. `reject` does not suit every domain: RFC 9989 advises against it where users post to mailing lists.
5. Set up TLS-RPT, then MTA-STS in `testing` mode, later `enforce`.
6. Enable DNSSEC, then DANE.

## At privymail.eu

The privymail.eu [Domain Autopilot](https://privymail.eu/en/domains.md) generates the relevant DNS records for custom domains and monitors them.

---

- This page as HTML: https://privymail.eu/en/email-authentication/
- Deutsche Fassung: https://privymail.eu/email-authentication.md
