## page was copied from Postfix/dkim-milter
## Original article at http://stas.nerd.ro/blog/index.php/read/200

= Introduction =

||<tablestyle="float:right; font-size: 0.9em; width:40%; background:#F1F1ED; margin: 0 0 1em 1em;" style="padding:0.5em;"><<TableOfContents(2)>>||

DomainKeys Identified Mail (DKIM) is a method for E-mail authentication, allowing a person who receives email to verify that the message actually comes from the domain that it claims to have come from. The need for this type of authentication arises because spam often has forged headers.

DKIM uses public-key cryptography to allow the sender to electronically sign legitimate emails in a way that can be verified by recipients.

DKIM also guards against tampering with mail, offering almost end-to-end integrity from a signing to a verifying Mail transfer agent (MTA).

[[http://en.wikipedia.org/wiki/DKIM|Read more on Wikipedia]]

dkim-milter is a milter-based application (dkim-filter) which plugs in to [[Postfix]] to provide DomainKeys Identified Mail service for your mail server. dkim-milter is no longer being developed, and it's original author has forked the source and is now developing opendkim.  For Lucid and later releases, opendkim is preferred over dkim-filter.  The instructions on this page should be the same (just with adjusted package names as needed).


= Installation =

We assume you already successfully installed Postfix MTA, if not, please read the [[Postfix]] dedicated page.

To install '''opendkim''', you need Universe repositories added, if so, use your favorite package manager and install the package.

{{{
sudo aptitude install opendkim opendkim-tools
}}}

'''Important:''' For 12.04 Precise you must install '''opendkim''' from the precise [[https://help.ubuntu.com/community/HelpOnLinking|backports]]. Note that backports are enabled only by using {{{/precise-backports}}} on a given package, so this will not affect any other packages you have installed.

{{{
sudo aptitude install opendkim/precise-backports
sudo aptitude install opendkim-tools/precise-backports
}}}


= Configuration =

'''opendkim''' configuration consists of two files:
{{{
/etc/opendkim.conf
/etc/default/opendkim
}}}

Use your favorite editor to edit those files.
Here's an example of '''/etc/opendkim.conf''' file already edited to suit my needs:
{{{
# 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
# dkim-milter (2.5.2.dfsg-1ubuntu1) hardy:
# Disable new umask option by default (not needed since Ubuntu default
# uses a TCP socket instead of a Unix socket).

# Attempt to become the specified userid before starting operations.
#UserID			105 # 'id postfix' in your shell


# Sign for example.com with key in /etc/mail/dkim.key using
# selector '2007' (e.g. 2007._domainkey.example.com)
Domain			ubuntu.ro
KeyFile			/etc/mail/dkim.key # See bellow how to generate and set up the key
Selector		mail

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

#InternalHosts          /etc/mail/dkim-InternalHosts.txt
# The contents of /etc/mail/dkim-InternalHosts.txt should be
#   127.0.0.1/8
#   192.168.1.0/24
#   other.internal.host.domain.tld
# You need InternalHosts if you are signing e-mails on a gateway mail server
# for each of the computers on your LAN.


###############################################
# Other (less-standard) configuration options #
###############################################
#
# If enabled, log verification stats here
Statistics		/var/log/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.
#ReportInfo		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
}}}

Actually '''/etc/opendkim.conf''' is the most important file. It provides our milter with required information about selector (used for DNS requests and email verifications) and used signing key (the key is used for signing the outgoing emails).

Here's an example of '''/etc/default/opendkim''' This file is used to connect the milter to MTA:
{{{
# Command-line options specified here will override the contents of
# /etc/dkim-filter.conf. See dkim-filter(8) for a complete list of options.
#DAEMON_OPTS=""
#
# Uncomment to specify an alternate socket
# Note that setting this will override any Socket value in dkim-filter.conf
#SOCKET="local:/var/run/dkim-filter/dkim-filter.sock" # Debian default
#SOCKET="inet:54321" # listen on all interfaces on port 54321
SOCKET="inet:8891@localhost" # Ubuntu default - listen on loopback on port 8891
#SOCKET="inet:12345@192.0.2.1" # listen on 192.0.2.1 on port 12345
}}}

In my case, this file needs no additional editing.

Now, to tell the Postfix about the existing milter, and where to connect with it, edit your Postfix main.cf file '''/etc/postfix/main.cf''', and append to its content the following data:
{{{
# DKIM
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
}}}

If you are using already some milter (for example [[Postfix/DomainKeys]]), you can add the new one like this:
{{{
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891,inet:localhost:8892
non_smtpd_milters = inet:localhost:8891,inet:localhost:8892
}}}

= Key generation for dkim-milter and its setup with DNS =

The '''opendkim-tools''' package provides a tool, '''opendkim-genkey''' for creating your key pairs:
{{{
opendkim-genkey -t -s mail -d ubuntu.ro
}}}
This will generate two files: '''mail.private''' which is your private key, and '''mail.txt''' which is your DNS record containing your public key.

The '''-s''' argument supplies the selector (in our case "mail"), the '''-d''' argument supplies the domain, and the '''-t''' argument says that we are running DKIM in [[http://www.dkim.org/specs/rfc4871-dkimbase.html#key-text|test mode]]. This indicates that verifiers shouldn't drop your mail if something's wrong with the signature. Its seems that the majority using DKIM run it in test mode.

Copy your private key in place:
{{{
cp mail.private /etc/mail/dkim.key
}}}
Now create your DNS record as supplied in '''mail.txt''', which should look like this:
{{{
mail._domainkey.ubuntu.ro. IN TXT "v=DKIM1; g=*; k=rsa; p=PpYHdE2tevfEpvL1Tk2dDYv0pF28/f 5MxU83x/0bsn4R4p7waPaz1IbOGs/6bm5QIDAQAB" ; ----- DKIM mail for ubuntu.ro
}}}

= Startup and testing =

Once configuration above was done, the daemon can be started with:
{{{
sudo service opendkim start
}}}
If it doesn't start, search the logs for problems and see what it requires more:
{{{
grep -i dkim /var/log/mail.log
}}}

Instead of using '''sudo service opendkim start''' you can run dkim-filter directly:
{{{
dkim-filter -x /etc/dkim-filter.conf
}}}
If you get the error like: '''dkim-filter: milter socket must be specified'''
Then try manually specifying the socket.  Use this to specify local (which does not match '''/etc/default/dkim-filter''' above):
{{{
dkim-filter -x /etc/dkim-filter.conf -p local
}}}

Now restart the Postfix MTA, and check for email signing:
{{{
sudo service postfix restart
}}}

For testing purposes, I recommend you tools like:
 * http://www.sendmail.org/dkim/tools
 * or just send an email to autorespond+dkim[at]dk.elandsys.com

Testing results should look like this in Gmail:
{{http://stas.nerd.ro/blog/data/dkim-filter.png}}

= Common errors and fixes =
== Missing signature ==
If something is not functioning properly (emails are not being signed) look for errors in the log:
{{{
grep -i dkim /var/log/mail.log
}}}

The following error indicates the filter ran properly however could not match the outgoing email domain with a filter (and thus no signature was generated):
{{{
Nov 21 06:59:56 appname dkim-filter[2911]: 81AA7E688: no signature data
}}}

Consider changing the domain to a wildcard in '''/etc/opendkim.conf''':
{{{
# Sign for example.com with key in /etc/mail/dkim.key using
# selector '2007' (e.g. 2007._domainkey.example.com)
Domain			*
KeyFile			/etc/mail/dkim.key
Selector		mail
}}}

Using a domain of * will require putting the dkim key into EACH domain's DNS zone file for those domains that send email using this server.  The dkim signing will work for your server, but without updating each DNS zone file, the public key will not be found by the recipient mail server.

== Multiple signatures ==
If amavis-new is installed and dkim signs emails multiple times with same domain and selector, is the configuration error likely to be how you feed messages back to postfix from amavis. 

Head to '''/etc/postfix/master.cf''' look for the section starting with:
{{{
127.0.0.1:10025 inet    n       -       -       -       -       smtpd
}}}

Find the option '''-o receive_override_options=''' and add ''',no_milters''' to the end of that line.
A corrected config could look something like this:

{{{
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,no_milters
}}}