x
Loading
 Loading
Featured Paper: Xen Virtualization with Novell SUSE Linux
Hello, Guest | Login | Register

Securing DNS

Recent additions to the world’s most popular DNS server help to insure that DNS spoofing-based attacks will become a thing of the past. Find out how to beef up security on your network.

Community Tools
RSS
Recommend This [?]
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...
Users That Liked This [?]
No one yet. Be the first.
Tags:
Tag This!
 No Comments

Security

Like most Internet protocols, the Domain Name System (DNS) began its life without many built-in security mechanisms. DNS is, after all, a global, public naming service, so you don’t normally care who queries your name server for data in the zones that you are responsible for maintaining.

The Unix world (including Linux) generally used BIND, the Berkeley Internet Name Domain software, to handle the resolution of domain names to IP addresses (and vice versa). Microsoft has its own implementation of a domain name server, first included in Windows NT 4.0 and now shipped in Windows 2000. While neither BIND nor the Microsoft DNS Server were particularly secure, BIND was open source and evolved quickly to include new security mechanisms for countering the malicious attacks that became more prevalent when DNS’s vulnerabilities were realized.

One of those security mechanisms, first introduced in BIND 8.2, was TSIG (Transaction Signatures). Later, Microsoft released Windows 2000, which uses a dialect of TSIG to secure dynamic updates between Windows 2000 clients and name servers. (Unfortunately, this isn’t a dialect spoken by BIND yet, and it’s not clear which version will support it. For more information on running BIND in a mixed environment, see the article “The Ties That BIND” (http://www.linux-mag.com/2001-03/bind_01.html) in the March 2001 issue of Linux Magazine.) BIND 9 supports TSIG even more completely, allowing administrators to secure almost any communication between two name servers. The techniques in this article counter a variety of attacks that could render a DNS server unable to do its job.

In this article, we’ll look at how TSIG works and how to use it with your BIND 9 name server(s). We’ll assume you already have your name server(s) up and running but that you don’t necessarily understand the more obscure features of BIND 9. We’ll also assume you are familiar with basic BIND configuration. If you’re not, please check out the article “Using DNS” in the September 2000 issue of Linux Magazine. You can find it on the Web at http://www.linux-mag.com/2000-09/dns_01.html.

A Little History

Let’s look back a bit to the days of BIND 4. The only security mechanism BIND 4 name servers supported was IP address-based access lists, and you could only use them to restrict zone transfers. For some time, that was arguably all you needed.

But as the Internet became a wilder and woollier place, the Internet Engineering Task Force (IETF) extended DNS to add security features. In particular, the DNS Security Extensions (DNSSEC), described in RFC 2535 (http://www.ietf.org/rfc/rfc2535.txt), introduced cryptographic data integrity checking and source authentication to DNS. To provide these, DNSSEC uses asymmetric cryptography, better known as public key encryption.

Unfortunately, while asymmetric cryptography is great for solving key distribution problems, it brings with it a big problem of its own; it’s computationally intensive (and consequently fairly time-consuming). This means it is impractical for resolvers and dynamic updates. Applications that use resolvers need their queries processed as quickly as possible, and servers that send or receive dynamic updates need to handle those updates promptly.

The IETF recognized this shortcoming in DNSSEC and developed Transaction Signatures, an alternate, lightweight security mechanism for use specifically by resolvers and dynamic updates. TSIG (pronounced “tee-sig”) is codified in RFC 2845 (http://www.ietf.org/rfc/rfc2845.txt). Instead of slow asymmetric encryption, TSIG uses a relatively fast one-way hash function, making it quite suitable for use in even the most time-critical transactions and on the busiest name servers.

TSIG Theory

TSIG takes advantage of some mathematical magic called a one-way hash function. One-way hash functions, also known as cryptographic checksums or message digests, calculate fixed-sized outputs from arbitrarily large inputs. While that’s not particularly magical (basic checksums do that), what makes it unique is that each bit in the output (called a hash value), depends upon the value of each and every bit of the input, however long. If even a single bit of input were changed, it would hash to a dramatically — and unpredictably — different hash value.

TSIG uses the popular MD5 hash function in a “keyed” mode dubbed HMAC-MD5. When used in a keyed mode, the hash value the function produces depends not only on every bit of the input, but also on every bit of a key also specified as input.

In TSIG, a DNS message (query, response, dynamic update) is run through HMAC-MD5. A key, shared between the two endpoints of the transaction (e.g., between an updater and the name server receiving the update), is also used as input. The resulting hash value is placed in a new resource record called a TSIG record, which is added to the DNS message.

The format of the TSIG record isn’t really important; the record is a “meta-record,” which is added to a DNS message automatically by the sender and stripped off (and verified) by the receiver. So you’d never add a TSIG record to a zone data file, for example. The only place you’d see one is in the output of a diagnostic tool like dig or a network-tracing tool like tcpdump. Understanding what’s in the TSIG record is important, though. In addition to the computed hash, it is composed of the key name and the time signed.

Key Name: It’s important that the recipient of a TSIG-signed DNS message know which key to use to verify it, so the signer includes the key’s name (which looks like a domain name) as the owner of the TSIG record.

Time Signed: Without some knowledge of when the DNS message was signed, the receiver couldn’t detect replay attacks. In a replay attack, an attacker sniffs out a legitimate DNS message (such as a dynamic update) and then maliciously replays it at a later date. For example, you might run software that automatically updates the domain name of your Web server to point to the address of the least loaded of several replicas. To do this, the software might periodically send an update deleting the old address record and a subsequent update to add a new one. Without a timestamp, an attacker could simply resend the “delete” update without a corresponding “add” update at a later time. To prevent this attack, the TSIG record includes a timestamp that tells the receiver when the message was signed. The receiver checks to make sure the timestamp is close to the current time (within the allowable fudge period, also part of the TSIG record; for BIND, this is always five minutes).

Since the recipient of the message checks the signature time against its reckoning of the current time, it’s important that the clocks on the computers at either end of the transaction be synchronized. One of the easiest ways to keep the computers’ clocks synchronized is to run Network Time Protocol (NTP) servers on both computers. (See http://www.eecis.udel.edu/~ntp for more information.)

The verification of a TSIG record establishes two things: that a holder of the correct TSIG key signed the DNS message and that the message wasn’t modified after it was signed. To put it simply, a signer (or modifier) without the correct key will not be able to produce the right hash value. TSIG doesn’t, however, do anything to ensure the privacy of a DNS message; the message is still sent in the clear.

Configuring Your Name Servers

Now we need to define the key on both name servers. The easiest way to do this is to add a key statement to the named. conf file on each name server:


key bubbles-buttercup.test.example. {
   algorithm hmac-md5;
   secret ?iPUE21TwhxfZj/RPLw86Lw==?;
};

For TSIG keys, the algorithm is always hmac-md5. Quotes aren’t necessary around the key name or the secret, though they’re permitted.

Since the key data is, as the name of the sub-statement implies, a secret, we should make sure that not everyone can read it. We can either remove world-read permission from named.conf or, if that won’t fly with our users, we can move the key statement to its own file and include it in named.conf using the include statement:


include “/etc/named.keys”;

Next, we configure the master name server to restrict zone transfers to those clients presenting the right TSIG key:


zone “test.example” {
   type master;
   file “db.test.example”;
   allow-transfer { keybubbles-buttercup.test.example.;};
};

Next, we configure the slave to present the right key when requesting a zone transfer:


zone “test.example” {
   type slave;
   masters{ 10.0.0.1 key bubbles-buttercup.test.example.;};
   file “bak.test.example”;
};

If the slave is loading several zones from the master, we can use a server statement to tell the slave to use the same key to sign all requests to the master:


server 10.0.0.1 {
   keys { bubbles-buttercup.test.example.; };
};

Testing TSIG

After setting things up, we can test to see if our restrictions are working using BIND 9’s version of dig.Figure One shows what happens when we try to transfer test.example from the master without specifying a TSIG key. Note that without the right TSIG key, we can’t transfer the zone.




Figure One: Attempting a Zone Transfer Without Key


% dig @10.0.0.1 axfr test.example.

; <<>> DiG 9.2.0rc1 <<>> @10.0.0.1 axfr test.example.
;; global options: printcmd
; Transfer failed.

Figure Two shows the very different results we get if we specify the TSIG key with the -y option.




Figure Two: Performing Zone Transfer With the Right Key


% dig @10.0.0.1 axfr test.example. -y bubbles-buttercup.test.example.:iPUE21TwhxfZj/RPLw86Lw==
; <<>> DiG 9.2.0rc1 <<>> @10.0.0.1 test.example. -y
bubbles-buttercup.test.example.:iPUE21TwhxfZj/RPLw86Lw==
;; global options: printcmd
test.example. 86400 IN SOA ns1.test.example. root.test.example. 2 3600 900 2592000 3600
test-bigmo. 0 ANY TSIG HMAC-MD5.SIG-ALG.REG.INT. 998956857 300 16 oFNPoxisCI36UqvxSpRl3Q== 55321 NOERROR 0
test.example. 86400 IN NS ns1.test.example.
test.example. 86400 IN TXT “External”
ns1.test.example. 86400 IN A 10.0.0.1
test.example. 86400 IN SOA ns1.test.example. root.test.example. 2 3600 900 2592000 3600
test-bigmo. 0 ANY TSIG HMAC-MD5.SIG-ALG.REG.INT. 998956857 300 16 EsRlIux5kPeQJlfTl5w0Kw== 55321 NOERROR 0
;; Query time: 337 msec
;; SERVER: 10.0.0.1#53(10.0.0.1)
;; WHEN: Mon Aug 27 17:59:57 2001
;; XFR size: 6 records

The -y option takes as an argument the name of the key, followed by a colon, and then the key data in base 64. If you look carefully at the output of the zone transfer, you’ll even see the TSIG record.

Using TSIG to Secure Dynamic Updates

Now that we’ve secured zone transfers between your authoritative name servers, let’s go on to something more interesting: securing dynamic updates.

Dynamic updates require cryptographic authentication. A dynamic update, as defined in the specification RFC 2136 (http://www.ietf.org/rfc/rfc2136.txt), may be forwarded from name server to name server before reaching its ultimate destination (the primary name server for the zone to be changed). Each time a dynamic update is forwarded, its source IP address changes, making address-based authorization useless.

A TSIG-signed dynamic update, on the other hand, bears the signature of the updater in a record in the DNS message itself. Forwarding the update has no effect on this authentication information.

Restricting Updates to Your Zone

We’ve already generated and configured a TSIG key in our previous example; creating and configuring a TSIG key to be used for dynamic updates is no different. Once you’ve properly configured a TSIG key, you can use it in a zone statement as an argument to an allow-update sub-statement, like the following example:


key bubbles-buttercup.test.example. {
   algorithm hmac-md5;
   secret ?iPUE21TwhxfZj/RPLw86Lw==?;
};

key blossom.test.example. {
   algorithm hmac-md5;
   secret ?/dkdYjLoO8GdrJK/wgxMBQ==?;
};

zone “test.example” {
   type master;
   file “db.test.example”;
   allow-transfer {keybubbles-buttercup.test.example.;};
   allow-update { key blossom.test.example.; };
};

(TSIG keys used with dynamic update are often named for the client sending the dynamic update rather than for the two endpoints.)

This allows an updater using the key blossom.test.ex-ample. to make any changes he wants to the test.example zone. If you think that sounds like a lot of control, you’re right. Allowing someone to make arbitrary changes to your zone can be awfully dangerous. Fortunately, BIND 9 name servers have update-policy — a new, finer-grained authorization mechanism for dynamic updates.

A zone’s update-policy sub-statement defines a list of rules. These rules specify which TSIG keys can change which records in the zone. The sub-statement has the syntax:


(grant | deny) identity nametype name [types]

The grant or deny specifies whether a name server receiving an update matching this particular rule should allow or deny the update. The identity is the name of the key used to sign the update. The nametype is one of the following:

name: Matches when the domain name being modified is the same as the name field.

subdomain: Matches when the domain name being modified is a subdomain of (i.e., ends in) the name in the name field.

wildcard: Matches when the domain name being modified matches the wildcard statement in the name field.

self: Matches when the domain name being modified is the same as the name in the identity field.

The optional types field can contain any value resource record type (except NXT), or multiple types, separated by white space. You can also use ANY as shorthand for “all types except NXT.”

The rules in an update-policy sub-statement are evaluated in the order in which they appear; the first one that matches a dynamic update determines whether the update is granted or denied. Any update-policy ends with an implicit deny all.

So to restrict the blossom.test.example. key to modifying just the domain name blossom.test.example, we could use the following zone statement:


zone “test.example” {
    type master;
    file “db.test.example”;
    allow-transfer{key bubbles-buttercup.test.example.;};
    update-policy {
        grantblossom.test.example. selfblossom.test.example.;
    };
 };
 

Even though the rule looks redundant, (listing blossom. test.example. twice) BIND 9’s parser insists on seeing a parameter after the nametype.

To limit the key to modifying just the domain name test.example, we could use the following zone statement:


zone “test.example” {
    type master;
    file “db.test.example”;
    allow-transfer{key bubbles-buttercup.test.example.;};
    update-policy {
       grant blossom.test.example. name test.example.;
    };
 };
 

The identity field can also include a wildcard:


zone “test.example” {
    type master;
    file “db.test.example”;
    allow-transfer{key bubbles-buttercup.test.example.;};
    update-policy {
      grant blossom.test.example. name test.example.;
      grant *.test.example. self *.test.example. A;
    };
 };
 

This lets blossom.test.example. modify any of test.example’s records, while any TSIG key ending in test.example can modify address records attached to the domain name.

Note that all of this configuration is necessary only on your zone’s primary master name server. The only configuration necessary on the zone’s slave name server is to turn on update forwarding. Unless you’re absolutely sure that all of your updaters will send their updates directly to your zone’s primary master name server, you’ll need to enable update forwarding on the slaves with the allow-update-forwarding sub-statement:


zone “test.example” {
    type slave;
    masters{ 10.0.0.1key bubbles-buttercup.test.example.;};
    file “bak.test.example”;
    allow-update-forwarding { any; };
 };
 

This instructs your slave name servers to forward dynamic updates to the zone’s master name server, which is perfectly okay if you’re only using TSIG-signed updates.

Sending Signed Dynamic Updates

Now that we know how to allow a particular signer to update particular records, how do we actually send signed dynamic updates? One relatively easy way is to use nsupdate, part of the BIND 9 distribution.

nsupdate works a little like nslookup: you run the program, specifying some command-line options, and enter an interactive mode. In nslookup’s interactive mode, you specify the various attributes of a query. In nsupdate’s interactive mode, you specify the various attributes of a dynamic update.

To send a TSIG-signed dynamic update, you can specify the key on the command line with the -y option. The -y option of nsupdate takes the same arguments that dig’s does: the name of the key, followed by a colon, then the base 64 encoding of the key data. If you used dnskeygen to generate the TSIG key, you can specify the name of the file that contains the key as the argument to the -k option:


% nsupdate -k Kblossom.test.example.+157+00000.private
 

Finally, you can specify the key from nsupdate’s interactive mode using the key command. At the > prompt, type: keynamesecret where the secret is in base 64 encoding.

The other important commands are:

send: Sends the update you’ve specified. You can also enter a blank line to send the update.

server: Specifies the name server to send the dynamic update to. If you don’t specify a name server, nsupdate will try to determine which name server to send the update to. It first establishes which zone the domain name you’re updating is in, then looks up the SOA record for that zone and assumes that the SOA record’s MNAME field contains the domain name of the zone’s primary master name server.

update add domain-name ttl type data: Adds a resource record with the specified domain name owner, time to live, type, and data. Note that you must specify a time to live: there is no default setting.

update delete domain-name [type [data]]: Deletes any resource records with the specified domain name owner and type (if specified) and data (if specified).

So to add a new TXT record to test.example with a signed update, we could use the commands in Figure Three (pg. 43).




Figure Three: Adding a Record


% nsupdate -k Kblossom.test.example.+157+00000.private
> update add test.example. 86400 IN TXT “Mojo bites!”
> send

To delete all records attached to buttercup.test.example, we could use the commands in Figure Four.




Figure Four: Deleting Records


nsupdate
> key blossom.test.example. /dkdYjLoO8GdrJK/wgxMBQ==
> update delete buttercup.test.example.
> send

Note that it’s probably wiser to use the -k option than the -y option, since the -y option leaves the key data exposed to anyone running ps on the system.

In addition, here’s a tip for troubleshooting problems with nsupdate: nsupdate normally does its work silently, so use the -d (debug) option to see what’s going wrong.

If you’re interested in sending signed updates programmatically, check out the latest development version of Michael Fuhr’s Net::DNS Perl module, available from http://www.fuhr.org/~mfuhr/perldns/.

Keepin’ It Safe…

Your name servers’ zone transfers and dynamic updates are now substantially more secure. A cracker would find it much harder to hijack a zone transfer or spoof a dynamic update, and the computational cost to your name servers is minimal.




Resources

BIND 9 Home Page: http://www.isc.org/products/BIND/bind9.html

RFC 2535: Domain Name System Security Extensions: http://www.ietf.org/rfc/rfc2535.txt

RFC 2845: Secret Key Transaction Authentication for DNS (TSIG): http://www.ietf.org/rfc/rfc2845.txt

RFC 2136: Dynamic Updates in the Domain Name System: http://www.ietf.org/rfc/rfc2136.txt

NET::DNS Perl Module: http://www.fuhr.org/~mfuhr/perldns





Cricket Liu is coauthor of DNS and BIND and the forthcoming DNS on Windows 2000. He can be reached at cricket@verisign.com.

Read More
  1. Enhance Security with Port Knocking
  2. Linux Magazine Annual Security Survey 2007
  3. Secure Remote Access from Your Desktop
  4. Protecting Linux Systems
  5. Keeping a Watchful Eye with OpenNMS

Comments on Securing DNS

No comments yet.

Sorry, the comment form is closed at this time.

ActivSupport
Linux Magazine has chosen ActivSupport as IT consultants.
Sponsored Links