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:

host1  10.13.2.5
host2 10.13.2.25

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”:

VApI7Kkz9lKCG3oQgxdYi+PRuFliK9ZaVDz2xOdqgQ2DwNHmbrTGEbpG6cjwOYhSmVuqJjHTpUZft1zrFGARzw==

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 10.13.3.25 {
    keys { tsig-keys. ;};
};

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

server 10.13.3.5 {
    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 {
    10.13.3.5;
    10.13.3.25;
};
....
....
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 @10.13.3.5 somesecuredomain.com axfr

from the server host2 (10.13.3.25). 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 @10.13.3.5 somesecuredomain.com axfr -k /etc/named/named.conf.tsigkeys

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

Continue reading

Using GnuTLS With Apache httpd 2.2

An alternative to using OpenSSL with Apache httpd is to use GnuTLS.  GnuTLS supports TLS 1.2 and TLS 1.1 aside from the cryptographic protocols supported by OpenSSL.  Note, however, that SSL 2.0 is not supported.

GnuTLS also supports secure renegotiation which stops attackers from intercepting and injecting data in a TLS connection.  Secure renegotiation is discussed in RFC5746

The following software are needed to get GnuTLS to work in Apache httpd:

The httpd module that enables GnuTLS in Apache httpd is mod_gnutls. One interesting feature is mod_gnutls’ support for Server Name Indication (SNI) which allows you to configure the web server to use one IP address for multiple TLS-enabled hostnames (just like the configuration for regular name-based virtual hosts).

The above software packages are to be installed in the same order.  These packages might be available for your favorite Linux distribution.  In our case, we simply compile and install from the original sources.

[GARD align=”center”]

Here are the configuration statements used:

GnuMP:

./configure
make
make check
make install

Nettle:

./configure --enable-shared
make
make check
make install

libgpg-error:

./configure
make
make check
make install

libgcrypt:

./configure
make
make check
make install

GnuTLS:

./configure
make
make check
make install

mod_gnutls:

./configure --with-apxs=/opt/apache2/sbin/apxs
make
make install

One thing to add to the Apache httpd configuration is the module specification:

LoadModule gnutls_module modules_dirname/mod_gnutls.so

The documentation for mod_gnutls is straightforward. You can find examples of configurations in the documentation.

A good way to test if your TLS-enabled site works properly is to use the testing tool of SSLLabs: http://www.ssllabs.com/. The test will determine the soundness of your security configuration. Take note that the test uses the features of Firefox 3.6.x to connect to your site. Apparently, this version of Firefox doesn’t seem to support SNI.

If you have trouble making the TLS cache to work for db/gdbm files, check the permissions on the filesystem to see if the web server is allowed to create, read, and write to the cache file. Make sure that Apache httpd, via the Apache Portable Runtime (APR), supports the use of the Berkeley DB and/or the GNU dbm libraries. In our case, we had to compile the APR to support db and gdbm explicitly.

Update:  25 Jul 2011

When installing the digital certificate for your site, make sure the certificate along with a certificate bundle from the issuer are in the proper order.  For example, for linuxunbound.com, the certificate hierarchy looks like this:

Linux Unbound Certificate Hierarchy

Linux Unbound Certificate Hierarchy

 

As for the actual certificate bundle, the certificates should be in the following order:

Digital Certificates In A Bundle

Sequence of Digital Certificates In A Bundle

As you can see above, the linuxunbound.com certificate comes first, followed by the rest in reverse order.  Compare this with the hierarchy as seen by the web browser.

In Apache httpd 2.x, the configuration shall look like this:

<IfModule gnutls_module>
  GnuTLSEnable on
  GnuTLSSessionTickets on
  GnuTLSPriorities NORMAL
  GnuTLSKeyFile /path_to_private/key
  GnuTLSCertificateFile /path_to_public/certificate_bundle.crt
</IfModule>

For performance reasons, a cache should be set up:

GnuTLSCache dbm "/path/to/tls-cache"
GnuTLSCacheTimeout 600

where tls-cache is the cache file. Note that in the above example, we use the BerkeleyDB format.