# PhoenixDKIM Documentation

Man pages | Configuration examples

## Man pages

- opendkim(8) — DKIM signing and verifying filter
- opendkim.conf(5) — configuration file
- opendkim-genkey(8) — generate a DKIM signing key
- opendkim-genzone(8) — generate a DKIM public key DNS zone fragment
- opendkim-testkey(8) — test a DKIM key in DNS
- opendkim-testmsg(8) — test a DKIM-signed message
- opendkim-lua(3) — Lua scripts for OpenDKIM

## 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.