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
- Your keys and DNS. The same PEM private keys, the same selectors, the same selector._domainkey TXT records — nothing to re-generate or re-publish.
- KeyTable / SigningTable. Identical format (keyname domain:selector:/path/to/key and the signing-table mapping). Copy them across unchanged.
- Configuration keywords. Mode, Domain, Selector, KeyFile, Canonicalization, SignHeaders, OversignHeaders, KeyTable, SigningTable, MultipleSignatures and the rest keep their names and meanings.
- DKIM behaviour and the milter interface. Signing and verification, relaxed/simple canonicalisation, multiple signatures, Ed25519 (RFC 8463) — all as before. Your MTA integration changes only by socket path.
- Lua policy scripts still run; the API table is now pdkim, with odkim kept as a deprecated alias so existing scripts keep working untouched.
What changed
- Binary: opendkim → phoenixdkim.
- Config path: /etc/phoenixdkim/phoenixdkim.conf. PhoenixDKIM never reads /etc/opendkim. Your OpenDKIM config file stays safe and untouched.
- Library and man pages: libphoenixdkim, phoenixdkim(8), phoenixdkim.conf(5), phoenixdkim-genkey, and so on.
- Security defaults. RSA-SHA1 signing is gone, and an RSA-SHA1 signature is never treated as valid on verification — per RFC 8301 it is reported dkim=neutral, never dkim=pass, with On-WeakAlgorithm setting only the message disposition. Keys below 2048 bits are refused for signing.
- Removed subsystems and their keywords. LDAP, SQL (OpenDBX), BerkeleyDB, VBR, ATPS, RBL, reputation, statistics, ADSP and GnuTLS are gone. If your config sets any of their keywords (Statistics, LDAP*, VBR-*, POPDBFile, …), remove them — their presence may stop the filter from starting. The full list and reasoning is on the Removed Features page.
- New backends. http: / https: / vault: / redis: data sets, a Vault selectors array for zero-downtime rotation, and a pdkim.http_get() Lua helper — see the documentation.
- Version number. PhoenixDKIM starts at 1.0.0 — a fresh line, not a step back from OpenDKIM 2.x.
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:
- Copy the keys into /etc/phoenixdkim/keys/ (or wherever you prefer), then update the paths in your KeyTable to match the new location.
- Leave the keys where they are (e.g. /etc/opendkim/keys/ or /etc/dkimkeys/) and just change their ownership to phoenixdkim. The paths in KeyTable then need no change.
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 — set a fresh phoenixdkim-specific path.
- UserID — change opendkim to phoenixdkim (or remove it entirely if you are using the systemd unit, which sets the user directly).
- PidFile — if your config has one, update the path (e.g. /var/run/opendkim/opendkim.pid → /run/phoenixdkim/phoenixdkim.pid), or remove it — the systemd unit does not need an explicit PidFile.
- KeyTable entries — if you copied the keys to a new directory, open /etc/phoenixdkim/KeyTable and update the /path/to/key.private column in each row to the new location. If you left the keys in place and only changed ownership, no path change is needed.
- KeyFile (single-key setups) — same as above: update the path if the key moved.
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
- Your keys and DNS. The same RSA/Ed25519 private keys and the same selector._domainkey TXT records. No re-keying, no DNS changes.
- OpenDKIM-style tables. Rspamd already ships OpenDKIM-compatible key_table / signing_table support, and PhoenixDKIM uses exactly that format, so the mapping is familiar.
- Vault key storage. PhoenixDKIM reads the same HashiCorp Vault secret layout Rspamd uses — see below.
What's different
- Scope. Rspamd filters, scores, greylists and more; PhoenixDKIM only signs and verifies DKIM. Keep Rspamd for the rest.
- Configuration. Rspamd uses UCL
(local.d/dkim_signing.conf); PhoenixDKIM uses the
phoenixdkim.conf keyword format. The signing intent maps directly:
- Rspamd path / selector_map / key → PhoenixDKIM KeyTable + SigningTable (or the vault: backend).
- Rspamd use_domain (header / envelope / recipient) and use_esld → PhoenixDKIM's SenderHeaders / SenderMacro / IdentityHeader selection.
- Rspamd sign_networks / authenticated-sender gating → PhoenixDKIM's InternalHosts / PeerList and signing-mode controls.
- How it runs. Rspamd signs inside rspamd_proxy; PhoenixDKIM is its own milter on its own socket.
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.