Removed Features
PhoenixDKIM 3.0 narrows the scope of the upstream trusteddomainproject/OpenDKIM tree to its DKIM core, retiring subsystems and build paths whose external dependencies are no longer maintained, or whose use cases have been overtaken by better-fitting tools elsewhere in the modern mail stack.
The original code remains available in the upstream repository for anyone who needs it. This document records each removal with the reasoning behind the call, so that future contributors can understand the shape of the project as it stands today. The scope decisions originate in SCOPE.md; this is the user-facing version.
Crypto
GnuTLS
A complete second crypto backend, selectable in the autotools build via --with-gnutls. Every signing, verifying, and hashing operation in libopendkim had a parallel GnuTLS implementation kept in lockstep with the OpenSSL path.
Reasoning:
- The modernisation target for this fork is the OpenSSL 3 EVP API. Keeping a second backend in sync would split maintenance effort between two crypto libraries that the project does not need to support simultaneously.
- OpenSSL 3 is widely available and is now an unconditional dependency.
See the crypto policy guide for the interaction with hardened crypto policies on RHEL-family distros.
RSA-SHA1 signing
rsa-sha1 has been removed from the signing-algorithm table, and an RSA-SHA1 signature is never treated as valid on verification: per RFC 8301 it can never be reported dkim=pass and is instead reported dkim=neutral — a permanently-failed signature, treated as unsigned. The On-WeakAlgorithm setting selects only what the milter tells the MTA to do with such a message, not whether the signature is trusted.
Reasoning:
- SHA1 is no longer collision-resistant by current standards.
- RFC 8301 (2018) states
rsa-sha1MUST NOT be used for DKIM signing or verifying, and that such a signature has permanently failed evaluation.
Database / data-set backends
BerkeleyDB (bdb: / libdb)
The binary key-table backend (bdb: URI prefix in KeyTable / SigningTable etc.).
Reasoning:
- Upstream Oracle BerkeleyDB has had no public release in years, and its 2013 licence change to AGPL led most Linux distributions to move away from it. Some have dropped the package entirely.
- LMDB is a good fit for the same role: crash-safe, single-file, memory-mapped, and actively maintained. It replaces BDB as the binary backend (
lmdb:).
QUERY_CACHE (internal DNS-result cache)
A libopendkim-internal cache layer in front of dkim-keys.c's TXT-record lookups. Signed key data was stored in a local BerkeleyDB hash file so that repeated verifications wouldn't re-query DNS.
Reasoning:
- The implementation is BerkeleyDB-only at the source level (
<db.h>,DB *,db_create,DB_VERSION_CHECK). With BDB itself removed, the natural follow-on is to remove the cache that depended on it. - A recursive (or stub-to-recursive) DNS resolver caches TXT-record answers at the DNS layer with the right semantics for the job, so losing this in-process cache should not change observable behaviour in a normally-configured deployment.
The public APIs dkim_flush_cache and dkim_getcachestats, and the DKIM_LIBFLAGS_CACHE flag, are removed from dkim.h alongside the feature.
OpenDBX (dsn: SQL backend)
A SQL abstraction layer fronting MySQL/MariaDB/PostgreSQL/SQLite through a single dsn: URI scheme.
Reasoning:
libopendbxis no longer actively maintained upstream.- Holding an SQL connection pool inside a per-message milter couples mail flow to database availability in a way that flat-file or LMDB key tables avoid. For the multi-instance / shared-state cases that motivated the SQL backend, this fork adds first-class Redis support, which is a closer fit operationally.
OpenLDAP (ldap: / ldaps: / ldapi:)
LDAP directory lookup for key tables and signing tables, including the LDAPSoftStart and LDAPDisableCache configuration options.
Reasoning:
- Same coupling concern as SQL: directory binds in the message path add a runtime dependency on the directory server.
- The deployment patterns LDAP supported (centralised tenant key lookup, dynamic policy) can be expressed via Lua hooks or Redis with less operational overhead.
DKIM-adjacent subsystems
VBR (Vouch By Reference)
RFC 5518. Allowed a sending domain to assert that a third-party "voucher" endorses its mail. Implemented as the libvbr/ library plus daemon wiring.
Reasoning:
- VBR did not see significant deployment in the years following its publication, and the reputation/voucher ecosystem that would have given it teeth never materialised at scale.
- Maintaining the implementation absent a deployment story is hard to justify when the project is scoping down to DKIM.
ATPS (Authorized Third-Party Signatures)
RFC 6541 (Experimental). A mechanism for a domain to delegate signing authority to a named third party.
Reasoning:
- ATPS remained Experimental and did not attract production deployment.
- The broader problem ATPS addressed — preserving authentication across mailing lists and other intermediaries that legitimately modify mail — is still unsettled in the standards community. ARC (RFC 8617) has been deployed but has its own trade-offs, and DKIM2 is in development. This fork's position is to wait for the dust to settle rather than carry a third experimental mechanism alongside the DKIM core.
RBL (Realtime Blacklist lookups)
librbl/ and the associated daemon glue, which consulted DNSBLs as part of message disposition.
Reasoning:
- DNSBL evaluation fits more naturally in the MTA's policy stage (postfix policy daemons, smtpd restrictions, opendmarc-style rejection logic) than inside a DKIM signing daemon. Keeping it in opendkim duplicates functionality available elsewhere.
Reputation subsystems (reputation/, reprrd/)
Two collaborative-reputation systems: one rrdtool-backed, one feeding an aggregation backend with per-sender data.
Reasoning:
- Both were Experimental and did not graduate to a production feature.
- The aggregation backend they fed did not see wide adoption.
Stats subsystem
Per-message statistics emitted via SQL to an aggregation server.
Reasoning:
- The aggregation server is no longer running upstream.
- The SQL backend it depended on has been removed (see OpenDBX above).
- A future telemetry story should probably emit StatsD or Prometheus, rather than write rows to a project-specific schema.
FFR (Future Feature Release) flags
The upstream tree used _FFR_* preprocessor guards to ship code for features that were under development or that the maintainers wanted available as opt-in build-time experiments. As this fork has narrowed its scope to the DKIM core, those experiments either tied into subsystems that are no longer present (SQL, LDAP, stats, ATPS, VBR, diffheaders), or addressed concerns that belong in another layer (rate limiting), or were small parser/identity tweaks that did not graduate to defaults. In each case the guarded code has been removed along with the surrounding subsystem rather than kept as conditional code without a way to turn it on.
Removed FFRs include _FFR_RESIGN, _FFR_IDENTITY_HEADER, _FFR_SENDER_MACRO, _FFR_ATPS, _FFR_VBR, _FFR_STATS, _FFR_STATSEXT, _FFR_DB_HANDLE_POOLS, _FFR_LDAP_CACHING, _FFR_POSTGRES_RECONNECT_HACK, _FFR_RATE_LIMIT, _FFR_SOCKETDB, _FFR_DEFAULT_SENDER, _FFR_DIFFHEADERS.
diffheaders / tre
A header-diffing diagnostic helper using the tre regex library to show which header bytes a signer touched.
Reasoning:
- A useful debugging aid, but not on the signing/verification path.
treitself is no longer actively maintained, and was the only dependency on it in this tree. With diffheaders removed, the dependency can go with it.
Other FFR flags
The remaining FFR removals are recorded in their individual removal commits — git log --grep=_FFR_ lists them.
Build system
Autotools (autoconf + automake + libtool)
Reasoning:
- Replaced by CMake + CTest once the new build reached test parity on Debian and Arch.
- The autotools build remains in the upstream repository for anyone who needs to compare or to retrieve it.
libar/ (async DNS resolver)
The internal asynchronous DNS resolver.
Reasoning:
- Already deprecated and effectively retired in opendkim 2.x.
- libunbound (optional,
-DWITH_UNBOUND=ON) covers DNSSEC-aware resolution; the system stub resolver covers the rest.
Configuration keywords no longer accepted
Because the subsystems above are gone, the configuration keywords that drove them are no longer recognised. They were previously enumerated in the configuration man page's deprecated-options section; they are recorded here instead, since PhoenixDKIM is a standalone product rather than a drop-in OpenDKIM replacement. If any of these were carried over from an opendkim.conf, remove them — their presence may stop the filter from starting.
ADSP and legacy policy
AddAllSignatureResults, ADSPAction, ADSPNoSuchDomain, BogusPolicy, DisableADSP, LocalADSP, NoDiscardableMailTo, On-PolicyError, SendADSPReports, UnprotectedPolicy — ADSP (RFC 5617) and its associated policy handling.
Removed subsystems
- RSA-SHA1 signing:
AllowSHA1Only. - LDAP:
LDAPAuthMechanism,LDAPAuthName,LDAPAuthRealm,LDAPAuthUser,LDAPBindPassword,LDAPBindUser,LDAPDisableCache,LDAPKeepaliveIdle,LDAPKeepaliveInterval,LDAPKeepaliveProbes,LDAPTimeout,LDAPUseTLS,LDAPSoftStart. - LDAP/SQL backend start-up:
SoftStart. - Statistics:
Statistics,StatisticsName,StatisticsPrefix. - VBR:
VBR-Certifiers,VBR-PurgeFields,VBR-TrustedCertifiers,VBR-TrustedCertifiersOnly,VBR-Type. - POP-before-SMTP:
POPDBFile. - Header text replacement (the MASQUERADE_AS workaround):
ReplaceHeaders,ReplaceRules.
What this fork keeps
For balance, the components that remain:
- DKIM signing and verification (the core of the project).
- Lua 5.4 policy scripting (
-DWITH_LUA=ON). - libunbound DNSSEC resolution (
-DWITH_UNBOUND=ON). - The
file:/refile:/csl:/lmdb:/redis:/lua:data set backends. - The milter integration (libmilter from Sendmail or as a standalone package).