DKIM with Postfix on Debian wheezy
DomainKeys Identified Mail is a method that allows an MTA to add a signature to outgoing mails. The receiving MTA can validate the signature using a key published in the sender's DNS records. This page outlines how to configure opendkim with Postfix on Debian wheezy. The setup is similar to one described in the document DKIM on Debian Wheezy with minor changes. Most notably, the setup described here uses a UNIX socket for the Postfix-to-opendkim communication rather than a TCP port. This is marginally more secure as it doesn't create a potential remote attack surface as a TCP port would.
First, install the opendkim packages:
opendkim Milter implementation of DomainKeys Identified Mail
opendkim-tools Set of command line tools for OpenDKIM
Configuring opendkim
Edit /etc/opendkim.conf and add the following lines. This page describes a multi-domain setup, hence the KeyTable option is used, which has a precedence over the KeyFile option.
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
UserID opendkim:opendkim
# Postfix runs in a chrooted environment under /var/spool/postfix:
Socket local:/var/spool/postfix/opendkim/opendkim.sock
Edit /etc/opendkim/TrustedHosts and add your trusted domains and IP addresses. These hosts may send mails through this system without credentials.
127.0.0.1
localhost
*.example.com
*.example.net
Next, create the Key table /etc/opendkim/KeyTable which maps the key names to a signing key.
key.for.example.com example.com:mailYYYYMMDD:/etc/opendkim/keys/example.com/mailYYYYMMDD.private
key.for.example.net example.net:mailYYYYMMDD:/etc/opendkim/keys/example.net/mailYYYYMMDD.private
Finally set up the signing table /etc/opendkim/SigningTable. This file maps addresses or domains to one or more signatures.
*@example.com key.for.example.com
*@example.net key.for.example.net
For each domain, create the key in a separate directory using the opendkim tool. The option -d specifies the domain. The -s option specifies the selector, which is the string before the fixed _domainkey domain part. The DNS resource record selector._domainkey.example.com
will be queried by the mail recipient to validate the DKIM signature.
I suggest to choose a form like mailYYYYMMDD as a selector where YYYYMMDD is the current date. This makes it easy to add a new key in the DNS record and still use the old key in Postfix while the change slowly trickles through the various layers of DNS caches.
mkdir -p /etc/opendkim/keys/example.com
opendkim-genkey -D /etc/opendkim/keys/example.com/ -s mailYYYYMMDD -d example.com
chown opendkim: /etc/opendkim/keys/example.com -R
This command creates two files, mailYYYYMMDD.private and mailYYYYMMDD.txt. The former file contains the key and is to be kept secret, and the latter file is a DNS TXT record which needs to be copied to the DNS configuration for the domain. Below is an example of the mailYYYYMMDD.txt file. Copy everything in quotes to the DNS TXT record with name mailYYYYMMDD._domainkey.
mailYYYYMMDD._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2hL+x3IXwY9a1n/UWnumT2K5TZF/UT2bb5tV15acgj6PyFcQhfG0OjJABhwkOsyR3g3qzFXiMqQAdR9qnzAd0PGFk8DQT xKyloNoLIV5wbVXyTDtnTYdGiNhfQmhaS9VmUkN7YKGZ9s8PlF6OlDoT1Yo+Fhr I5jj0Sna6cmppYwIDAQAB" ; ----- DKIM key mailYYYYMMDD for example.com
Please allow a few hours for the various DNS servers to refresh their cache before configuring Postfix.
Configuring Postfix
Edit /etc/postfix/main.cf and add the following line that tells Postfix to handle milter errors gracefully.
milter_default_action = accept
If the DKIM milter is the only in use, then add also the following lines:
smtpd_milters = unix:/opendkim/opendkim.sock
non_smtpd_milters = unix:/opendkim/opendkim.sock
Otherwise, if there are already some milters configured, then simply add the opendkim milters to the existing lines, e.g.:
smtpd_milters = unix:/spamass/spamass.sock, unix:/opendkim/opendkim.sock
non_smtpd_milters = unix:/spamass/spamass.sock, unix:/opendkim/opendkim.sock
Also add a milter_connect_macros option:
milter_connect_macros = j {daemon_name} v {if_name} _
Make sure the directory /var/spool/postfix/opendkim exists and is writable by the user opendkim. Also add the postfix user to the opendkim group so it can read the socket:
mkdir -p /var/spool/postfix/opendkim
chown opendkim:opendkim /var/spool/postfix/opendkim/
usermod -a -G opendkim postfix
On Debian Wheezy, the path to the opendkim.sock is hard coded in the file /lib/systemd/system/opendkim.service. Change the argument to the -p option to /var/spool/postfix/opendkim/opendkim.sock and restart systemd:
systemctl daemon-reload
Finally, restart opendkim and Postfix and you're done.
service opendkim restart
service postfix restart
Increasing the header size for opendkim
Sometimes mails get rejected and you see messages like the one below in your log.
U Wed Dec 7 04:32:55 2016 5 opendkim.service opendkim[3493]: too much header data
This means the header exceeds the built-in size limit in opendkim. You can increase this limit with the following setting in your /etc/opendkim.conf file.
MaximumHeaders 262144
A value of 0 disables the size limit altogether.
Updates
- 7 December 2016
- Added the MaximumHeaders setting and reformulated some sentences.
- 24 June 2015
- Fixed problems with missing /var/spool/postfix/opendkim and access rights to it. Thanks to Milivoj.