This is a DKIM signing and verification milter. In theory it has been tested with both Postfix and Sendmail. The configuration file is designed to be compatible with OpenDKIM, but only a subset of OpenDKIM options are supported. If an unsupported option is specified, an error will be raised. This package includes a default configuration file and man pages. For those to be installed when installing using setup.py, the following incantation is required because setuptools developers decided not being able to do this by default is a feature: python setup.py install --single-version-externally-managed --record=/dev/null For users of Debian Stable (Debian 9, Codename Squeeze), all dependencies are available in either the main or backports repositories: [sudo] apt install python-milter python-nacl python-ipaddress python-dnspython [sudo] apt install -t stretch-backports python-authres python-dkim The preferred method of installation is from PyPi using pip (if distribution packages are not available): [sudo] pip install dkimpy_milter Using pip will cause required packages to be installed via easy_install if they have not been previously installed. Because pymilter and PyNaCl are compiled Python extensions, the system will need appropriate development packages and an C compiler. Alternately, install these dependencies from dsitribution/OS packages and then pip install dkimpy_milter. The milter will work with either pydns (DNS) or dnspython (dns), preferring dnspython is both are available. The dkimpy DKIM module also works with either. Both a systemd unit file and a sysv init file are provided. Both make assumptions about defaults being used, e.g. if a non-standard pidfile name is used, they will need to be updated. The sysv init file is Debian specific and untested, since the developers are not using sysv init. Feedback/patches welcome. The dkimpy-milter drops priviledges after setup to the user/group specified in UserID. During initial setup, this system user needs to be manually created. As an example, using the default dkimpy-user on Debian, the command would be: [sudo] adduser --system --no-create-home --quiet --disabled-password \ --disabled-login --shell /bin/false --group \ --home /var/run/dkimpy-milter dkimpy-milter Since /var/run or /run is sometimes on a tempfs, if the PID file directory is missing, the milter will create it on startup. To start dkimpy-milter with systemd for the first time, you will need to take the following steps: [sudo] systemctl daemon-reload [sudo] systemctl enable dkimpy-milter [sudo] systemctl start dkimpy-milter [sudo] systemctl status dkimpy-milter (to verify it started correctly) As with all milters, dkimpy-milter needs to be integrated with your MTA of choice (Sendmail or Postfix). For Sendmail: Configuration is very similar to opendkim, but needs some adjustment for dkimpy-milter. Here's an example configuration line to include in your sendmail.mc: INPUT_MAIL_FILTER(`dkimpy-milter', `S=local:/var/run/dkimpy-milter/dkimpy-milter.sock')dnl Changing the sendmail.mc file requires a Make (to compile it into sendmail.cf) and a restart of sendmail. Note that S= needs to match the value of Socket in the dkimpy-milter configuration file. Milter support should be present by default in most versions of sendmail these days, but if not included in your Sendmail build, see: http://www.elandsys.com/resources/sendmail/milter.html ISSUES USING SENDMAIL TO SIGN AND VERIFY ======================================== When using the sendmail MTA in both signing and verifying mode, there are a few issues of which to be aware that might cause operational problems and deserve consideration. (a) When the MTA will be used for relaying emails, e.g. delivering to other hosts using the aliases mechanism, it is important not to break signatures inserted by the original sender. This is particularly sensitive particular when the sending domain has published a "reject" DMARC policy. By default, sendmail quotes to address header fields when there are no quotes and the display part of the address contains a period or an apostrophe. However, opendkim only sees the raw, unmodified form of the header field, and so the content that gets verified and what gets signed will not be the same, guaranteeing the attached signature is not valid. To direct sendmail not to modify the headers, add this to your sendmail.mc: conf(`confMUST_QUOTE_CHARS', `') (b) As stated in sendmail's KNOWNBUGS file, sendmail truncates header field values longer than 256 characters, which could mean truncating the domain of a long From: header field value and invalidating the signature. You may wish to consider increasing MAXNAME in sendmail/conf.h to mitigate changing the messages and invalidating their signatures. This change requires recompiling sendmail. (c) Similar to (a) above, sendmail may wrap very long single-line recipient fields for presentation purposes; for example: To: very long name ,anotherloo...ong name b ...might be rewritten as: To: very long name , anotherloo...ong name b This rewrite is also done after opendkim has seen the message, meaning the signature opendkim attaches to the message does not match the content it signed. There is not a known configuration change to mitigate this mutation. The only known mechanism for dealing with this is to have distinct instances of opendkim do the verifying (inbound) and signing (outbound) so that the version that arrives at the signing instance is already in the rewritten form, guaranteeing the input and output are the same and thus the signature matches the payload. For Postfix: Integration of dkimpy-milter into Postfix is like any milter (See Postfix's README_FILES/MILTER_README). Here's an example master.cf excerpt that talks to two dkimpy-milter instances, one configured for signing and one configured for verification: smtp inet n - - - - smtpd ... -o smtpd_milters=inet:localhost:8892 ... submission inet n - - - - smtpd ... -o smtpd_milters=inet:localhost:8891 ... These need to match the Socket value for each dkimpy-milter instance. Care is required to segregate outbound mail to be signed and inbound mail to be verified. The above example uses two instances of dkimpy-milter to do this. There are many possible ways. Here is another example using milter macros to keep the mail streams segregated: Postfix master.cf: smtp inet n - - - - smtpd ... -o smtpd_milters=inet:localhost:8891 -o milter_macro_daemon_name=VERIFYING ... submission inet n - - - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes ... -o milter_macro_daemon_name=ORIGINATING -o smtpd_milters=inet:localhost:8891 ... Dkimpy-milter.conf: ... Mode sv MacroList dameon_name|ORIGINATING MacroListVerify daemon_name|VERIFYING ... The python DKIM library, dkimpy, requires the entire message being signed or verified to be in memory, so dkimpy-milter does not write messages out to a temp file. This may impact performance on low-memory systems. This is an initial production release to support interoperability testing with Ed25519 signatures sufficient functionality for basic use. The documented functionality has been implemented and at generally partially tested. It is free of known defects, but is not fully tested in a variety of environments. DKIM Ed25519 signatures are still in development, but the specification is technically stable. Version 1.0.0 supports draft-ietf-dcrup-dkim-crypto-09.