			INSTALLING DKIM-FILTER

OVERVIEW
========

In order to install the dkim-filter as a milter plugin to sendmail you will
need to perform the following steps:

* Compile the dkim-filter program itself.

* Configure the DKIM subsystem for signing and verification.

* Install the milter and configure sendmail to use it.

Note that there is a difference between "dkim-filter" and "dkim-milter".
"dkim-milter" is a package containing a library, a filter and some tools to
be used in testing your DKIM installation.  "dkim-filter" is the filter
program contained in the "dkim-milter" package.

libdkim is a library available as an API for programmers everywhere.  That
API is described in a set of HTML files in the dkim-milter source code
package.

dkim-filter is a plugin that incorporates the libdkim library and which works
with recent versions of sendmail and Postfix.  It does not work with other
MTAs that do not support the milter interface.  For more information about
milter, see <http://www.milter.org> and <http://www.sendmail.org>.

This document describes using dkim-filter with sendmail.  For information
about Postfix, see <http://www.postfix.org>.  For other mail systems, contact
your provider.


COMPILING
=========

The dkim-filter plugin requires sendmail v8.13.0 or later, for required
milter protocol enhancements.  If you don't have a current version, go to
<http://sendmail.org/releases/> for more information.

To build this package you must first have installed or at least have available
the OpenSSL package and libmilter.  The former is available from
<http://www.openssl.org> or in package form from your vendor.  At a minimum
version 0.9.8 is required to meet DKIM requirements.  The application library
libmilter is part of the sendmail Open Source distribution and can be built
and installed from there (ftp://ftp.sendmail.org).

The commands shown below assume a UNIX system with standard build tools
installed.

Steps to compiling the library and the milter:

(1) Download the source from Sourceforge (project name "dkim-milter").

    (a) Go to <http://sourceforge.net/projects/dkim-milter/>, select
        "Download > Browse All Files", and choose the most recent stable
        version.  That will take you to another page where you can select
        the actual file to be downloaded.  The file will be named something
        like <dkim-milter-$ver.tar.gz> where $ver is the version number
        (e.g., "2.4.0") that you want to run.

    (b) Save the chosen distribution file in a convenient directory, for
        example, ~/src/.  How you do this will depend on what browser you
        are using.

    (c) change directory into the the download directory:
	% cd ~/src     # or wherever you chose in step 1b

(2) Unpack the tarball:
	% tar -xzvf dkim-milter-$ver.tar.gz

	Be sure you set $ver to the version number that you downloaded.

(3) Change directories to the release directory (dkim-milter-<version>) that
    was created in step 2.
	% cd dkim-milter-$ver

(4) Edit ./site.config.m4.dist to enable/disable/adjust any options you'd
    like the package to use.  When you're done, move or copy this file to
    devtools/Site/site.config.m4.

(5) Type "sh ./Build" to compile the programs in the package.

(6) Type "sh ./Build install" to install the programs into the appropriate
    system directories.  The locations chosen by the build system will
    depend on your operating system environment.  You can override these
    if you wish by following the instructions in the devtools/README
    directory.  You'll probably need to be the superuser to do so.


INSTALLING AND CONFIGURING DKIM-MILTER
======================================

(1) Choose a selector name.  Current convention is to use a code for the
    current month and year, or just the year.  However, you are free to
    choose any name you wish, especially if you have a selector assignment
    scheme in mind.

(2) Create a public/private keypair for signing:

  (a) Run the script "dkim-genkey".  (A manual page for this tool is
      available and will be installed by the above process if you want to
      see the available options.)

      This will generate a private key in PEM format and a TXT record
      appropriate for insertion into your DNS zone file.  Insert the contents
      of the TXT record file into your DNS zone file, increment the
      serial number, and reload your DNS server so that the new record
      is published.  This is by far the easiest approach.

  (b) If for some reason you cannot use the "dkim-genkey" script, manually
      generate a public and private key.  The steps below are exactly what
      is performed by the dkim-genkey script.

    (i) Run this command:

	    % openssl genrsa -out rsa.private 1024

	This generates a private key and writes it to the file "rsa.private".
	The generated key is in PEM format and is a 1024-bit key, the
	minimum required by the DKIM specification.

    (ii) Run this command:

	    % openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM

	This reads the private key generated in the previous step and
	extracts from it the matching public key.  This is written to the
	file "rsa.public".

    (iii) Add a TXT DNS record containing the base64 encoding of your public
        key, which is everything between the BEGIN and END lines in the
        rsa.public file generated above, with spaces and newlines removed.
        It should be in this form:

	  "g=*; k=rsa; t=y; p=MFwwDQYJ...AwEAAQ=="

        ...using, of course, your own public key's base64 data.  The name of
        the TXT record should be SELECTOR._domainkey.example.com (where
        "SELECTOR" is the name you chose and "example.com" is your domain
        name).  Reload your nameserver so that the record gets published.
	If you are running BIND 9 the command is "rndc reload"; for other
	nameservers, consult your vendor documentation.

	If you are using a large key, you may need to format this record
	in a special way in order for it to be used by your nameserver.
	See the LARGE KEYS section below.

	For a translation of the parameter and value pairs shown here, see
	the DKIM specification (RFC4871) section 3.6.  The specification
	is available in a file in the source code package called
	"rfc4871.txt".  Basically this key record just announces an RSA
	public key and also declares that your site is using this key in
	test mode so nobody should take any real action based on success
	or failure of the use of this key to verify a message.

(3) Store the private key in a safe place.  We generally use a path like
    /var/db/dkim/SELECTOR.key.pem (where "SELECTOR" is the name you chose).
    The /var/db/dkim directory and the associated .pem file should be owned by
    the user that will be executing the filter (preferably not the
    superuser) and be mode 0700 and 0600 respectively.

(4) Start dkim-filter.  You will need at least the "-p" option.  (A manual
    page for this tool is available and will be installed by the above
    process if you want to see the available options.)  The current
    recommended basic set of command line options is:

	-l -p SOCKETSPEC -d DOMAIN -k KEYPATH -s SELECTOR

    ...where SOCKETSPEC is the socket you want the MTA to use (see below),
    DOMAIN is the domain or set of domains for which you want to sign
    mail, KEYPATH is the path to the private key file you generated, and
    SELECTOR is the selector name you picked.  You can tack "-f" on there
    if you want it to run in the foreground instead of in the background
    as a daemon.

    The SOCKETSPEC is a socket where the MTA will attempt to connect
    to your filter.  The filter must therefore be listening there for
    connections from MTAs in order to process messages.  See the
    documentation in libmilter (available with the open source sendmail
    source code) for details on selecting and specifying a socket.

    Instead of command line options, you can also use a configuration file.
    In that case, you only need to tell the filter where the configuration
    file is by specifying a command line option of:

	-x CONFPATH

    ...where CONFPATH is the path to the configuration file you wish to
    use.  A template configuration file can be found in the "dkim-filter"
    directory, named "dkim-filter.conf.sample".



CONFIGURING AND RESTARTING SENDMAIL
===================================

(1) Configure sendmail to use the new milter:

  (a) Choose a socket at which the MTA and the filter will rendezvous
      (see the documentation in libmilter for details).

  (b) Add a line like this example to your sendmail.mc using your desired
      socket specification:

	INPUT_MAIL_FILTER(`dkim-filter', `S=inet:8891@localhost')

  (c) Rebuild your sendmail.cf in the usual way.

(2) Restart sendmail.

	% kill -1 `head -1 /var/run/sendmail.pid`


LARGE KEYS
==========

If you wish to use a large key in DNS, there are some limitations of which
you should be aware.  A TXT record in the DNS consists of a series of
strings each of which don't exceed 255 bytes.  This is a result of the
fact that each string is preceded by a length byte (which, of course,
can't exceed 255).  Furthermore, some DNS implementations don't allow
packets larger than 512 bytes.  Some RSA keys will exceed the 255 byte
limit once encoded with base64, so some special formatting must be
used to make such a record fit.  Failing to do so can cause an incomplete
record to be published or, worse, the nameserver to refuse to serve the
record or even the entire zone.

In the case of the BIND nameserver, there are two syntax rules one can use
to make a large record fit within these boundaries:

1) TXT substrings

	Instead of a record like:

	recname	IN	TXT	"foobarbazblivitalphabravocharliedelta...zulu"

	...one can also do:

	recname	IN	TXT	"foobar" "baz" "blivit" "alpha" ... "zulu"

	(The "..." is mean to indicate continuation and is not a literal set of
	three "." characters.)

	You simply have to break up the large record into smaller strings such
	that no string exceeds 255 bytes.  DKIM implementations will
	reassemble TXT records broken down this way into the full original
	single string before processing them.

2) Line continuations

	It can be difficult for some to edit very long lines of text.
	It's therefore desirable to have a mechanism to break very long
	TXT records down so that they fit nicely within an editor window.
	In BIND, this is done by enclosing the wrapped lines within
	parentheses.  Continuing with the example above, this:

	recname	IN	TXT	"foobar" "baz" "blivit" "alpha" ... "zulu"

	...can also be expressed as:

	recname	IN	TXT	( "foobar" "baz" "blivit" "alpha"
				  "bravo" "charlie" "delta" "echo"
				  ...
				  "yankee" "zulu" )

So using these two techniques, a very large public key could be encoded
in a DNS zone file as follows:

recname	IN	TXT	( "v=DKIM1; g=*; k=rsa; "
 			  "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1Z4F"
 			  "JEMHjJDuBmt25zvYFVejlARZGt1L8f0s1+rLxIPYkfCogQi+Y8"
 			  "oLEg9vvEKnLx9aogZzuNt6j4Sty3LgXxaIwHnMqk0LldbA/mh3"
 			  "wLZb16Wc6btXHON0o3uDipxqGK2iRLTvcgAnNDegseOS+i0aJE"
 			  "nNSl663ywRBp/QKezhUC7cnbqR/H8dz8pEOjeawNN3nexdHGsk"
 			  "+RaafYvCFvU+70CQORcsk+mxb74SwGT2CGHWxVywQA9yrV+sYk"
 			  "JpxaufZLo6xp0Z7RZmbf1eGlCAdhkEy+KYQpQkw2Cdl7iKIK4+"
 			  "17gr+XZOrfFLJ5IwpVK/a19m3BLxADf0Kh3oZwIDAQAB" )


TESTING
=======

To test, send a piece of e-mail through the MTA doing signing for your
domain to sa-test@sendmail.net.  It should be returned to you shortly
showing your message in the body of a new message, including all of
the header changes that were made in transit.  The message you generated
should appear there with a DKIM-Signature: header added, containing
the signature data your dkim-filter added, and an Authentication-Results:
header which the testing machine's dkim-filter added after verifying the
signature.  The value of this header should indicate a "pass".  If it
isn't, something in between has altered your message in a way that
invalidated the signature.  Perhaps you have other filters running which
appended or modified a header.

The reply from the test machine will also itself be signed, and in the
headers of the reply you should see its signature and another
Authentication-Results: header, which should also read "pass".


$Id: INSTALL,v 1.19 2008/04/15 01:59:00 msk Exp $
