Mail-DKIM and DKIM Proxy

This is the main web site for the software projects Mail-DKIM and DKIM Proxy.

Mail-DKIM is a Perl module that implements the new Domain Keys Identified Mail (DKIM) standard, and the older Yahoo! DomainKeys standard, both of which sign and verify emails using digital signatures and DNS records. Mail-DKIM can be used by any Perl program that wants to provide support for DKIM and/or DomainKeys.

DKIM Proxy is an SMTP-proxy that signs and/or verifies emails, using the Mail::DKIM module. It is designed for Postfix, but should work with any mail server. It comprises two separate proxies, an "outbound" proxy for signing outgoing email, and an "inbound" proxy for verifying signatures of incoming email. With Postfix, the proxies can operate as either Before-Queue or After-Queue content filters.

Mail-DKIM and DKIM Proxy are free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation.

News

2007-07-31 - Mail::DKIM 0.28 available here for testing

Version 0.28 contains a fix for a line-wrapping bug reported on dkim.meulie.net.

2007-07-25 - Mail::DKIM 0.27 available here for testing

In this release I've been working on better support for sender signing policies. I'll be posting it to CPAN in a week or two if no problems are noticed.

2007-05-24 - dkimproxy 0.16 has been released

This version of dkimproxy is supposed to let you control how many processes are running, with the --min_servers and --max_servers command-line options.

Also, if you have 0.25 or better of Mail::DKIM, the signatures will be made "pretty", i.e. line-wrapped to less than 80 characters per line.

2007-05-24 - Mail::DKIM 0.26 now available

The DKIM spec has now been published as RFC 4871. This RFC contains a change in what version number signatures should use. Please update your Mail::DKIM module to 0.26 so that these new "v=1" signatures are recognized and generated.

Requirements

Mail::DKIM requires the following Perl modules:

Dkimproxy is written in Perl. It requires the Mail::DKIM module, found on this page, as well as the following Perl modules:

Download

Download the Mail-DKIM Perl module: Version 0.28.

See what's new in this release.

Dkimproxy is currently beta-quality software, and still under development. Certain circumstances may result in it mangling, discarding, bouncing, or duplicating your email. That said, if you are comfortable with Postfix and willing to give it a try, please do.

Download the current version of DKIM Proxy: Version 0.16.

See what's new in this release.

Dkimproxy has evolved from my earlier project, Dkfilter, which was based on smtpprox and Mail::DomainKeys. My thanks go out to Bennett Todd for providing smtpprox and Anthony D. Urso for providing Mail::DomainKeys.

Installing dkimproxy

The following steps are recommended for installing dkimproxy:

  1. Determine where you want to install dkimproxy's program files, e.g. /usr/local/dkfilter.
  2. "cd" to the directory containing dkimproxy's source code and type ./configure --prefix= followed by the location in which you want to install the filter. E.g.
    ./configure --prefix=/usr/local/dkfilter
    
  3. Run make install to install the program files to the desired directory. If you used /usr/local/dkfilter as the prefix, the filter scripts will be installed in /usr/local/dkfilter/bin and the Perl module files will be in /usr/local/dkfilter/lib.
  4. Create a Unix user/group dedicated to running dkfilter. E.g. dkfilter.
  5. Create a startup/shutdown script for the filter. A sample script (sample-dkim-init-script.sh) is provided... make sure to check, and modify if necessary, the user, group, and directory found in the script. Also, you may need to adjust command-line arguments for starting the filter(s). Then you can copy it to /etc/init.d/dkimproxy and use it like any other init script.

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 is specified with command-line arguments to dkimproxy.out.

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 dkfilter 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; p=MHwwDQYJK ... OprwIDAQAB; t=y"
    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, configure command-line arguments for dkimproxy.out startup:

--keyfile=KEYFILE
this is required; specifies the file containing the private key
--selector=SELECTOR
this is required; specifies the name of the key selector
--domain=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=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
METHOD selects the canonicalization method for signing. Examples are simple, relaxed, relaxed/relaxed. If not specified, the default is simple.
--reject-error
if specified, 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.

e.g.

dkimproxy.out --keyfile=/usr/local/dkfilter/private.key --selector=selector1 \
        --domain=example.org,example.com --method=relaxed \
        127.0.0.1:10027 127.0.0.1:10028

Finally, you need to configure your mail server to filter outgoing, authorized messages only through the dkimproxy.out service on port 10027.

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 from this 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 can be configured to reject messages that fail to verify (though this is not recommended at this time). Otherwise, it will add a header to the message indicating the result of the verification.

Behavior of the inbound proxy is controlled using the following arguments:

--reject-fail
(not recommended at this time) if specified, 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 specified, 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=HOSTNAME
specifies the hostname used in the Authentication-Results header that gets added to a verified message

To manually start the inbound proxy:

dkimproxy.in 127.0.0.1:10025 127.0.0.1:10026
This starts the proxy listening on port 10025 and transmitting to port 10026.

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

Known Issues

Please check the Frequently Asked Questions page if you have a problem. It is possible there is already a known solution to your problem.

Here I will try to document unresolved issues with Mail::DKIM or dkimproxy.

If you notice any problems, let me know so I can add them to this list.

Interoperability Testing

The following email address is configured to auto-respond with DKIM verification results. It uses the dkimproxy implementation as found on this web page.

test@dkimtest.jason.long.name

For best results, place the words dkim and/or test in the subject of your message. This will reduce the likelihood of your message getting quarantined by my spam filters.

Note 1: the above auto-responder responds to the SMTP envelope sender; i.e. it ignores contents of From: and Reply-to: headers when making its reply.

Note 2: the above auto-responder deals with the validity of the signature itself. It does NOT apply any signing policies.

The following auto-responders are offered by others, and will test your signed messages against other implementations:

Support

If you need help with dkimproxy, or with the Perl module (Mail::DKIM), feel free to post in one of these web forums:

Please also post comments, suggestions, and patches, if you have any. I will monitor the forums when I can.

You can also email me directly (jlong@messiah.edu), but be warned I sometimes take a while to respond to email. Someday I might setup a mailing list as well, for this project.