PhoenixDKIM

A security-focused DKIM signing and verification milter.


Coming from OpenDKIM or Rspamd

You can try PhoenixDKIM while leaving your current DKIM intact (just disabled).

In most cases there is no need to create new DKIM keys, or change DNS records. If you come from OpenDKIM or Rspamd, you can most likely just point PhoenixDKIM to your keys / KeyTable and SigningTable / Vault files. You might have to change the ownership and/or permissions on the key files, but that's all. Then hook PhoenixDKIM up to your MTA, and you're good to go.

This page covers the two most common starting points. The Rspamd section is only about Rspamd's DKIM signing — PhoenixDKIM does not replace the rest of what Rspamd does.

One caution: run a single signer at a time. Don't chain both OpenDKIM and PhoenixDKIM as signing milters for the same mail, or each message gets two signatures from the same selector.

From OpenDKIM | From Rspamd (DKIM signing)


From OpenDKIM

PhoenixDKIM started as a fork of OpenDKIM and is therefore mostly compatible with not-too-exotic OpenDKIM configurations. Migrating is mostly a matter of installing PhoenixDKIM, copying your opendkim.conf file to /etc/phoenixdkim/phoenixdkim.conf, and perhaps changing the ownership of the DKIM key files.

Remember to point your MTA to the PhoenixDKIM socket!

What stays the same

What changed

Test it alongside OpenDKIM

PhoenixDKIM installs a wholly separate footprint and never touches OpenDKIM's files, so the two run side by side. Give PhoenixDKIM its own socket, point it at your existing keys, and move the MTA's milter to it; the signatures it produces validate against your existing DNS because the selector and key are unchanged.

1. Copy the config and keys (or reuse the files in place):

install -d /etc/phoenixdkim
cp  /etc/opendkim/opendkim.conf  /etc/phoenixdkim/phoenixdkim.conf
cp  /etc/opendkim/KeyTable /etc/opendkim/SigningTable  /etc/phoenixdkim/     # If used

For the keys, choose one of two approaches:

Permissions and ownership. PhoenixDKIM runs as its own phoenixdkim user, so it must be able to read the private keys — and by default (RequireSafeKeys) it will refuse a key file that is readable or writable by anyone other than its owner or a group the process belongs to. OpenDKIM's keys are typically owned by the opendkim user, so after copying or pointing at the originals, hand them to phoenixdkim and keep them owner-only (adjust the path if you left the keys in place):

chown -R phoenixdkim:phoenixdkim /etc/phoenixdkim/keys
chmod 600 /etc/phoenixdkim/keys/*.private

A key PhoenixDKIM cannot securely read is skipped rather than used, so check the log on first start if a domain is unexpectedly going unsigned. (Setting RequireSafeKeys false downgrades the refusal to a warning, but fixing ownership is the right answer.)

2. In phoenixdkim.conf, update the paths that still point at OpenDKIM locations and remove any keywords for the dropped subsystems:

Socket            local:/run/phoenixdkim/phoenixdkim.sock
UserID            phoenixdkim:phoenixdkim
Mode              sv
Canonicalization  relaxed/relaxed
KeyTable          /etc/phoenixdkim/KeyTable
SigningTable      refile:/etc/phoenixdkim/SigningTable

(A single-key setup with Domain / Selector / KeyFile works just as well.)

3. Point the MTA at the new socket. For Postfix:

# was:  smtpd_milters = local:/run/opendkim/opendkim.sock
smtpd_milters      = local:/run/phoenixdkim/phoenixdkim.sock
non_smtpd_milters  = local:/run/phoenixdkim/phoenixdkim.sock

Reload Postfix and send a test message; the DKIM-Signature uses the same selector and key, so it validates against your existing DNS record. If anything looks off, point the milter back at OpenDKIM — nothing else changed. When you're happy, leave it on PhoenixDKIM and retire OpenDKIM at your leisure.


From Rspamd (DKIM signing)

This section is only about the DKIM signing part of Rspamd — its dkim_signing module. Rspamd is a full mail-filtering system; PhoenixDKIM is only a DKIM milter, and does not replace Rspamd's scanning, scoring, or anything else. The natural split is to keep Rspamd for filtering and let PhoenixDKIM take over just the DKIM part — which it can do while reading the very same key store.

Order matters: If you let PhoenixDKIM sign and verify DKIM, then you must configure your MTA (e.g. Postfix) to pass emails first to PhoenixDKIM, and only then to Rspamd. That way Rspamd can use the Authentication-Results header that PhoenixDKIM creates for mail filtering (see below for configuration).

What carries over

What's different

Share the same Vault keys

If you manage DKIM keys with rspamadm vault, PhoenixDKIM can sign from the very same secret. Its vault: backend understands the Rspamd layout — a selectors array of {selector, key, alg, valid_start, valid_end} — and applies the identical validity-window rule (valid_start inclusive, valid_end exclusive). During a key roll it behaves exactly as Rspamd does: it signs with every currently-valid selector at once, so the old and new selectors (and RSA + Ed25519) overlap cleanly while DNS propagates.

KeyTable      vault://vault.example.com:8200/v1/secret/data/dkim/{d}
SigningTable  refile:/etc/phoenixdkim/signingtable
VaultToken    hvs.CAES...

No keys are copied and no DNS changes: PhoenixDKIM reads the same store Rspamd already signs from. The full secret format is in the rotation documentation.

Test it alongside Rspamd

Keep Rspamd running for filtering, add PhoenixDKIM as a separate signing milter on its own socket, and turn off Rspamd's signing so you don't double-sign. Keys and DNS stay exactly as they are.

1. Point PhoenixDKIM at your keys — easiest is the shared Vault store above, or a local KeyTable/SigningTable built from the same PEM files — and give it its own socket:

Socket            local:/run/phoenixdkim/phoenixdkim.sock
UserID            phoenixdkim:phoenixdkim
Mode              sv
Canonicalization  relaxed/relaxed
KeyTable          vault://vault.example.com:8200/v1/secret/data/dkim/{d}
SigningTable      refile:/etc/phoenixdkim/signingtable
VaultToken        hvs.CAES...

Permissions and ownership. With the shared Vault store the keys themselves live in Vault, but the VaultToken must be reachable by the phoenixdkim user — if you keep it in a file or reuse Rspamd's token, make sure that file is owned by and readable only by phoenixdkim (and that the token's Vault policy allows the read). If instead you sign from local key files exported from Rspamd, the same rule as the OpenDKIM section applies: chown them to phoenixdkim and keep them owner-only, since RequireSafeKeys refuses loosely-permissioned keys by default. Rspamd usually runs as the _rspamd user, so files carried over from it will not be readable by phoenixdkim until you re-own them.

2. Disable Rspamd's signing so only PhoenixDKIM signs. In local.d/dkim_signing.conf:

enabled = false;

3. Add PhoenixDKIM to the MTA's milter chain ahead of Rspamd, so it signs and Rspamd still filters. For Postfix, rspamd_proxy typically listens on localhost:11332:

smtpd_milters = unix:/run/phoenixdkim/phoenixdkim.sock, inet:localhost:11332

Reload, send a test message, and confirm the DKIM-Signature validates — same selector, same key, same DNS record. To roll back, re-enable Rspamd's dkim_signing and drop PhoenixDKIM from the milter list. When you're happy, leave signing with PhoenixDKIM and let Rspamd get on with filtering.