≡ Menu

Bind Security: Transaction Signatures (TSIG) Configuration

Q. How do I configure BIND9 name serves with TSIG (Transaction SIGnature) mechanism to secure server-to-server communication? How do I use secret key transaction authentication for DNS (bind nameservers)?

A. Transaction signatures (TSIG) is a mechanism used to secure DNS messages and to provide secure server-to-server communication (usually between master and slave server, but can be extended for dynamic updates as well). TSIG can protect the following type of transactions between two DNS servers:

  • Zone transfer
  • Notify
  • Dynamic updates
  • Recursive query messages etc

TSIG is available for BIND v8.2 and above. TSIG uses shared secrets and a one-way hash function to authenticate DNS messages. TSIG is easy and lightweight for resolvers and named.

How it works?

  1. Each name server adds a TSIG record the data section of a dns server-to-server queries and message.
  2. The TSIG record signs the DNS message, proving that the message’s sender had a cryptographic key shared with the receiver and that the message wasn’t modified after it left the sender.
  3. TSIG uses a one-way hash function to provide authentication and data integrity.

Our sample setup:

  • Master nameserver: ns1.theos.in –
  • Slave nameserver: ns2.theos.in –
  • BIND configuration is stored in /etc/bind/ directory.
  • Zone data is stored in /etc/bind/named.conf file.

How do I configure TSIG?

Type the following command on master nameserver (ns1.theos.in) to create the shared keys, using the dnssec-keygen program, which creates two files, both containing the key generated.
# dnssec-keygen -a HMAC-MD5 -b 128 -n HOST rndc-key
Sample output:


List all files, enter:
# ls -l

total 52
-rw-r--r-- 1 root root  237 2009-01-06 12:16 db.0
-rw-r--r-- 1 root root  271 2009-01-06 12:16 db.127
-rw-r--r-- 1 root root  237 2009-01-06 12:16 db.255
-rw-r--r-- 1 root root  353 2009-01-06 12:16 db.empty
-rw-r--r-- 1 root root  256 2009-01-06 12:16 db.local
-rw-r--r-- 1 root root 1506 2009-01-06 12:16 db.root
-rw------- 1 root root   52 2009-01-25 14:13 Krndc-key.+157+64252.key
-rw------- 1 root root   81 2009-01-25 14:13 Krndc-key.+157+64252.private
-rw-r--r-- 1 root bind 1302 2009-01-25 14:13 named.conf
-rw-r--r-- 1 root bind  165 2009-01-06 12:16 named.conf.local
-rw-r--r-- 1 root bind  358 2009-01-25 14:02 named.conf.options
-rw-r----- 1 bind bind   77 2009-01-24 20:37 rndc.key
-rw-r--r-- 1 root root 1317 2009-01-06 12:16 zones.rfc1918


  • -a Specify the encryption algorithm.
  • -b Specify the key size.
  • -n Specify the nametype. A nametype can be a ZONE, HOST, ENTITY, or USER. Usually, you need to use HOST or ZONE such as theos.in

The above dnssec-keygen program created two files as follows. Both .key and .private files are generated for symmetric encryption algorithms such as HMAC-MD5, even though the public and private key are equivalent:

  • Krndc-key.+157+64252.key – Contains the public key. The .key file contains a DNS KEY record that can be inserted into a zone file.
  • Krndc-key.+157+64252.private – Contains the private key. The .private file contains algorithm-specific fields.

Using TSIG – master server configuration

Run the following command and note down the Key:
# cat Krndc-key.+157+64252.private
Sample output:

Private-key-format: v1.2
Algorithm: 157 (HMAC_MD5)
Key: 0jnu3SdsMvzzlmTDPYRceA==
Bits: AAA=

Open /etc/bind/tsig.key file, enter:
# vi /etc/bind/tsig.key
Now you need to create tsig.key file on master server as follows:

