Securing DNS Transactions With Transactional Signatures (TSIG)

Transactional Signatures (TSIG) is a mechanism for authenticating DNS messages as specified in RFC 2845. TSIG allows DNS messages such as zone transfers to be cryptographically signed using a shared secret. It can be used in any DNS transaction as a way to restrict access to certain server functions (e.g. zone transfers, recursive queries, record updates) and can be combined with IP restrictions as well.

This article describes one way of using TSIG to authenticate DNS messages in ISC Bind9.

Creating A TSIG Key File

Here, we generate a shared secret to be distributed to hosts involved in DNS transactions. Let’s have, for example, two hosts:


The following command generates a 512-bit HMAC-SHA512 key:

dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST -r /dev/urandom host1-host2

From the file with a filename similar to host1-host2.private, we extract the key (the string following the label “Key”:


We shall use this string as the shared secret.

On each server, let us create the following file: /etc/named/named.conf.tsigkeys, assuming /etc/named is a valid directory that can be used by Bind. We put the text into this file:

key "tsig-key" {
    algorithm HMAC-SHA512;
    secret "VApI7Kkz9lKCG3oQgxdYi+PRuFliK9ZaVDz2xOdqgQ2DwNHmbrTGEbpG6cjwOYhSmVuqJjHTpUZft1zrFGARzw==";

Copy this file in a secure way to all the servers that will be exchanging DNS transactions. For example, use scp to distribute the file.

Make sure the file is only readable by root and the user under which Bind (i.e. the named daemon) runs.

Add this statement in named.conf, the main Bind configuration file:

include "/etc/named/named.conf.tsigkeys";

In host1, add the following reference to host2 in host1’s named.conf:

server {
    keys { tsig-keys. ;};

Similarly, in host2, add the following reference to host1 in host2’s named.conf:

server {
    keys { tsig-keys. ;};

These entries make sure that DNS transactions between the two hosts are signed.

Access Control

TSIG keys may be specified in ACL definitions and directives such as allow-query, allow-transfer, and allow-update. The key would be denoted in an ACL as key tsig-key.

For example:

acl dns-servers {;;
allow-transfer { ! { !dns-servers; any; }; key tsig-key. ;};

enables transfers to succeed only if the transfer requestes comes from an address in the dns-servers ACL and if it’s signed using the tsig-key key.

To test, use dig:

dig @ axfr

from the server host2 ( With the above command lacking the shared key, you should get a ‘Transfer failed.‘ message and not be able to transfer the zone.

On the other hand, using this:

dig @ axfr -k /etc/named/named.conf.tsigkeys

you should be able to transfer the zone with no errors.

The above procedure was adapted from the following articles: