Mail-DKIM and DKIMproxy

Using DKIMproxy

DKIMproxy can be used to add DKIM support to any environment which uses SMTP to deliver email messages. First, you will need to decide whether you want to use DKIM/DomainKeys for signing outbound messages, verifying inbound messages, or both. You will need to configure your mail server to pass messages for signing or verifying to DKIMproxy, which will process the message and deliver it on to a predetermined SMTP address/port.

If you follow the instructions below, you will have the inbound (signature-verifying) proxy installed as a Before-Queue filter to verify inbound mail received on port 25, and the outbound (signing) proxy installed as an After-Queue filter to sign outgoing mail received on port 587. This means all of your users, when configuring their SMTP server, should specify port 587. Another method of supporting signing and verifying is to configure Postfix to listen on two different IP addresses, configuring one IP address for verification and the other IP address for signing.

Note: Please read and understand the Postfix documentation on content filters before attempting to use dkimproxy with Postfix.

Using DKIMproxy to sign outbound messages

The outbound proxy adds a digital signature to the header of each message it processes. To compute the signature, it needs access to an OpenSSL private key. In addition, in needs to know the name of the key selector being used, and what domain it should sign messages for. This information can be specified in a variety of ways, but first, let's generate a private/public key pair and publish the public key in DNS.

  1. Generate a private/public key pair using OpenSSL:
    openssl genrsa -out private.key 1024
    openssl rsa -in private.key -pubout -out public.key
    
    This creates the files private.key and public.key in the current directory, containing the private key and public key. Make sure private.key is not world-readable, but still readable by the dkim user.
  2. Pick a selector name... e.g. selector1
  3. Put the public-key data in DNS, in your domain, using the selector name you picked. Take the contents of the public.key file and remove the PEM header and footer, and concatenate the lines of the file into one big line. Then create a TXT entry, like this:
    selector1._domainkey IN TXT "k=rsa; t=s; p=MHwwDQYJK ... OprwIDAQAB"
    where selector1 is the name of the selector chosen in the last step and the p= parameter contains the public-key as one long string of characters.

Now, to configure DKIMproxy... create a file named /usr/local/dkimproxy/etc/dkimproxy_out.conf and give it the following content:

# specify what address/port DKIMproxy should listen on
listen    127.0.0.1:10027

# specify what address/port DKIMproxy forwards mail to
relay     127.0.0.1:10028

# specify what domains DKIMproxy can sign for (comma-separated, no spaces)
domain    example.org

# specify what signatures to add
signature dkim(c=relaxed)
signature domainkeys(c=nofws)

# specify location of the private key
keyfile   /usr/local/dkimproxy/private.key

# specify the selector (i.e. the name of the key record put in DNS)
selector  selector1

You will want to edit the following options:

keyfile
this is required; specifies the file containing the private key
selector
this is required; specifies the name of the key selector
domain
this is required; specifies what domain(s) emails are signed for. If you want to sign for multiple domains, specify the domains separated by commas (see example below)
signature
specify dkim to use the newer DKIM signatures; specify domainkeys to use the older Yahoo! DomainKey signatures. If not specified, the default is dkim.
method
METHOD selects the canonicalization method for signing. Examples are simple, relaxed, relaxed/relaxed. If not specified, the default is simple.
reject_error
if 1, and an error occurs while generating a signature, a temporary rejection will be generated, and the sending system will have to try again later. Otherwise, the message will go through without being signing.
sender_map
reads signature options from a file containing one or more domains and their corresponding options; in this case the 'domain', 'selector', and 'keyfile' arguments can be omitted from the main configuration file and specified in the sender map file instead.

For a detailed explanation of each option, look at the dkimproxy.out man page.

To start DKIMproxy with this configuration file, run

dkimproxy.out --conf_file=/usr/local/dkimproxy/etc/dkimproxy_out.conf

This will have DKIMproxy listen on port 10027 and forward received mail to some other SMTP service listening on port 10028.

Finally, you need to configure your mail server to actually use DKIMproxy; i.e. filter outgoing (authorized messages only) through the dkimproxy.out service on port 10027 and receive the results on port 10028.

Using DKIMproxy to verify incoming messages

First off, if you use SpamAssassin, you may not want to use DKIMproxy for verifying messages. SpamAssassin includes a DKIM plugin which uses the same Mail::DKIM module to verify messages as DKIMproxy itself. All you need to do is install the Mail::DKIM module (available on the Download page) and enable the plugin in SpamAssassin's config.

Otherwise...

The inbound proxy scans each message for DKIM and DomainKey signatures, attempting to verify any that it finds. To verify a signature, the proxy will query the sender's DNS for their public key. If the message has a valid signature, the message is "verified." The inbound proxy will add a header to the message indicating the result of the verification. It can also be configured to reject messages that fail to verify (though this is not recommended at this time).

Behavior of the inbound proxy is controlled using a configuration file, or with command-line arguments. Here is a minimal configuration file for the inbound (verifying) proxy:

# specify what address/port DKIMproxy should listen on
listen    127.0.0.1:10025

# specify what address/port DKIMproxy forwards mail to
relay     127.0.0.1:10026

Other options you can use are:

reject_fail
(not recommended at this time) if set to 1, messages without a valid signature from domains with strict "sender signing policies" will be rejected. The sender will get an error message saying "DKIM - fail (bad signature)" or similar. Note: this applies to "hard" fails only. Soft fails, like when the sending domain is "testing" domain keys, or if they don't have a "sign-all" policy published, will still be accepted.
reject_error
if set to 1, and an error occurs while verifying a signature, a temporary rejection will be generated, and the sending system will have to try again later. Otherwise, the message will go through without verification, unaltered.
hostname
specifies the hostname used in the Authentication-Results header that gets added to a verified message

For a detailed explanation of each option, look at the dkimproxy.in man page.

To manually start the inbound proxy:

dkimproxy.in --conf_file=/usr/local/dkimproxy/etc/dkimproxy_in.conf
This starts the proxy listening on the port 10025 as specified in the configuration file.

Now you need to configure your mail server to pass incoming messages through the dkimproxy.in service on port 10025 for verification, and listen on port 10026 for the results.

Get DKIMproxy at SourceForge.net.