Securing your DNS with DNSSEC
Once you understand how DNS works, it’s easy to see why security is required to help control the information within a DNS database. The most fundamental issue with DNS is that its distributed nature, coupled with the way names are resolved into the IP addresses, makes it vital the information be correct.
One key reason DNS is not as secure as it should be is the use of UDP as a network transport. UDP packets do not provide information on the packet source, making it difficult to ensure that the client talking to the DNS server is really who it says it is. This can cause problems from unauthorized DNS registrations to attacks that enable entire domains to be spoofed, leading to traffic being redirected to alternative servers.
This is where DNSSEC can help. It provides secure extensions to the DNS protocol that operate through public-key infrastructure. Clients and servers that expect to supply DNS information must have the correct public key to update the domain. Changes like this normally mean completely changing the infrastructure of the protocol, obviously not an option with such a public system. DNSSEC is therefore backward-compatible with earlier DNS implementations, and the administrator chooses whether to use the functionality to help protect the DNS information.
Most DNS servers are configured to automatically list all the hosts (and their associated information, such as IP addresses) to a client when requested. This can give away potentially damaging information, such as the name of the servers to be used in an attack.
The first stage in preventing this is to use transaction signatures (TSIGs) and the allow-transfer directive to secure communication between the DNS server and other machines. A TSIG is a combination of a secret key string and a hashing algorithm — i.e., when Server A requests information from Server B, it must supply the TSIG and meet the restrictions on the allow-transfer directive for Server B to supply the domain information.
To set up a TSIG, first generate a unique key, which we do with the dnssec-keygen command. Specify the algorithm to use with the key, the size of the key (the number of bits), and the type of key you are generating. For a TSIG, a host key is required. Choosing the right algorithm and key size is dependent on the desired level and type of security. Irrespective of algorithm, the more bits, the better, as this implies a larger and more complex key to crack. For this exercise, we’ll use the HMAC-MD5 key. To create a key, use the following command:
$ dnssec-keygen -a HMAC-MD5 -b 128 -n host shareit.private.dom |
The key generator should automatically use the /dev/random device, if available (it’s part of many Unix distributions), to generate a random string to be used as the key. If it’s not available, you may be asked to type a key (which should be a random string, so go ahead and pound the keyboard with any old rubbish). Once finished, you should have two files:
Kshareit.private.dom.+157+19121.key Kshareit.private.dom.+157+19121.private |
The first file, ending with .key, is your public key. The public key contains the information to be distributed to the servers with which you want to exchange domain information. The second key, ending .private, is the private key. The numbers in the file name indicate the algorithm type and key size.
An examination of the content of the public key file at this time would reveal it contains a simple string for the hashing key:
shareit.private.dom. IN KEY 128 3 157 dlV1EKwOtxquWRX15IdNrg== |
That sequence of random characters is the secret key, which will be needed in a moment.
Next, configure the two hosts, starting with the primary server. The named.conf file should look something like this:
key shareit.private.dom.{ algorithm hmac-md5; secret "dlV1EKwOtxquWRX15IdNrg=="; }; server 192.168.1.2 { keys { shareit.private.dom; }; } zone "private.dom" { type master; file db.private.dom; allow-transfer { key shareit.private.dom. ; }; }; |
The very first part sets up the public key for the domain, and including it here in named.conf isn’t a very secure idea. We’ll look at ways to remedy this shortly.
Next, we specify the domain, set it up as a master domain, and then use the allow-transfer directive to tell the server to allow transfers only to servers that supply the correct key.
Thus, named.conf in the secondary server would look something like this:
key shareit.private.dom.{ algorithm hmac-md5; secret "dlV1EKwOtxquWRX15IdNrg=="; }; server 192.168.1.1 { keys { shareit.private.dom; }; } zone "private.dom" { type slave; master { 192.168.1.1 }; file private.dom.cache; allow-transfer { none; }; }; |
The problem with the above configuration is that many people can read named.conf, as we’re giving away the supposedly secret key right in the file. The solution is to put the domain keys, such as this one, into a separate file; secure that file by making it readable only by root; and then replace the key definition in named.conf to include the keyfile, by removing the inline key definition and adding the following line:
include /etc/bind/shared.keys |
From now on, servers requesting the exchange of the entire domain private.dom from the primary DNS host will get the domain only if they supply the right public key. This is an explicit request to restrict access, meaning most users will have backward compatibility with the old unsecure method but can also secure their domains if they wish.
This is a very simple way of securing the overall domain exchange. BIND 9.3 can also sign an entire domain with a security key, making it easy to verify whether domain records have been changed. In addition, the public key security provided by the DNSSEC extensions can be used to create an entire infrastructure for signing domain information.
>> Support Options, Looking Ahead