ipsure logo
Logo and Language
Login icon Language selection icon
Hello, guest
*NIX Active category menu left background Active category menu right background BACKUP Hands-On blog header image Right block of Hands-On blog header image Final menu block of Hands-On blog header image
MS TIP PKI Active category menu left background Active category menu right background PROJECTS CMS Türkçe HANDS-ON SERVICES IT BUSINESS CONTACT ABOUT REFERENCES TERMS RSS
Home page Hands-On Services IT Business Contact About References Terms of Use RSS


DomainKeys Identified Mail (DKIM) with Postfix (SMTP-Only)

Filed under: *NIX, PKI — Tags: , , , , , , — Sezgin Bayrak @ 22:37

spam emailsDKIM is a sender authentication scheme for signing messages in a way that these messages can be validated by the recipient side. DKIM, which is usually a part of MTA, is based on public-key cryptography therefore the validation process naturally depends on public-private key pair. Signer MTA affixes a digital signature into the message header by “DKIM Signature:” field which will then be used by the verifier side to recover the signer’s public key via DNS and complete the verification.

If DKIM is used, you can absolutely build a positive reputation regarding your domain to help improve delivery but you shouldn’t rely upon it to create an “all emails into Inbox” marvel especially if you have a mass mailing oriented marketing strategy. In terms of authentication, DKIM is one of the serious and highly recommended steps that has to be taken to gratify the growing expectations of huge messaging providers but won’t be the final one.

Although the installation and implementation of DKIM for Postfix slightly differ at variety of *nix types, configuration principles will resemble each other up-and-down. We’ll be implementing it on FreeBSD so let’s get to work by first updating our ports tree if it’s stale.

# portsnap fetch
# portsnap update

We’ll use dkim-milter (mail filter) plugin so we have to edit make.conf to compile it to use Postfix port instead of sendmail which is the default option. For further technical info, you may visit http://www.postfix.org/MILTER_README.html

# vi /etc/make.conf

Add the following line into the file;


Exclamation mark This setup had been last tested on FreeBSD 8.2-RELEASE at Feb 2011. As dkim-milter has expired and recently it has been removed from the ports tree, we strongly recommend you to read our “Dkim-milter is No Longer Available, How to Use OpenDKIM Instead” guide and consequently move to OpenDKIM.

Navigate to dkim-milter port directory and install the port;

# cd /usr/ports/mail/dkim-milter
# make install clean

Copy the sample configuration file as dkim-filter.conf in order to edit it;

# cp /usr/local/etc/mail/dkim-filter.conf.sample /usr/local/etc/mail/dkim-filter.conf
# vi /usr/local/etc/mail/dkim-filter.conf

Uncomment KeyList parameter at line 229. We’ll create this file later below to specify our domains that we want to sign.

KeyList /var/db/dkim/keylist

Travel down to line 489, uncomment and set the socket information with an appropriate port where the filter should listen for milter connections from the MTA;

Socket inet:10026@localhost

Our next step is to create separate directories for our email domains in order to store our key pair inside them. Keys will be generated by dkim-genkey tool as two separate files. default.private will hold the RSA private key and default.txt will hold the matching public one in a format that you can insert to your DNS zone file.

# mkdir -p /var/db/dkim/keys/ipsure.com
# cd /var/db/dkim/keys/ipsure.com/
# dkim-genkey -r -d ipsure.com
 -r Restricts the key for use in e-mail signing only. The default is to allow the key to be used for any service.

 -d domain Names the domain which will use this key for signing.


-rw-------  1 root  wheel  887 Sep 18 10:51 default.private
-rw-------  1 root  wheel  304 Sep 18 10:51 default.txt

We shall rename these default files to proper subdomain names (selector) which the public key will also be published by. For example if we want to publish the public key under dkim._domainkey.ipsure.com then we’ll set them as;

-rw-------  1 root  wheel  887 Sep 18 10:51 dkim
-rw-------  1 root  wheel  301 Sep 18 17:45 dkim.txt

_domainkey is the standard and the integral part of the whole domain name as the recipient side will particularly query the public key in that manner. But the SELECTOR part is completely up to you and may be whatever you like. Recipient side will find this selector value in your email’s DKIM-Signature: header field.

So I opt dkim as a selector for this implementation and rename the files appropriately.

# mv default.private dkim
# mv default.txt dkim.txt

We create our keylist file and append the path of the private key(s) with the relevant domain names one under the other by using “pattern:domain:selector” format.

# touch /var/db/dkim/keylist
# vi /var/db/dkim/keylist

We have to enable SMTP-only Milter application inside Postfix configuration file so that milter can handle the emails that arrive via the Postfix server. Insert smtpd_milters parameter into your Postfix main.cf file;

# vi /usr/local/etc/postfix/main.cf
smtpd_milters = inet:localhost:10026

Add the daemon directive to your /etc/rc.conf file in order to set dkim-milter start at system boot time;

# echo 'milterdkim_enable="YES"' >> /etc/rc.conf

Start the dkim-milter;

# /usr/local/etc/rc.d/milter-dkim start

If you get an error such as;

Starting milterdkim.
dkim-filter: smfi_opensocket() failed
/usr/local/etc/rc.d/milter-dkim: WARNING: failed to start milterdkim

