DKIM -- short for "DomainKeys Identified Mail" -- is a mechanism that provides integrity controls over parts of an email transmission. More information about the protocol can be found at http://www.dkim.org/, as this article will deal only with the required integration with your DNS.
DKIM is a two-part process: In the first part, the message's originator is responsible for generating a DKIM Signature that is then placed in special headers, such as these:
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=itverx.com.ve;
s=alice; t=1342650894;
bh=pFo6ZYCLWFoBWmva8IlsxprN/QOinqGTGscl1MBI3sQ=;
h=MIME-Version:Sender:In-Reply-To:References:Date:Message-ID:
Subject:From:To:Cc:Content-Type;
b=Fkcgti0ONF9w/F12LwqW1GQjecEZZgohQmQlkDENRQOdWJINF4DaowPc6LM5tAd5/
kM666teylglDIgJnF2ThGEUrnkmavZvPsHuecWc/ZEYl+3NT7/gb46568UWPjXqbFo
zQDzLozzqw+GABj+pXlC2fDBscesx++q5fBw5dPA=`
The message's receiver is then expected to complete DKIM processing by validating the signature. This requires looking up the matching Public Key from the specified domain. For the above example, the process would be equivalent to performing the query depicted below:
bind9# dig txt alice._domainkey.itverx.com.ve
...
;; QUESTION SECTION:;alice._domainkey.itverx.com.ve. IN TXT
;; ANSWER SECTION:alice._domainkey.itverx.com.ve. 86400 IN TXT "v=DKIM1\; g=*\; k=rsa\; p=MIGfM
A0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDqFGebZAOHfSGy9CWtA4Uads0zaXAy8TWtW9uIFbyIkFNC67fQVFVjsxlmcEg1oFNp2CrTY
F1YNh2gB144c+XY5GVM2fGEYAKx3iBxajWTzsx3SvpQtAZ2Bvf2mV+Te+JtlbpxVuiuiW2Alqwhk1ytTWspf/S3bM73XssV+/mh9wIDA
QAB"
...
As can be seen, DKIM uses the DNS as a trusted mechanism to distribute its public keys to the large and diverse population of mail receivers. Sites wishing to use DKIM will require the publication of their public keys in the corresponding DNS zones, so that receivers can access them.
Managing the DKIM Keys
All DKIM implementations include a specific mechanism to generate the required key pair. Please consult your system's documentation to find the right steps for this task, as they will differ.
One popular option for implementing DKIM in Open Source environments is dkim-milter, which integrates easily with Sendmail and Postfix using the Milter interface and is also included in leading Linux distributions. When instructions are properly followed, the key generation process will leave you with two files:
mta# ls -l /etc/mail/dkim/keys/alice.*
-r--r----- 1 dkim-filter smmsp 891 Apr 21 2009 /etc/mail/dkim/keys/alice.private
-r--r----- 1 root smmsp 308 Apr 21 2009 /etc/mail/dkim/keys/alice.txt
These files contain the private and public keys of the pair, respectively. While the private key is required by your signing server, only the public key should be published by your primary name server. The public file, denoted with the .txt extension, contains a valid fragment of a DNS zone, as shown:
mta# cat /etc/mail/dkim/keys/alice.txt
alice._domainkey IN TXT "v=DKIM1; g=*; k=rsa; t=y; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDqFGebZAOHfSGy9CWtA4Uads0zaXAy8TWtW9uIFbyIkFNC67fQVFVjsxlmcEg1oFNp2CrTYF1YNh2gB144c+XY5GVM2fGEYAKx3iBxajWTzsx3SvpQtAZ2Bvf2mV+Te+JtlbpxVuiuiW2Alqwhk1ytTWspf/S3bM73XssV+/mh9wIDAQAB" ; ----- DKIM alice for itverx.com.ve
Other tools provide only the value of the key itself (the fragment between the double quotes or even the contents of the p= field). We recommend that you examine the format and contents of your public key file as this is important for actually adding the public key to your DNS zone file, as explained below. Regardless of which method you use to provision your public DKIM key in the DNS, ensure that afterwards it can be looked up by the receivers (ie, the public key is available in the DNS). Then proceed to test the validity of the signing process.
$INCLUDEing the Keys in your DNS Zone
This is the easiest method to use if your DKIM implementation provides a complete TXT record compatible with the zone syntax file, as in the example shown above. The steps are simple.
On your master nameserver, you will be editing the data file that BIND loads for the zone.
- If you're using Dynamic Updates in your zone, freeze it first by issuing this command:
rndc freeze <your domain name>
2. Add a $INCLUDE directive to the zone, referring to the corresponding .txt file with the public key. In the example below, we use an absolute path but note that you can also opt for a relative path if this suits your configuration style better.
-
Increment the serial number of the zone, to ensure a flawless zone transfer to your slave servers after reloading the zone on your master.
-
If you had frozen the zone in step 1, thaw it now by issuing this command:
rndc thaw <your domain name>
- Reload the zone file by issuing this command:
rndc reload <your domain name>
In Step 2 above, we copied the alice.txt file from our DKIM signing server (mta
) into the directory where we keep our zone files in our primary DNS server (bind9
). We added the following line to the zone file.
$INCLUDE alice.txt
And after the zone reload completes (and the updated zone propagates to all slave servers), the TXT record became available.
Directly Editing your DNS Zone
You might use this method if you prefer to avoid using $INCLUDE in your zone files or if for some other reason, you need to assemble the TXT record. The steps are as follows.
On your master nameserver, you will be editing the data file that BIND loads for the zone.
- If you're using Dynamic Updates in your zone, freeze it first by issuing this command:
rndc freeze <your domain name>
- Add the required TXT record.
-
Increment the serial number of the zone, to ensure a flawless zone transfer to your slave servers after reloading the zone on your master.
-
If you had frozen the zone in step 1, thaw it now by issuing this command:
rndc thaw <your domain name>
- Reload the zone file by issuing this command:
rndc reload <your domain name>
Again, after reloading the zone, the TXT record should become available.
Dynamically Updating your DNS Zone to add the DKIM Public Key
In scenarios where you intend to maintain a large number of DKIM keys published or if your operation uses Dynamic Updates for your DNS zone maintenance, it is possible to use this mechanism to manage your DKIM public keys with ease. This scheme requires fewer steps and can be easily integrated in automated provisioning schemes.
First, you must ensure that you'll be able to add the DKIM public keys. You'll need a configuration stanza like this in your BIND configuration file:
zone "_domainkey.itverx.com" {
type master;
file "db._domainkey.itverx.com";
update-policy {
grant dupdates.itverx.com. subdomain _domainkey.itverx.com. TXT;
};
allow-transfer { key transfer.itverx.com; };
};
If you added or changed your configuration file according to the example above, you'll have to signal BIND to apply any configuration changes after insuring your new configuration file is correct.
rndc reconfig
Afterwards, a simple session with nsupdate
will allow you to simply add keys in real time:
updater# nsupdate -k Kdupdates.itverx.com.+157+59728.private
> update add alice._domainkey.itverx.com. 3600 in txt "v=DKIM1\; g=*\; k=rsa\; CWt..."
> send
> ^D
Removing public DKIM keys in real time is equally easy:
updater# nsupdate -k Kdupdates.itverx.com.+157+59728.private
> update delete alice._domainkey.itverx.com. 3600 in txt
> send
> ^D
And of course, conditional update operations work as expected. In all cases, the changes are reflected right away.