home old db
documentation:zdkimfilter dkimsign redact zaggregate zfilter_db zdkimfilter.conf




zdkimfilter - DKIM filter for the Courier mail server  


filterctl ("start" | "stop") zdkimfilter

/local/libexec/usr/path/filters/zdkimfilter OPTION

The second form is used for scripting or testing. See OPTIONS below.  


zdkimfilter is a global filter, in the sense that it works for all users. It works in either signing or verifying mode, based on whether the sender has relaying privileges.

A DKIM signature on a message associates a domain with the message, thereby allowing domain owners to claim some responsibility for the messages.  


The signing domain can be inferred in two ways, either by SMTP authentication or by setting a non-empty RELAYCLIENT variable. In both cases, Courier grants relaying privileges.

For SMTP authentication, the domain name is determined after the user id, if it contains an "@". Alternatively, one can define a default_domain.

For non-empty RELAYCLIENT variable, typically set in smtpaccess files, zdkimfilter signs only if the value of RELAYCLIENT starts with "@". In that case, the domain name is the rest of the string. The local part of the user id is set to ``postmaster'' (e.g. for db_sql_check_user). CAUTION: this setting may conflict with Courier appending the value of RELAYCLIENT to message recipient(s). That is meant to force the message through local delivery, possibly using percentrelay. The filter removes the appended values as long as it is installed. To prevent that behavior set let_relayclient_alone. At any rate, when a client uses SMTP authentication, any RELAYCLIENT content is reset.

In either case, the domain name can be obtained from a suitable header field of the message, such as "From:". Use the key_choice_header configuration option to specify that.

The domain name is then looked up in the domain_keys directory. It should be a soft link to the actual key. The basename of the linked-to file contains the selector: If the basename starts with the same string as the domain name, then that initial part and an optional dot are skipped. In addition, an extension of ".private" or ".pem" is discarded. For example, the following will all result in assigning selector sel as the key for example.com:

        example.com -> ../anywhere/sel.private
        example.com -> ../anywhere/sel
        example.com -> ../anywhere/example.com.sel
        example.com -> ../anywhere/example.comsel
        example.com -> ../anywhere/example.com.sel.private
        example.com -> ../anywhere/example.comsel.private
        example.com -> ../anywhere/example.com.sel.pem
        example.com -> ../anywhere/example.comsel.pem
        example.com -> ../anywhere/sel.pem

Keys can be created using opendkim-genkey. The public key must be published on the DNS in order to make it possible for remote receivers to verify the signatures. Domain owners should change selector on a regular basis, or whenever they think the private key might have been compromised. The soft link that enables signing with a given private key should be set after publishing the corresponding public key. The file existence is going to be effective on It is not necessary to restart zdkimfilter for that to take effect.

The user-id used for SMTP authentication is also reported in Courier's "Received:" header field. If the redact_received_auth configuration option is set, zdkimfilter obscures it. See redact(1).

After signing an outgoing message, zdkimfilter logs to the database the list of domains that appeared in any RCPT command. The database can be used for whitelisting and for rate-limiting users. See zfilter_db(1) for more details.  


Messages not qualified as RELAYCLIENT are candidate for DKIM verification. zdkimfilter sorts signatures by domain, putting author domain and whitelisted domains first. It then verifies each domain's signatures until a valid one. If the database is used, an attempt is made to authenticate each domain unless verify_one_domain is set. If report_all_sigs is set, all signatures are processed. Normally, there are only a few signatures in each message, so these settings don't actually change much. However, messages having an unreasonable number of signatures are rejected (max_signatures). That's the only rejection done by default.

Messages can be rejected or dropped according to DMARC, ADSP, and NXDOMAIN configurations, summarized below, and also according to an action_header. The latter is meant to be a last resort for messages caught by anti-virus or anti-phishing filters that add a given header field instead of discarding the message tout-court. For action_header, whitelisting can be tuned by setting dnswl_worthiness_pass and similar options. By setting save_drop, the messages dropped after action_header can be saved.

By default, zdkimfilter adds an "Authentication-Results:" (A-R) header field only when there are noticeable results to report. It uses the host name that Courier uses in its "Received:" field. Other A-R fields with that same name get zapped from the message, if found.

After the message has been dealt with, zdkimfilter logs to the database the results. See zfilter_db(1) for the details.  

DMARC and ADSP policies

These policies deal with the "From:" domain. It is not advisable to honor them indiscriminately, because users of a domain with a strict policy can subscribe to a mailing list that invalidates their signatures. Rejecting that mail would then cause local users to be unsubscribed from such mailing list.

