PhoenixDKIM Documentation

Man pages | Configuration examples

Man pages

Configuration examples

These examples cover common setups from the simplest to the more involved. They are not a substitute for the opendkim.conf(5) man page, which documents every option.

1. Verify only | 2. Verify and sign | 3. Dual signing: Ed25519 and RSA | 4. Hardening

1. Verify only

The minimum configuration to get started: check DKIM signatures on incoming mail without signing anything. Useful while you generate and publish your key, or if you simply do not send mail through this filter.

Syslog                  yes
Socket                  local:/run/opendkim/opendkim.sock
UserID                  opendkim:opendkim

Mode                    v

2. Verify and sign

Generate an RSA signing key with opendkim-genkey(8):

opendkim-genkey -b 2048 -d example.com -s mail

This creates two files: mail.private (the private key) and mail.txt (the DNS TXT record to publish). Copy mail.private to /etc/opendkim/keys/ and publish the record from mail.txt as mail._domainkey.example.com in your domain's DNS.

Syslog                  yes
Socket                  local:/run/opendkim/opendkim.sock
UserID                  opendkim:opendkim

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

Mode sv enables both signing and verification. If you sign for more than one domain, use KeyTable and SigningTable instead of Domain, Selector, and KeyFile; see the opendkim.conf(5) man page.

3. Dual signing: Ed25519 and RSA

Ed25519 is a modern elliptic-curve signature algorithm standardised for DKIM in RFC 8463. Compared to RSA, Ed25519 signatures are smaller, faster to generate, and harder to attack. The downside is that some older or poorly maintained mail infrastructure does not yet support verifying them, and a few milters are known to misbehave — or crash — when they encounter an Ed25519 signature.

One way to handle this is to sign each message with both an Ed25519 key and an RSA key. A verifier that supports Ed25519 uses that signature; one that does not falls back to the RSA signature.

Do consider, though, that until Ed25519 signatures are supported by all major mail services, they are not more effecient because you have to dual-sign with an RSA key for backup. It is also possible that not all mail servers will handle Ed25519 gracefully, even if you have an RSA backup signature.

If you do want to proceed, generate both keys:

opendkim-genkey -b 2048 -d example.com -s mail-rsa
opendkim-genkey -t ed25519 -d example.com -s mail-ed25519

Copy both .private files to /etc/opendkim/keys/example.com/ and publish both DNS records. It is good practice to keep each domain's keys in its own subdirectory under keys/.

The format of KeyTable and SigningTable is described in the opendkim.conf(5) man page.

Create /etc/opendkim/keytable:

mail-rsa      example.com:mail-rsa:/etc/opendkim/keys/example.com/mail-rsa.private
mail-ed25519  example.com:mail-ed25519:/etc/opendkim/keys/example.com/mail-ed25519.private

Create /etc/opendkim/signingtable:

*@example.com  mail-rsa
*@example.com  mail-ed25519
Mode                    sv
Canonicalization        relaxed/relaxed
KeyTable                /etc/opendkim/keytable
SigningTable            refile:/etc/opendkim/signingtable
MultipleSignatures      yes

The refile: prefix on SigningTable enables regular expression matching. With MultipleSignatures yes, all matching entries are applied, so each message receives both signatures.

4. Hardening

By default, PhoenixDKIM signs only the minimum set of headers required by the DKIM specification. Extending this — and oversigning certain headers — significantly raises the bar for forgery and header injection.

SignHeaders extends signing beyond the minimum. Any listed header that is present in a message will be covered by the signature; if it is later altered in transit, the signature will fail. The following covers the headers that matter most for a typical mail sender:

SignHeaders             From,Sender,Reply-To,Subject,Date,Message-Id,To,Cc,Mime-Version,Content-Type,Content-Transfer-Encoding,In-Reply-To,References,List-Id,List-Help,List-Owner,List-Unsubscribe,List-Unsubscribe-Post,List-Subscribe,List-Post,Resent-To,Resent-Cc,Resent-From,Resent-Sender,Resent-Message-Id,Openpgp,Autocrypt

OversignHeaders protects against header injection. When a header is oversigned, the signature includes a commitment to the absence of an extra instance of that header. If an attacker later prepends a new header of the same name — a classic technique for spoofing the apparent From — the signature is immediately invalidated:

OversignHeaders         From,Reply-To,Subject,To,Cc,Date,Message-Id,Mime-Version,Content-Type,Content-Transfer-Encoding,In-Reply-To,References,Sender,Openpgp,Autocrypt

Note that OversignHeaders does not need to mirror every entry in SignHeaders. Headers from the List-* and Resent-* families may legitimately appear multiple times (on mailing lists, for example), so oversigning them can break valid traffic. Focus oversigning on the headers that identify and address the message.