check your log file

# tail -f /var/log/maillog

Sep 18 11:05:30 mail dkim-filter[51326]: Sendmail DKIM Filter: Unable to bind to port inet:10026@localhost: Address already in use
Sep 18 11:05:30 mail dkim-filter[51326]: Sendmail DKIM Filter: Unable to create listening socket on conn inet:10026@localhost
Sep 18 11:05:30 mail dkim-filter[51326]: smfi_opensocket() failed

and change your listening socket port to another one which is not already in use!

Reload Postfix

# postfix reload

check your logs back again

# tail -f /var/log/maillog

Sep 18 11:09:15 nix1 dkim-filter[51343]: Sendmail DKIM Filter v2.8.3 starting (args: -l -u mailnull -P /var/run/milterdkim/pid -x /usr/local/etc/mail/dkim-filter.conf)

If everything is ok. then you need to grab the pre-generated TXT record inside dkim.txt and paste it into your DNS zone record (Watch out for the text wraps and missing quotation marks).

# vi /var/db/dkim/keys/ipsure.com/dkim.txt
dkim._domainkey IN TXT "v=DKIM1; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQ(...)x2ndSUOxbGQhnVbYOD6X49Z9jEtmBJPn1IowIDAQAB"

We may enhance DKIM TXT entries like:

_domainkey.(yourdomain.com). IN TXT "t=y; o=~; r=postmaster@(yourdomain.com)"


t=y means “this domain is currently testing DKIM, verifier side mustn’t treat the messages differently from unsigned e-mails even if the signature fails to be verified”
o=~ means “some e-mails from this domain are signed, some are not”
o=- means “all e-mails from this domain are signed”
r=postmaster@(yourdomain.com) designates responsible e-mail address

After reloading your DNS server it’s time to send a test e-mail to your favorite accounts. If there’s no problem with your setup, you’ll notice an additional “signed-by yourdomain.com” field (click show details) upon receiving the e-mail in your Gmail account. Also a successful DKIM implementation must reveal itself in the message sources;

Authentication-Results: mx.google.com; spf=pass (google.com: domain of test@ipsure.com designates 212.x.x.x as permitted sender) smtp.mail=test@ipsure.com; dkim=pass header.i=@ipsure.com

Authentication-Results: mta175.mail.ac4.yahoo.com from=ipsure.com; domainkeys=neutral (no sig); from=ipsure.com; dkim=pass (ok)

But if you face the faulty results in message sources such as;

domainkeys=neutral (no sig); from=ipsure.com; dkim=permerror (no key)
dkim=neutral (bad format) header.i=@ipsure.com

then I can only suggest you to revise your DNS records and check it by using an online tool such as http://dkimcore.org/tools/dkimrecordcheck.html in order to be sure that you’re not breaking something with DNS.

Basically, below NS query should have been giving a healthy response as follows;

# nslookup -q=txt dkim._domainkey.ipsure.com

Non-authoritative answer:
dkim._domainkey.ipsure.com      text = "v=DKIM1\; g=*\; k=rsa\; p=MIGfMA0GCSqGSIb3DQ(...)x2ndSUOxbGQhnVbYOD6X49Z9jEtmBJPn1IowIDAQAB"

Postfix Inside Jails

If you read this topic in search of a solution to your junk folder trouble growing out of your mass mailing strategies, it means that most probably you must be running separate Postfix (and dkim-milter) instances inside multiple jail environments. If you’re doing so, you may notice that the emails originating from your jail(s) are not signed while the ones from the main host are signed perfectly. This is because dkim-filter accepts the jail as an external host due to its different hostname;

# tail -f /var/log/maillog
Sep 21 17:45:36 vmta dkim-filter[69543]: 439D798BC25 external host vmta.yourdomain.com attempted to send as yourdomain.com
Sep 21 17:45:36 vmta dkim-filter[69543]: 439D798BC25: no signature data

If you have a such issue, follow the steps below to introduce your jail domain name and/or IP address network as external hosts to dkim-milter in jails.

# cd /usr/local/etc/mail/
# touch InternalHosts.txt
# chmod 444 InternalHosts.txt
# vi InternalHosts.txt
# vi /usr/local/etc/mail/dkim-filter.conf

Go to Line 190, uncomment and designate the location of your InternalHosts file;

InternalHosts           /usr/local/etc/mail/InternalHosts.txt
# /usr/local/etc/rc.d/milter-dkim restart
# postfix reload

For further reading about DKIM, visit http://dkim.org

If you’re looking for a complete installation guide of Postfix (Virtual Setup) Dovecot SpamAssassin ClamAV Maia Roundcube (/w MySQL db) on FreeBSD, please see here.

Related Posts with Thumbnails
Subscribe to our RSS feeds Email Subscription via FeedBurner RSS Subscription via FeedBurner
  1. DomainKeys with Postfix Using dk-milter (SMTP-Only)
  2. Dkim-milter is No Longer Available, How to Use OpenDKIM Instead
  3. Postfix (Virtual Setup) Dovecot SpamAssassin ClamAV Maia Roundcube (/w MySQL db) on FreeBSD



Reader Comments

There are currently no reader comments available at this time.

RSS feed for comments RSS feed for comments on this post. TrackBack URL

Leave a comment