Options honor_dmarc and honor_author_domain set to 0 or 1 the corresponding flags. Then a query db_sql_domain_flags can increase or decrease those values. A DMARC record is looked up unless DMARC flag is less than ADSP's. If no record is found, an ADSP record is looked up unless ADSP flag is less than DMARC's. Thus, if the flags are equal an ADSP record is looked up for domains that still don't have DMARC. Then, if its flag is greater than 0, the policy is honored. However, if an authenticated domain is whitelisted, vouched, or DNSWL allowed, the message is delivered even though the policy failed.

In order to look up a DMARC record correctly, the Public Suffix List file must be available and configured in publicsuffix. In addition, to comply with DMARC, aggregate reports should be sent and received; see zaggregate(1).

A DMARC policy can ask to quarantine a message. If that is honored, A-R field contains a "(QUARANTINE)" comment and the message is delivered normally.

Record lookup of either policy is not going to work for non-existing domains. For A-R, ADSP provides a "dkim-adsp=nxdomain" result code. Rejecting those messages can be enabled by reject_on_nxdomain.  


Configuration options are documented in zdkimfilter.conf(5) and zfilter_db(1).  


The esmtpd configuration files can be tweaked to avoid rewritings that would break existing signatures.
Set this value in esmtpd. See also "trust_a_r" in zdkimfilter.conf(5). Setting both flags allows smooth usage of A-R header fields.
Setting MIME=none prevents rewriting the MIME structure. If you use this, you may want to override it in esmtpd-msa, e.g. by setting MIME=some.
Documented in esmtpd.

DMARC requires SPF, besides DKIM. To enable SPF checking in bofh see courier(8). The result of Courier's SPF check is read from Received-SPF header fields in the message. If SPF is not configured in Courier, turn off this behavior with no_spf, to avoid spurious authentications.  


These are only useful for testing.
-f config-filename
Override the default configuration file; config-filename can be an empty string ("").
Omit database processing.
Print usage and exit.
Print version info, including versions of the underlying libopendkim, and exit.
Any following -t option will directly parse ctlfiles, rather than sending their names through a pipe to one child per mailfile. Albeit read from stdin, the mail file must be a regular file. It is copied to stdout even if not modified, unless errors occur.
-tN[,x] file...
Scan the arguments that follow as N ctl and mail file(s). With ,x behave like batch test, that is non-interactively. Otherwise prompt the user with the id of the forked process, to ease attaching a debugger to it.
Enter batch test mode. This mode accepts a few commands from standard input, in addition of mail and ctl files. These cause DKIM keys (test2), policies (test3), and VBR assertions (test4) to be retrieved from files in the current directory rather than from the DNS.


The HUP signal can be used to have zdkimfilter reload its configuration.

Upon receiving the signal, zdkimfilter reads its configuration file and opens new connections to OpenDKIM library and (possibly) to the database. If no error occurs, it then cleans up the old area, closing old connections, and writes LOG_INFO if verbosity is 2 or higher.  


Please report bugs to the author. Command-line options above should allow one to reproduce any misbehavior in a controlled fashion.  


The id of the parent zdkimfilter process. The basename of this file reflects the command name by which the filter was loaded.
/local/courier/var/path/filters/zdkimfilter or /local/courier/var/path/allfilters/zdkimfilter
The socket where filter process listens to filtering requests. This socket is created in one or the other directory based on "all_mode" configuration option (see zdkimfilter.conf(5)). The basename of this file reflects the command name by which the filter was loaded.
Default directory for links to private keys.
Default configuration file.


Alessandro Vesely <vesely@tana.it>  


courier(8), courierfilter(8)
Explain the "enablefiltering" configuration file, and how to start and stop filters.
Generate an asymmetric key pair suitable for DKIM use.
Explains each configuration option, excluding those for database.
Explains the database configuration options and how to test them.
Also useful for testing a configuration file.
For retrieving an obfuscated user-id.
RFC 6376
DomainKeys Identified Mail (DKIM) signatures.
RFC 7208
Sender Policy Framework (SPF)
RFC 7489
Domain-based Message Authentication, Reporting, and Conformance (DMARC).
RFC 5451
Message header field for indicating message authentication status.
RFC 5617
DomainKey Identified Mail (DKIM) Author Domain Signing Practices (ADSP).

Copyright © 2012-2019 Alessandro Vesely