In this post, I would like to show, how to use DKIM together with postfix to enhance the chance, that mails send by your mail server are not marked as spam at the receiver. In my last post, I showed how to set up postfix in front of scalix to filter incoming mails. As also the outgoing mails will use postfix I would like to insert the DKIM header into the mails by postfix. To do this, I will use opendkim on debian. Before I start to explain how to configure it, I would like to explain DKIM.
What is DKIM
DKIM or DomainKeys Identified Mail is a procedure, developed by Yahoo in order do validate the sender of a mail. This can be helpful to detect if the mail is spam or not.
If a mail is sent, the sending mail server will add a DKIM header to the mail. This header includes information like the signing domain and a selector, besides other information and the signing key. The receiver will then use both information to query a TXT (DNS) record for this domain to get the public signing key. With the help of this key, the receiver of the mail will recalculate the signing key on his own and then compare the one in the mail with the calculated one. If both matches, the mail was not altered during transmission and comes from a trusted source.
Using DKIM with Postfix
To sign outgoing emails and check incoming emails, you can use OpenDkim on D
The first step is to install OpenDkim on Debian:
apt-get install opendkim
After OpenDkim is installed, you need to configure it to work with Postfix. Open the main configuration file for OpenDkim:
/etc/opendkim.conf
The file should look like this:
# This is a basic configuration that can easily be adapted to suit a standard
# installation. For more advanced options, see opendkim.conf(5) and/or
# /usr/share/doc/opendkim/examples/opendkim.conf.sample.
# Log to syslog
Syslog yes
# Required to use local socket with MTAs that access the socket as a non-
# privileged user (e.g. Postfix)
UMask 002
# Sign for example.com with key in /etc/mail/dkim.key using
# selector '2007' (e.g. 2007._domainkey.example.com)
#Domain example.com
#KeyFile /etc/mail/dkim.key
#Selector 2007
# Commonly-used options; the commented-out versions show the defaults.
#Canonicalization simple
#Mode sv
#SubDomains no
#ADSPAction continue
# Always oversign From (sign using actual From and a null From to prevent
# malicious signatures header fields (From and/or others) between the signer
# and the verifier. From is oversigned by default in the Debian pacakge
# because it is often the identity key used by reputation systems and thus
# somewhat security sensitive.
OversignHeaders From
# List domains to use for RFC 6541 DKIM Authorized Third-Party Signatures
# (ATPS) (experimental)
#ATPSDomains example.com
AutoRestart Yes
AutoRestartRate 10/1h
SyslogSuccess Yes
LogWhy Yes
Canonicalization relaxed/simple
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
Mode sv
PidFile /var/run/opendkim/opendkim.pid
SignatureAlgorithm rsa-sha256
UserID opendkim:opendkim
Socket inet:12301@localhost
The last part is the interesting one. Save the file. We now need to create some additional files to get it working.
I will start with this file:
/etc/opendkim/TrustedHosts
This file is used to specify hosts and domains which are not checked but signed. The file could look like this:
127.0.0.1
localhost
10.3.5.0/24
*.flomain.de
According to the content of this file, all e
The next file is the KeyTable:
/etc/opendkim/KeyTable
This file is used to link the domain selector to the private key which is stored in a file. It could look like this:
mail._domainkey.flomain.de flomain.de:mail:/etc/opendkim/keys/flomain.de/mail.private
The separator is “mail”. You can use any separator as you like.
The last file is the file with the signing table:
/etc/opendkim/SigningTable
This one instructs OpenDkim, which key should be used for which mail address. Basically, every mail user could have their own private key. In reality, this makes no sense and you would specify one key for the domain like this:
*@flomain.de mail._domainkey.flomain.de
We have now everything in place, except the keys. Generating the keys is the next step. The good news is, that OpenDkim already includes the tools to generate the key.
You can create the key in every folder on your server and copy the key then into the key directory or you change to the keys directory now:
cd /etc/opendkim/keys/
You should create sub folders for every domain:
mkdir flomain.de
and change into this created directory. To generate the key use this command:
opendkim-genkey -s mail -d floamin.de
Where “s” is the selector and “d” is the domain.
This will generate two files. The key file, which should be kept private by changing the owner to “opendkim” and make it available only for this user, and a txt file which has the txt record the for the DNS server included.
I know have to add the content of the
You can check, if the record is correct by using this site:
http://www.protodave.com/tools/dkim-key-checker/
You need to insert the selector and the domain and the tool will query your DNS server and check if the record is there and configured correctly.
If this is working, you need to tell postfix to use Opendkim to check and sign messages.
Open this file:
/etc/default/opendkim
and add this to the end of the file:
SOCKET="inet:12301@localhost"
Save the file and open the Postfix configuration:
/etc/postfix/main.cf
Check if those lines are present:
milter_protocol = 2
milter_default_action = accept
and add the following lines:
smtpd_milters = inet:localhost:12301
non_smtpd_milters = inet:localhost:12301
If the two commands above are already there, e.g. if you use milter to connect SpamAssassin to postfix, simply add the Opendkim milter at the end, separated by a “,”.
After restarting both services, Opendkim and Postfix, it should work. You can test this by sending a mail to “[email protected]”. You should receive a reply containing the result of the DKIM check like this:
==========================================================
Summary of Results
==========================================================
SPF check: pass
DomainKeys check: neutral
DKIM check: pass
Sender-ID check: pass
SpamAssassin check: ham
If you see “pass” for the DKIM check, then your DKIM configuration is working.
If you look into the source code of your emails and see the DKIM header twice, you should adjust your Postfix master config:
/etc/postfix/master.cf
You should have an entry like this at the end of the file:
127.0.0.1:10025 inet n - - - - smtpd
-o content_filter=
-o local_recipient_maps=
-o relay_recipient_maps=
-o smtpd_restriction_classes=
-o smtpd_delay_reject=no
-o smtpd_client_restrictions=permit_mynetworks,reject
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o smtpd_data_restrictions=reject_unauth_pipelining
-o smtpd_end_of_data_restrictions=
-o mynetworks=127.0.0.0/8
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
-o smtpd_client_connection_count_limit=0
-o smtpd_client_connection_rate_limit=0
-o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
Add this to the last line:
,no_milters
After restarting Postfix, you should have only one DKIM header in your mails.
If you have any questions, regarding this post or if you would like provide feedback, please use the comment function below.