key "TRANSFER" {
          algorithm hmac-md5;
          secret "0jnu3SdsMvzzlmTDPYRceA==";
# Slave server IP # 1
server {
        keys {
# If you have 3rd slave server with IP
#server {
#        keys {
#                TRANSFER;
#    };

First block is nothing but keys. TSIG keys are configured using the keys substatements. The keys substatements inform a name server to sign queries and zone transfer requests sent to a particular remote name server. In our case the above substatement informs the master server, to sign all requests to the host slave server with the key called TRANSFER. The server statement’s keys clause to tell the slave name server to sign all zone transfer requests and queries sent to its master server and vice verse. Save and close the file. Open named.conf file, enter:
# vi /etc/bind/named.conf
Append the following line:

include "/etc/bind/tsig.key";

Save and close the file. Restart named:
# rndc reload
# service named restart

Using TSIG – slave server configuration

Create /etc/bind/tsig.key on slave server, enter:
# vi /etc/bind/tsig.key
Append following config:

key "TRANSFER" {
	algorithm hmac-md5;
	secret "0jnu3SdsMvzzlmTDPYRceA==";
# Master server IP
server {
	keys { TRANSFER; };

Save and close the file. Append following to named.conf:

include "/etc/bind/tsig.key";

Restrict zone transfers only to those signed with a specific key

On the master name server, you can restrict zone transfers only to those signed with a specific key such as TRANSFER. open named.conf
# vi /etc/bind/named.conf
You must restrict zone transfers to those signed with the TRANSFER key as follows:

zone "theos.in" {
        type master;
        file "/etc/bind/zones/master.theos.in";
        allow-transfer {  key TRANSFER; };

Save and close the file. Restart / reload the bind server:
# rndc reload
# service named restart

Verify TSGI

Watch your master BIND dns server log file or system log file, enter:
# tail -f /var/log/messages
# tail -f /var/log/syslog
# grep 'theos.in/IN' /var/log/syslog
Sample output:

Jan 26 13:43:11 rose named[9170]: client transfer of 'theos.in/IN': AXFR-style IXFR started: TSIG transfer
Jan 26 13:43:11 rose named[9170]: client transfer of 'theos.in/IN': AXFR-style IXFR ended

You should able to see similar message on slave server:

Jan 26 19:18:33 txvip1 named[17899]: client received notify for zone 'theos.in': TSIG 'transfer'
Jan 26 19:18:33 txvip1 named[17899]: zone theos.in/IN: Transfer started.
Jan 26 19:18:33 txvip1 named[17899]: transfer of 'theos.in/IN' from connected using
Jan 26 19:18:34 txvip1 named[17899]: zone theos.in/IN: transferred serial 2008071011: TSIG 'transfer'
Jan 26 19:18:34 txvip1 named[17899]: transfer of 'theos.in/IN' from end of transfer

Suggested readings:

  • man dnssec-keygen
  • BIND 9 Administrator Reference Manual
Share this tutorial on:

Your support makes a big difference:
I have a small favor to ask. More people are reading the nixCraft. Many of you block advertising which is your right, and advertising revenues are not sufficient to cover my operating costs. So you can see why I need to ask for your help. The nixCraft, takes a lot of my time and hard work to produce. If you use nixCraft, who likes it, helps me with donations:
Become a Supporter →    Make a contribution via Paypal/Bitcoin →   

Don't Miss Any Linux and Unix Tips

Get nixCraft in your inbox. It's free:

{ 17 comments… add one }
  • Jere January 27, 2009, 2:13 pm

    Cool, thats pretty easy!
    Thank you!

  • mostafa January 27, 2009, 4:54 pm

    very small and very effective it’s the first time for me to understand this

    thanx very much

  • Tapas Mallick January 28, 2009, 10:05 am

    Nice and lucid document to understand and implement. I would like to request you to post same kind of document for “Dynamic DNS with DHCP” and “Secure NTP”.


  • Danny February 14, 2009, 6:39 pm

    I’m trying to impliment this, but when I restart named, it says it can’t find the tsig.key file, I’ve quadruple checked for any typo’s

    Any clues (I’m tearing my hair out!!)

    • Niels Dettenbach July 2, 2015, 9:11 am

      Double check your unix file permission rights of tsig.key (try to make a chmod 666 tsig.key – but for test purposes only!) and possible further access restrictions by additional security mechs configured within your OS installation (i.e. acls, selinux etc.).

      …and if your named is running within a chroot, be aware of the changed pathes fitting the chroot environment your named is “running in”.

  • nixCraft February 14, 2009, 7:23 pm

    Do you run bind in chrooted jail?

  • Danny February 14, 2009, 7:29 pm

    Not sure I fully understand the question, but it’s on a VPS so I guess the answer’s probably yes

  • Alejandro March 14, 2009, 8:16 pm

    It Works. OpenBSD 4.4 (master chrooted) and Debian Lenny (slave chrooted).

    Your website is very useful !

    Thank You Very Much.

  • ashok reddy January 31, 2010, 7:27 am

    Wonderful document !

    Super simple steps.. Thanks much

    Have a gr8 day.

    Ashok reddy

  • Babu Satasiya March 3, 2010, 7:34 pm

    nice to have secure zone transfer and you made it simpler for all. Thank you.

  • GUIgao Pang November 2, 2011, 9:18 am

    Looking at a very simple configuration, but in two server configuration, respectively, after the completion of the test found that always tip NotAuth is this why?

    04:28:42.285594 IP > 1993+ A? http://www.test.qq. (29)
    04:28:42.286449 IP > 41773 [2au] A? http://www.test.qq. (117)
    04:28:42.286589 IP > 52125 [2au] NS? . (105)
    04:28:42.288131 IP > 41773 NotAuth- 0/0/2 (123)
    04:28:42.288382 IP > 1993 ServFail 0/0/0 (29)
    04:28:42.289374 IP > 52125 NotAuth- 0/0/2 (111)

  • hamida June 13, 2012, 9:38 pm

    it was useful thank you.

  • Rocky June 14, 2012, 9:59 am

    Hi Vivek,

    Which OS and bind version are you using at production environment?


  • VJ May 2, 2013, 8:15 pm

    neatly explained.. came in handy ..!

  • Jonas Pedersen September 25, 2014, 1:57 pm

    Good clean tut. But at slave zone configurations example could be nice.
    Here is a example of mine config
    zone “test.com” {
    type slave;
    masters {; };
    file “/etc/bind/db.test.com”;
    allow-notify {; };
    allow-query { any; };
    allow-transfer { key TRANSFER; };

  • Tom December 27, 2015, 8:31 am

    Hm, I might be wrong, but to me you mix up the rndc and TSIG keys: rndc is the tool to remotely manage Bind9, which got nothing to do with TSIG. The rndc key is already there (see your ls), so you don’t need to generate it. – Your steps are correct regarding TSIG, it is just unclear, why you call it rndc.

  • sergiu June 14, 2016, 12:50 pm

    Why are you using private keys in bind conf file? It should be the public key and not private key. Private keys are kept safe on the generated machine…

    # cat Krndc-key.+157+64252.private

    instead of

    # cat Krndc-key.+157+64252.key

    correct me if i’m wrong…

Security: Are you a robot or human?

Leave a Comment

You can use these HTML tags and attributes: <strong> <em> <pre> <code> <a href="" title="">

   Tagged with: , , , , , , , , , ,