DKIM (DomainKeys Identified Mail) adds a digital signature to every message your domain sends. The receiving server looks up your public key in DNS and verifies the signature, proving the message really came from you and wasn't altered in transit. DKIM is one of the three pillars of email authentication alongside SPF and DMARC — and DMARC enforcement requires DKIM (or SPF) to pass with alignment.
DKIM-Signature header naming a selector. The receiver fetches the matching public key from <selector>._domainkey.yourdomain.com and checks the signature. The private key never leaves your server; only the public key lives in DNS.Step 1 — Generate or Obtain a Key Pair
Most managed email providers (Google Workspace, Microsoft 365, and ESPs like SendGrid, Mailgun, Amazon SES) generate the key for you and give you the DNS record to publish — skip to Step 3 in that case. If you run your own mail server, generate a 2048-bit RSA key pair:
# Generate a 2048-bit private key and its public key
openssl genrsa -out dkim-private.key 2048
openssl rsa -in dkim-private.key -pubout -out dkim-public.key
# Show the public key as a single line (strip the PEM header/footer)
grep -v '^-----' dkim-public.key | tr -d '\n's2026a or mail2026. The selector goes in both the DNS record name and the DKIM-Signature header.Step 2 — Build the DNS Record
Publish the public key as a TXT record. The host/name is <selector>._domainkey and the value contains the DKIM version, key type, and the base64 public key:
; Name / Host
s2026a._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...IDAQAB"| Tag | Meaning |
|---|---|
v=DKIM1 | DKIM version — always DKIM1 |
k=rsa | Key type (rsa is universally supported; ed25519 is newer) |
p=… | The base64-encoded public key |
t=y | Optional — testing mode; remove once verified |
"v=DKIM1; k=rsa; p=MIIBI..." "...IDAQAB". They are concatenated on lookup.Step 3 — Publish the Record for Common Providers
Managed providers give you a ready-made record. Typical selectors:
| Provider | Selector(s) | Record type |
|---|---|---|
| Google Workspace | google | TXT (generated in Admin console) |
| Microsoft 365 | selector1, selector2 | CNAME to Microsoft |
| SendGrid | s1, s2 | CNAME |
| Amazon SES | 3 CNAMEs (Easy DKIM) | CNAME |
| Mailchimp / Mandrill | k1 | CNAME |
Step 4 — Enable Signing on Your Server
For a self-hosted Postfix server, OpenDKIM is the usual choice:
# /etc/opendkim.conf
Domain example.com
Selector s2026a
KeyFile /etc/opendkim/keys/example.com/s2026a.private
Socket inet:8891@localhost
# Then in Postfix main.cf
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
milter_default_action = acceptsudo systemctl restart opendkim && sudo systemctl restart postfixStep 5 — Verify DKIM Is Working
Confirm the public key resolves in DNS:
dig TXT s2026a._domainkey.example.com +short
# Expected: "v=DKIM1; k=rsa; p=MIIBIjAN..."Then send a test message to a mailbox you control and inspect the headers — a passing check shows dkim=pass in the Authentication-Results header. You can also confirm the record with the ShowDNS TXT Lookup or run a full Domain Health Report to check SPF, DKIM and DMARC together.
p=quarantine or p=reject so spoofed mail is actually stopped.