1. Library
  2. Computer Networks
  3. Email Protocols
  4. Authentication

Updated 8 hours ago

DKIM solves a simple problem: how does a receiving server know an email actually came from your domain?

The answer is cryptographic signatures. You generate a key pair—one private, one public. You publish the public key in DNS where anyone can find it. Your mail server signs every outbound message with the private key. Receiving servers verify the signature against your published public key.

If the signature checks out, the message really came from someone with your private key. If it doesn't, something's wrong—either the message was modified in transit, or it wasn't signed by you at all.

The Key Decisions

Before generating anything, make three decisions:

Selector name: Selectors identify which key signed a message. You might use default, mail, or date-based names like 202512 for easier rotation tracking. The selector becomes part of the DNS lookup: selector._domainkey.example.com.

Key size: 2048-bit RSA. It's the standard. 1024-bit is technically acceptable but unnecessarily weak. 4096-bit creates DNS records too large for some resolvers.

Canonicalization: Use relaxed/relaxed. This tells receivers to tolerate minor whitespace changes that happen during transit. The stricter simple/simple breaks signatures if anything touches the message.

Generate Your Keys

On Linux with OpenDKIM tools:

$ sudo apt-get install opendkim-tools
$ opendkim-genkey -t -s selector1 -d example.com -b 2048

This creates two files:

  • selector1.private — Your signing key. Guard this.
  • selector1.txt — The DNS record to publish.

Or generate manually with OpenSSL:

$ openssl genrsa -out dkim.private 2048
$ openssl rsa -in dkim.private -pubout -out dkim.public

Protect the Private Key

Your private key is your domain's signature. Anyone who has it can sign messages as you. Anyone who doesn't, can't. That's the entire security model.

$ chmod 600 selector1.private
$ chown opendkim:opendkim selector1.private

Store it on the mail server in a protected directory like /etc/opendkim/keys/. Back it up securely. Never email it, commit it to version control, or generate it on third-party websites.

Publish the Public Key

The generated selector1.txt contains your DNS record:

selector1._domainkey IN TXT "v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5j8..."

Add this as a TXT record in your DNS provider:

FieldValue
TypeTXT
Nameselector1._domainkey
Valuev=DKIM1; h=sha256; k=rsa; p=MIIBIjANB...
TTL3600

Verify it's published:

$ dig selector1._domainkey.example.com TXT

You should see your public key in the answer section.

Configure Your Mail Server

The specifics depend on your software. Here's Postfix with OpenDKIM:

Install and configure OpenDKIM (/etc/opendkim.conf):

Domain                  example.com
Selector                selector1
KeyFile                 /etc/opendkim/keys/selector1.private
Canonicalization        relaxed/relaxed
Mode                    sv

Connect Postfix to OpenDKIM (/etc/postfix/main.cf):

smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept

Restart both:

$ sudo systemctl restart opendkim postfix

For hosted services like Google Workspace or Microsoft 365, the admin console walks you through it—they generate keys and tell you exactly what DNS records to add.

Verify It Works

Send an email from your domain. Check the headers. You should see:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
    d=example.com; s=selector1;
    h=from:to:subject:date;
    bh=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN/XKdLCPjaYaY=;
    b=gCN9nNMk+9p2q3VhR8BVqR9tVFPLl9V7q1z5XpHBvUl8...

And on the receiving end:

Authentication-Results: mx.google.com;
    dkim=pass header.i=@example.com header.s=selector1

dkim=pass means it worked. Send a test to check-auth@verifier.port25.com for a detailed authentication report.

Key Rotation

Rotate keys annually, or immediately if someone with private key access leaves or you suspect compromise.

The process has an awkward truth: email moves slower than DNS. Messages signed with your old key are still flying through the Internet while you're setting up the new one. So you need both keys published simultaneously during the transition.

  1. Generate a new key with a new selector (selector2)
  2. Publish the new public key in DNS
  3. Configure your mail server to sign with the new key
  4. Wait 48 hours for DNS propagation and in-flight messages to clear
  5. Remove the old public key from DNS
  6. Delete the old private key

When Things Go Wrong

No DKIM-Signature header: Your mail server isn't signing. Check that the DKIM plugin is enabled and the private key path is correct.

dkim=fail: Either the DNS record doesn't match the private key, or the message was modified in transit. Regenerate keys if needed, and ensure you're using relaxed canonicalization.

dkim=temperror: DNS lookup failed. Verify your records are published and accessible.

dkim=permerror: Malformed DNS record. Check for accidental line breaks or syntax errors in the public key.

Monitoring

Set up DMARC to receive aggregate reports:

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

These reports show your DKIM pass rates, which selectors are in use, and where signatures are failing. It's the only way to know if your DKIM setup is actually working across all the mail you send.

Frequently Asked Questions About DKIM Setup

Was this page helpful?

😔
🤨
😃