Signing mail with DKIM

Signing mail with DKIM

This tutorial will demonstrate how you can sign your outgoing emails with DKIM (DKIM is based on Yahoo’s Domain keys and Cisco’s Identified Internet mail, It is defined in RFC 4871.)

The goal of this tutorial is to have postfix sign all mails for multiple domain names, including mail that originates from PHP’s mail function, or any other that passes the Postfix or “Postfix / Sendmail” MTA.

Debian Lenny is my Operating System, Debian’s dkim-filter’s package will sign the mail, and Debian’s Postfix package will be our MTA
1- About DKIM / How it works.

Just like SSL, DKIM uses a private key and a public key to encrypt messages.

in SSL (and DKIM) messages encrypted with the private key are only decrypted by the public key and the messages encrypted by the public key can only be decrypted by the private key.

The private key is (as in SSL) stored on the server ONLY, this is why it is private, and disclosing it to anyone else defeats the purpose, and the public key, in DKIM is stored IN DNS for the receiving server to obtain with a simple DNS request to the nameservers…

A text record in DNS will have the selector as the record name, and the key as record value.

Anyone can decrypt the message by looking up the DNS record, then using that to decrypt the message, the idea is based on the following logic.

The Logic: the sender managed to encrypt this message, so the sender must be the authentic domain owner to be able to encrypt with the private key.

2- Installing DKIM

On my Debian Lenny machine with Postfix installed

apt-get install postfix dkim-filter

3- generating Private and Public keys

Now, with our dkim-filter package, dkim-genkey is automatically installed

So our domains are example1.com example2.com example3.com and example4.com, we want to sign all emails for all mentioned domain names, In our example, multiple domains on our server will use the same public and private keys !

dkim-genkey -d example1.com -t -s dkmail

dkmail that you see at the end is the selector, you can have many selectors for more than one mail server where you do not want to share the private key between servers.

in the above, we are generating a public and a private key into 2 files in the current directory, although the command includes a domain name, the keys can be used for any set of domain names really, so not to worry about that, Now, let us create a directory to store the Private Key, and move the private key to it

mkdir /var/dkim_keys
mv dkmail.private /var/dkim_keys/dkim.private

The public key is stored in the file dkmail.txt, the contents of that file are 1 line that is as follows

dkmail._domainkey IN TXT "v=DKIM1; g=*; k=rsa; t=y; p=MIGfMA0GC...AQAB" ; ----- DKIM dkmail for anyoneofyourdomains.com

While this is a typical TXT record in BIND for example, adding this to your DNS will depend on your provider, for example when using godaddy, you can click add TXT record in your DNS manager, and enter the following into the 3 provided fields

the TXT name should be

dkmail._domainkey

The TXT value should be (The dots denote a longer string, this is just an example)

v=DKIM1; g=*; k=rsa; t=y; p=MIGfMA0GC...AQAB

And the TTL should be left at

1 hour

Now, once you hit OK, you can use any linux machine that has the DIG command to make sure your changes are already visible on the internet by issuing

dig dkmail._domainkey.anyoneofyourdomains.com TXT

You should see your public key as a result, once you do, you can move on to the next steps.

Now, Edit the file /etc/default/dkim-filter and add the following line at the bottom

SOCKET="inet:8891@localhost"

this will make the application listen on port 8891 which we will use with postfix

The other config file is /etc/dkim-filter.conf

in that file i have the following settings, you can change that if you like, my file uses the DKIM-FILTER to sign multiple domain names with the same private key, the public key is applied to all domain name DNS of all 4 domains

# 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			example1.com,example2.com,example3.com,example4.com
KeyFile		/var/dkim_keys/dkim.private
Selector		dkmail


# Common settings. See dkim-filter.conf(5) for more information.
AutoRestart		yes
Background		yes
Canonicalization	simple
DNSTimeout		5
Mode			sv
SignatureAlgorithm	rsa-sha256
SubDomains		no
#ASPDiscard		no
#Version		rfc4871
X-Header		no

###############################################
# Other (less-standard) configuration options #
###############################################
# 
# If enabled, log verification stats here
#Statistics		/var/run/dkim-filter/dkim-stats
#
# KeyList is a file containing tuples of key information. Requires
# KeyFile to be unset. Each line of the file should be of the format:
#    sender glob:signing domain:signing key file
# Blank lines and lines beginning with # are ignored. Selector will be
# derived from the key's filename.
#KeyList		/etc/dkim-keys.conf
#
# If enabled, will generate verification failure reports for any messages
# that fail signature verification. These will be sent to the r= address
# in the policy record, if any.
#SendReports		yes
#
# If enabled, will issue a Sendmail QUARANTINE for any messages that fail
# signature verification, allowing them to be inspected later.
#Quarantine		yes
#
# If enabled, will check for required headers when processing messages.
# At a minimum, that means From: and Date: will be required. Messages not
# containing the required headers will not be signed or verified, but will
# be passed through
#RequiredHeaders	yes

Now, in your postfix installation, add the following lines at the bottom of the /etc/postfix/main.cf file

# DKIM
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

Now, you should restart both postfix and dkim-filter

/etc/init.d/dkim-filter restart  
/etc/init.d/postfix restart  

Now, if you send an email to Yahoo mail, or Gmail, you can view the headers and make sure that your DKIM state is pass, if not you should recheck.

Note that SPF goes very well with DKIM and should also be implemented

1- Where are log files for help…

Links for this inp progress article

http://packages.debian.org/source/lenny/dkim-milter

http://packages.debian.org/lenny/dkim-filter

http://www.topdog.za.net/postfix_dkim_milter

http://www.elandsys.com/resources/sendmail/dkim.html

https://help.ubuntu.com/community/Postfix/DKIM

https://help.ubuntu.com/community/Postfix/DomainKeys

https://help.ubuntu.com/community/Postfix

http://www.howtoforge.com/postfix-dkim-with-dkim-milter-centos5.1

http://www.sendmail.com/sm/wp/dkim/

http://www.howtoforge.com/forums/showthread.php?p=234174

http://www.howtoforge.com/set-up-dkim-for-multiple-domains-on-postfix-with-dkim-milter-2.8.x-centos-5.3

http://www.howtoforge.com/forums/showthread.php?p=231268

http://howtoforge.org/set-up-dkim-on-postfix-with-dkim-milter-centos-5.2

http://howtoforge.org/forums/showthread.php?t=26219