--- title: "DKIM with BIND9" slug: "aa-00725" description: "DKIM -- short for \"DomainKeys Identified Mail\" -- is a mechanism that provides integrity controls over parts of an email transmission." tags: ["dkim"] updated: 2026-09-25T10:24:53Z published: 2026-09-25T10:24:53Z canonical: "kb.isc.org/aa-00725" --- > ## Documentation Index > Fetch the complete documentation index at: https://kb.isc.org/llms.txt > Use this file to discover all available pages before exploring further. # Adding DKIM Records with BIND9 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://dkim.org/](http://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 must publish 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. @(Info)(Keep your Private Key secure)(Keep in mind that the Private key must be kept secure and never shared, as this compromises the effectiveness of DKIM and allows third parties to sign mail in your domain's behalf.) One popular option for implementing DKIM in Open Source environments is [dkim-milter](http://sourceforge.net/projects/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. 1. If you're using Dynamic Updates in your zone, freeze it first by issuing this command: ``` rndc freeze ``` 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. 1. Increment the serial number of the zone to ensure a flawless zone transfer to your slave servers after reloading the zone on your master. 2. If you had frozen the zone in step 1, thaw it now by issuing this command: ``` rndc thaw ``` 1. Reload the zone file by issuing this command: ``` rndc reload ``` 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 will become 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. 1. If you're using Dynamic Updates in your zone, freeze it first by issuing this command: ``` rndc freeze ``` 1. Add the required TXT record. @(Info)(Don't forget to add the _domainkey subdomain after the key selector name)(For an example of syntax, see the examples above. Note the lack of a trailing dot so that BIND automatically appends the zone $ORIGIN.) 1. Increment the serial number of the zone to ensure a flawless zone transfer to your slave servers after reloading the zone on your master. 2. If you had frozen the zone in step 1, thaw it now by issuing this command: ``` rndc thaw ``` 1. Reload the zone file by issuing this command: ``` rndc reload ``` 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 into 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 ensuring 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. @(Info)(Note the additional zone definition)(In this third example above, unlike the first two, the _domainkey.itverx.com zone has been delegated/separated from the main itverx.com zone so that it can have update controls configured independently of the parent zone.)