DNS
Security Protocols II: DNSSEC
Kerry Thompson
This is the second of two articles examining the latest mechanisms
for securing DNS. In the September 2004 issue of Sys Admin,
I looked at securing dynamic updates and zone transfers with TSIG
keys; in this article, I will look at the DNSSEC protocol for securing
the zone data itself.
In conventional DNS usage, there is no guarantee that the data
received by a name server or client is authoritative or that a name
server is not maliciously providing false information. The DNSSEC
system prevents clients from trusting information that is false.
Under DNSSEC, all data must be authenticated and verified before
it can be trusted. To prove that the data is authoritative and has
not been tampered with, an authoritative source must create and
digitally sign the data.
In the following examples, I'm using ISC BIND version 9.3.0rc2
from www.isc.org -- you will need to use version 9.3.0 of ISC
BIND in order to usefully explore DNSSEC because previous versions
used deprecated DNSSEC record types. If you are compiling this from
the source, you will need to use the "--with-openssl"
option to the ./configure command to enable the cryptographic
functions, and you will also probably want to enable signature chasing
support for the dig command. The commands to build BIND with
these options are:
STD_CDEFINES="-DDIG_SIGCHASE=1"
export STD_CDEFINES
./configure --with-openssl
make
make install
As with the previous article, my test systems have been set up to
serve a test domain "domain.tld" and a reverse domain "1.168.192.in-addr.arpa".
Secure DNS Zones
Making secure updates is good, but how can we ensure that the
results of DNS queries actually came from an authoritative server
and have not been modified in transit? The aim of the DNSSEC protocol
extensions is to make sure DNS data comes from the correct server
and cannot be changed.
To enable DNSSEC for a zone, we first generate two keys for the
zone. These will become the key signing key (KSK) and the zone signing
key (ZSK). For our test domain, use the following commands to generate
the keys:
cd /var/named
dnssec-keygen -r /dev/urandom -a RSASHA1 -b 1024 -n ZONE domain.tld
dnssec-keygen -r /dev/urandom -a RSASHA1 -b 2048 -n ZONE domain.tld
dnssec-keygen -r /dev/urandom -a RSASHA1 -b 1024 -n ZONE 1.168.192.in-addr.arpa
dnssec-keygen -r /dev/urandom -a RSASHA1 -b 2048 -n ZONE 1.168.192.in-addr.arpa
Dnssec-keygen will generate the keys and put them into newly created
key files with cryptic names such as Kdomain.tld.+005+14957.key. Here,
we create a 1024-bit key, which will be used as the ZSK, and a 2048-bit
key for the KSK. The numbers in the key file names designate the algorithm
used to create the key (005 for RSASHA1) and a random 5-digit number
to represent a key ID.
Next, insert these keys into the zone files and generate new signed
zone files. Edit the domain.tld and 1.168.192.in-addr.arpa zone
files and in each add the key file with $include statements. In
the domain.tld file, add the following lines just after the SOA
record:
# 1024-bit ZSK:
$include Kdomain.tld.+005+14957.key
# 2048-bit KSK:
$include Kdomain.tld.+005+61205.key
In the 1.168.192.in-addr.arpa file, add:
# 1024-bit ZSK:
$include K1.168.192.in-addr.arpa.+005+38921.key
# 2048-bit KSK:
$include K1.168.192.in-addr.arpa.+005+07571.key
Run the dnssec-signzone utility to sign the zone with the keys.
This will take the zone file domain.tld and create a new, signed zone
in domain.tld.signed:
dnssec-signzone -r /dev/urandom -t -k Kdomain.tld.+005+61205.key \
domain.tld Kdomain.tld.+005+14957.key
dnssec-signzone -r /dev/urandom -t -k K1.168.192.in-addr.arpa.+005+07571.key \
1.168.192.in-addr.arpa K1.168.192.in-addr.arpa.+005+38921
We use the -k option to specify the 2048-bit KSK to dnssec-signzone.
Note that the names of the zone files are the same as the names of
the DNS zones. If they're different, you need to specify extra
options to dnssec-signzone.
If you look at the newly generated .signed files, you'll
see that they have been filled with lots of extra records, with
types such as NSEC, RRSIG, and DNSKEY. The DNSKEY record contains
a copy of the public key for the zone, RRSIG contains a digital
signature for a resource record (an RR), and NSEC records are used
to provide an authenticated denial of existence for queries to unknown
records.
Now edit /etc/named.conf and change the name of the data file
for the zones to refer to the signed zone file. In my example for
domain.tld and 1.168.192.in-addr.arpa, the named.conf entries become:
zone "domain.tld" IN {
type master;
file "domain.tld.signed";
allow-update { key update_key; };
allow-transfer { key slave_xfers_key; };
};
zone "1.168.192.in-addr.arpa" IN {
type master;
file "1.168.192.in-addr.arpa.signed";
allow-update { key update_key; };
allow-transfer { key slave_xfers_key; };
};
Also, add the option "dnssec-enable" into the options statement
at the top of the named.conf file to enable the DNSSEC extensions:
options {
directory "/var/named";
dnssec-enable yes;
};
Restart named and check syslog for any errors. You should see messages
stating that the signed zone has been loaded, similar to these:
named[910]: zone domain.tld/IN: loaded serial 4 (signed)
At this point, you can also send dynamic updates to add and delete
records in the signed zones. This method is much easier than editing
the original zone file and re-signing the records.
Testing DNSSEC Secure Zones
You can use the dig utility, which comes with BIND to check
that your DNSSEC domain is functioning properly. By including the
+dnssec option, you should receive the additional RRSIG and DNSKEY
records for your query:
dig +dnssec @192.168.1.2 www.domain.tld
The client cannot verify the validity of the returned records unless
it has a copy of the domain key. You can use the "+sigchase"
dig option to perform this verification (refer to the dig
man page for details).
Using Secure Zones for Non-DNSSEC Clients
There are currently no client-side resolver libraries that perform
verification of DNSSEC records. So, how do client systems make use
of the secure zones? The way to do this is to configure a forwarding
DNS server that the client will use for lookups and that will perform
the verification of signed records. Such a server should be "close"
to the client, preferably on the same subnet.
To configure a forwarding server to utilize DNSSEC, simply add
the public keys of the top-level zone of your DNSSEC tree into a
"trusted-keys" section of named.conf and enable DNSSEC
extensions in the options statement. For our test server, the entire
named.conf for a verifying forwarder configuration is:
options {
directory "/var/named";
pid-file "/var/named/named.pid";
forward only;
forwarders {
192.168.1.3;
};
dnssec-enable yes;
dnssec-must-be-secure "domain.tld" yes;
dnssec-must-be-secure "1.168.192.in-addr.arpa" yes;
};
zone "." {
type hint;
file "named.ca";
};
trusted-keys {
# public KSK:
"domain.tld." 256 3 5 "AQPhlHNZPFlrY/evopm....";
"1.168.192.in-addr.arpa." 256 3 5 AQOsRH9Bt9dbA....";
};
I've truncated the data of the key data lines in this case. These
can be quite long in practice. The syntax for the trusted-keys statement
is:
trusted-keys {
<domain> <flags> <protocol> <algorithm> <key-string>;
};
where the key fields can be extracted from the public key file generated
for the respective zone.
The "dnssec-enable" option is necessary to enable the
DNSSEC functionality in the server. The "dnssec-must-be-secure"
option says that the records for the "domain.tld" zone
MUST be verified to be secure by the forwarding server. If the verification
fails, the client will get a SERVFAIL error and no record data.
If dnssec-must-be-secure is set to "no" then the client
will get the query results even if the verification fails.
Restart your forwarding server after changing /etc/named.conf
and check syslog for any error messages.
You should now be able to perform lookups against your forwarding
server and get the server to verify the signatures that it receives
from the authoritative master server. If the forwarder fails to
validate responses from a zone for which trusted keys have been
configured, the client should receive a "SERVFAIL" error
and not be given invalid data that fails verification. You can test
this by shutting down your master server, editing the ".signed"
zone file, and changing a record manually (such as the IP address
of an A record). After starting the master server again (and restarting
the forwarder to clear its cache) queries for the modified record
should receive an error response rather than valid record data.
Note that debugging DNSSEC operations can be difficult due to
the cryptic logging messages. The papers in the Resources section
below should provide help.
Conclusion
In this article, I've shown briefly how to configure DNSSEC-signed
zones to ensure the security of DNS zone data. The full implementation
of DNSSEC is really much more involved. To properly secure a zone,
the parent zone should have copies of the child zone's public
key, which is then signed by the parent's key, and so on, up
to the root zones that should have well-known public keys. This
chain of trust is quite similar in structure to the chain of certificates
used to secure Web servers using the https protocol.
DNSSEC is still quite experimental and changes are still being
finalized by the IETF. The BIND beta code is a little buggy, but
from this you should be able to see how it can be utilized. Some
users have commented that there may be risks in deploying DNSSEC
in production systems as it is not as fault-tolerant as classical
DNS. For example, if the zone keys expire then the entire zone may
become inaccessible.
There have even been proposals for using DNSSEC protocols as a
method of securely distributing keys to form a Public Key Infrastructure
(PKI) system. Using DNSSEC to securely distribute public keys, such
as PGP or ssh keys, is left as an exercise for the reader.
Another thing to note when using DNSSEC is that the network packets
are significantly larger than normal plain DNS. If the 512-byte
packet size is exceeded, systems will start using the TCP transport
rather than UDP. Also, be careful of key expiry and be prepared
to roll over keys. The papers in the References section explain
how to do this.
References
DNSSEC project Web site with many useful resources -- http://www.dnssec.net
BIND v9 ARM (Administrators Reference Manual) -- http://www.nominum.com/content/documents/bind9arm.pdf
DNSSEC Operations HOWTO -- http://www.ripe.net/disi/Course/TechCourse.pdf
Nominum DNSSEC FAQ -- http://www.nominum.com/getOpenSourceResource.php?id=8
Kerry Thompson is a CISSP-certified security consultant for
Open Systems Specialists in Auckland, New Zealand. He has been working
in Unix systems administration and security for many years and regularly
writes papers on IT security. Contact him at kerry@crypt.gen.nz. |