Skip to content

DKIM with Postfix

After looking deeper into various email management solutions, I have decided to implement DKIM on my personal smtp server, mainly to sign outgoing mail.

I have chosen to use dkim-filter for this job, using Postfix ability to deal with Sendmail milters.

Making dkim-filter work with my current setup (I use DSPAM for mail filtering) was quite easy, I simply followed these steps:

Install dkim-filter and generate the key

# aptitude install dkim-filter
# mkdir -p /usr/local/var/dkim-filter
# dkim-genkey -d yourdomain.tld -s yourselector -d /usr/local/var/dkim-filter

Replace yourdomain.tld with your domain name, and yourselector by the selector name you want to use (the selector is added to the domain name, used to find DKIM public key information).

Configure dkim-filter

dkim-filter configuration file on Debian is /etc/dkim-filter.conf.

Edit this file to suit your needs, reading dkim-filter.conf(8) will undoubtedly help you a lot.
Most important is to edit the first variables: Domain, KeyFile (full path to your private key saved in /usr/local/var/dkim-filter if you followed the previous step), and Selector (the selector you have just chosen).

You might also want to change the operating mode of dkim-filter (variable is Mode: valid modes are s (signer) and v (verifier), default being sv, meaning dkim-filter acts both as signer and verifier).

You will also want to edit /etc/default/dkim-filter so that dkim-filter uses TCP connection, rather than a local socket (this could be done, but Postfix running in a chroot on Debian, the socket file would need to be accessible from within this chroot):

SOCKET="inet:8891@localhost"

Configure bind DNS server

Simply add the contents of the .txt file created by dkim-genkey in the first step to your zone file.
It should look like this:

selector._domainkey IN TXT "v=DKIM1; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJPLpjcpGRWqO[...]" ; ----- DKIM dkim for yourdomain.tld

Reload your zone and wait for the change to spread to other DNS servers.

Configure Postfix

Just append the following lines to /etc/postfix/main.cf:

# dkim
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

If, like me, you use DSPAM, you will also have to pay particular attention to how DSPAM reinjects mail to postfix after analysing them. To avoid mail being inspected twice by dkim-filter, you will need to add “no_milters” to the receive_override_options in the DSPAM reinjection service:

localhost:10026 inet  n -       n       -       -        smtpd
  -o content_filter=
  -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks,no_milters
  -o smtpd_helo_restrictions=
  -o smtpd_client_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o mynetworks=127.0.0.0/8
  -o smtpd_authorized_xforward_hosts=127.0.0.0/8

Test

After starting the dkim-filter service and reloading Postfix so that the new configuration options are taken into account, you can send some email to the Port25.com autoresponder: check-auth2 [at] verifier.port25.com
This will confirm that outgoing messages are correctly signed.

You should get something like:

==========================================================
Summary of Results
==========================================================
SPF check:          neutral
DomainKeys check:   neutral
DKIM check:         pass
Sender-ID check:    pass
SpamAssassin check: ham

You may also simply want to email to / from Gmail. When you read a DKIM signed mail, you should see “signed by” line like:Capture-Gmail

When receiving an email sent from Gmail, you should find a header like:

Authentication-Results: mail.kirya.net; dkim=pass (1024-bit key)
 header.i=@gmail.com; dkim-asp=none

You can use it to accept/refuse/classify your email using procmail, maildrop or sieve.

If you use logcheck, you might be interested in these local rules I added to /etc/logcheck/ignore.d.server/local-dkim-filter:

^\w{3} [ :0-9]{11} [._[:alnum:]-]+ dkim-filter\[[0-9]+\]: [[:xdigit:]]{10} external host .* attempted to send as kirya.net$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dkim-filter\[[[:digit:]]+\]: [[:xdigit:]]{10}: no signature data$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dkim-filter\[[[:digit:]]+\]: [[:xdigit:]]{10}: can't parse From: header$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dkim-filter\[[[:digit:]]+\]: [[:xdigit:]]{10} ASP query: missing parameter\(s\) in policy data$