FreeBSD utilizes, by default, a version of BIND (Berkeley
Internet Name Domain), which is the most common implementation
of the DNS protocol.
DNS is the protocol through which names are
mapped to IP addresses, and vice versa.
For example, a query for
www.FreeBSD.org
will receive a
reply with the IP address of The FreeBSD
Project's web server, whereas, a query for
ftp.FreeBSD.org
will return the
IP address of the corresponding
FTP machine. Likewise, the opposite can
happen. A query for an IP address can
resolve its hostname. It is not necessary to run a name
server to perform DNS lookups on a
system.
FreeBSD currently comes with BIND9 DNS server software by default. Our installation provides enhanced security features, a new file system layout and automated chroot(8) configuration.
DNS is coordinated across the Internet through a somewhat complex system of authoritative root, Top Level Domain (TLD), and other smaller-scale name servers which host and cache individual domain information.
Currently, BIND is maintained by the Internet Systems Consortium https://www.isc.org/.
To understand this document, some terms related to DNS must be understood.
Term | Definition |
---|---|
Forward DNS | Mapping of hostnames to IP addresses. |
Origin | Refers to the domain covered in a particular zone file. |
named, BIND | Common names for the BIND name server package within FreeBSD. |
Resolver | A system process through which a machine queries a name server for zone information. |
Reverse DNS | Mapping of IP addresses to hostnames. |
Root zone | The beginning of the Internet zone hierarchy. All zones fall under the root zone, similar to how all files in a file system fall under the root directory. |
Zone | An individual domain, subdomain, or portion of the DNS administered by the same authority. |
Examples of zones:
.
is how the root zone is usually
referred to in documentation.
org.
is a Top Level Domain
(TLD) under the root zone.
example.org.
is a
zone under the org.
TLD.
1.168.192.in-addr.arpa
is a zone
referencing all IP addresses which fall
under the 192.168.1.*
IP address space.
As one can see, the more specific part of a hostname
appears to its left. For example,
example.org.
is more
specific than org.
, as org.
is more specific than the root zone. The layout of each part
of a hostname is much like a file system: the
/dev
directory falls
within the root, and so on.
Name servers generally come in two forms: authoritative name servers, and caching (also known as resolving) name servers.
An authoritative name server is needed when:
One wants to serve DNS information to the world, replying authoritatively to queries.
A domain, such as
example.org
, is
registered and IP addresses need to be
assigned to hostnames under it.
An IP address block requires reverse DNS entries (IP to hostname).
A backup or second name server, called a slave, will reply to queries.
A caching name server is needed when:
A local DNS server may cache and respond more quickly than querying an outside name server.
When one queries for
www.FreeBSD.org
, the resolver
usually queries the uplink ISP's name
server, and retrieves the reply. With a local, caching
DNS server, the query only has to be made
once to the outside world by the caching
DNS server. Additional queries will not
have to go outside the local network, since the information is
cached locally.
In FreeBSD, the BIND daemon is called named.
File | Description |
---|---|
named(8) | The BIND daemon. |
rndc(8) | Name server control utility. |
/etc/namedb | Directory where BIND zone information resides. |
/etc/namedb/named.conf | Configuration file of the daemon. |
Depending on how a given zone is configured on the server,
the files related to that zone can be found in the
master
,
slave
, or
dynamic
subdirectories
of the /etc/namedb
directory. These files contain the DNS
information that will be given out by the name server in
response to queries.
Since BIND is installed by default, configuring it is relatively simple.
The default named configuration is that of a basic resolving name server, running in a chroot(8) environment, and restricted to listening on the local IPv4 loopback address (127.0.0.1). To start the server one time with this configuration, use the following command:
#
service named onestart
To ensure the named daemon is
started at boot each time, put the following line into the
/etc/rc.conf
:
There are obviously many configuration options for
/etc/namedb/named.conf
that are beyond
the scope of this document. There are other startup options
for named on FreeBSD, take a look at
the named_
flags in *
/etc/defaults/rc.conf
and
consult the rc.conf(5) manual page. The
Section 12.7, “Using rc(8) Under FreeBSD” section is also a good
read.
Configuration files for named
currently reside in
/etc/namedb
directory
and will need modification before use unless all that is
needed is a simple resolver. This is where most of the
configuration will be performed.
Just as the comment says, to benefit from an uplink's
cache, forwarders
can be enabled here.
Under normal circumstances, a name server will recursively
query the Internet looking at certain name servers until it
finds the answer it is looking for. Having this enabled
will have it query the uplink's name server (or name server
provided) first, taking advantage of its cache. If the
uplink name server in question is a heavily trafficked, fast
name server, enabling this may be worthwhile.
127.0.0.1
will
not work here. Change this
IP address to a name server at the
uplink.
In named.conf
, these are examples
of slave entries for a forward and reverse zone.
For each new zone served, a new zone entry must be added
to named.conf
.
For example, the simplest zone entry for
example.org
can look
like:
The zone is a master, as indicated by the
type
statement, holding its zone
information in
/etc/namedb/master/example.org
indicated by the file
statement.
In the slave case, the zone information is transferred from the master name server for the particular zone, and saved in the file specified. If and when the master server dies or is unreachable, the slave name server will have the transferred zone information and will be able to serve it.
An example master zone file for
example.org
(existing
within /etc/namedb/master/example.org
)
is as follows:
Note that every hostname ending in a “.” is
an exact hostname, whereas everything without a trailing
“.” is relative to the origin. For example,
ns1
is translated into
ns1.
example.org.
The format of a zone file follows:
The most commonly used DNS records:
start of zone authority
an authoritative name server
a host address
the canonical name for an alias
mail exchanger
a domain name pointer (used in reverse DNS)
example.org.
the domain name, also the origin for this zone file.
ns1.example.org.
the primary/authoritative name server for this zone.
admin.example.org.
the responsible person for this zone,
email address with “@”
replaced. (<admin@example.org>
becomes
admin.example.org
)
2006051501
the serial number of the file. This must be
incremented each time the zone file is modified.
Nowadays, many admins prefer a
yyyymmddrr
format for the serial
number. 2006051501
would mean last
modified 05/15/2006, the latter 01
being the first time the zone file has been modified
this day. The serial number is important as it alerts
slave name servers for a zone when it is
updated.
This is an NS entry. Every name server that is going to reply authoritatively for the zone must have one of these entries.
The A record indicates machine names. As seen above,
ns1.example.org
would resolve
to 192.168.1.2
.
This line assigns IP address
192.168.1.1
to the current
origin, in this case
example.org
.
The canonical name record is usually used for giving
aliases to a machine. In the example, www
is aliased to the “master” machine whose name
happens to be the same as the domain name
example.org
(192.168.1.1
). CNAMEs can
never be used together with another kind of record for the
same hostname.
The MX record indicates which mail servers are
responsible for handling incoming mail for the zone.
mail.example.org
is the
hostname of a mail server, and 10 is the priority of that
mail server.
One can have several mail servers, with priorities of
10, 20 and so on. A mail server attempting to deliver to
example.org
would first
try the highest priority MX (the record with the lowest
priority number), then the second highest, etc, until the
mail can be properly delivered.
For in-addr.arpa zone files (reverse DNS), the same format is used, except with PTR entries instead of A or CNAME.
This file gives the proper IP address to hostname mappings for the above fictitious domain.
It is worth noting that all names on the right side of a PTR record need to be fully qualified (i.e., end in a “.”).
A caching name server is a name server whose primary role is to resolve recursive queries. It simply asks queries of its own, and remembers the answers for later use.
Domain Name System Security Extensions, or DNSSEC for
short, is a suite of specifications to protect resolving name
servers from forged DNS data, such as
spoofed DNS records. By using digital
signatures, a resolver can verify the integrity of the record.
Note that DNSSEC only provides integrity via
digitally signing the Resource Records (RRs). It provides neither
confidentiality nor protection against false end-user
assumptions. This means that it cannot protect against people
going to example.net
instead of example.com
.
The only thing DNSSEC does is authenticate
that the data has not been compromised in transit. The
security of DNS is an important step in
securing the Internet in general. For more in-depth details
of how DNSSEC works, the relevant
RFCs are a good place to start. See the
list in Section 29.7.10, “Further Reading”.
The following sections will demonstrate how to enable DNSSEC for an authoritative DNS server and a recursive (or caching) DNS server running BIND 9. While all versions of BIND 9 support DNSSEC, it is necessary to have at least version 9.6.2 in order to be able to use the signed root zone when validating DNS queries. This is because earlier versions lack the required algorithms to enable validation using the root zone key. It is strongly recommended to use the latest version of BIND 9.7 or later to take advantage of automatic key updating for the root key, as well as other features to automatically keep zones signed and signatures up to date. Where configurations differ between 9.6.2 and 9.7 and later, differences will be pointed out.
Enabling DNSSEC validation of queries
performed by a recursive DNS server
requires a few changes to named.conf
.
Before making these changes the root zone key, or trust
anchor, must be acquired. Currently the root zone key is
not available in a file format BIND
understands, so it has to be manually converted into the
proper format. The key itself can be obtained by querying
the root zone for it using dig.
By running
%
dig +multi +noall +answer DNSKEY . > root.dnskey
the key will end up in root.dnskey
.
The contents should look something like this:
Do not be alarmed if the obtained keys differ from this example. They might have changed since these instructions were last updated. This output actually contains two keys. The first key in the listing, with the value 257 after the DNSKEY record type, is the one needed. This value indicates that this is a Secure Entry Point (SEP), commonly known as a Key Signing Key (KSK). The second key, with value 256, is a subordinate key, commonly called a Zone Signing Key (ZSK). More on the different key types later in Section 29.7.8.2, “Authoritative DNS Server Configuration”.
Now the key must be verified and formatted so that BIND can use it. To verify the key, generate a DS RR set. Create a file containing these RRs with
%
dnssec-dsfromkey -f root-dnskey . > root.ds
These records use SHA-1 and SHA-256 respectively, and should look similar to the following example, where the longer is using SHA-256.
The SHA-256 RR can now be compared to the digest in https://data.iana.org/root-anchors/root-anchors.xml. To be absolutely sure that the key has not been tampered with the data in the XML file can be verified using the PGP signature in https://data.iana.org/root-anchors/root-anchors.asc.
Next, the key must be formatted properly. This differs
a little between BIND versions 9.6.2 and
9.7 and later. In version 9.7 support was added to
automatically track changes to the key and update it as
necessary. This is done using
managed-keys
as seen in the example
below. When using the older version, the key is added using
a trusted-keys
statement and updates must
be done manually. For BIND 9.6.2 the
format should look like:
For 9.7 the format will instead be:
The root key can now be added to
named.conf
either directly or by
including a file containing the key. After these steps,
configure BIND to do
DNSSEC validation on queries by editing
named.conf
and adding the following to
the options
directive:
To verify that it is actually working use
dig to make a query for a signed
zone using the resolver just configured. A successful reply
will contain the AD
flag to indicate the
data was authenticated. Running a query such as
%
dig @resolver
+dnssec se ds
should return the DS
RR for the .se
zone.
In the flags:
section the
AD
flag should be set, as seen
in:
The resolver is now capable of authenticating DNS queries.
In order to get an authoritative name server to serve a DNSSEC signed zone a little more work is required. A zone is signed using cryptographic keys which must be generated. It is possible to use only one key for this. The preferred method however is to have a strong well-protected Key Signing Key (KSK) that is not rotated very often and a Zone Signing Key (ZSK) that is rotated more frequently. Information on recommended operational practices can be found in RFC 4641: DNSSEC Operational Practices. Practices regarding the root zone can be found in DNSSEC Practice Statement for the Root Zone KSK operator and DNSSEC Practice Statement for the Root Zone ZSK operator. The KSK is used to build a chain of authority to the data in need of validation and as such is also called a Secure Entry Point (SEP) key. A message digest of this key, called a Delegation Signer (DS) record, must be published in the parent zone to establish the trust chain. How this is accomplished depends on the parent zone owner. The ZSK is used to sign the zone, and only needs to be published there.
To enable DNSSEC for the
example.com
zone depicted
in previous examples, the first step is to use
dnssec-keygen to generate the
KSK and ZSK key pair.
This key pair can utilize different cryptographic
algorithms. It is recommended to use RSA/SHA256 for the
keys and 2048 bits key length should be enough. To generate
the KSK for
example.com
, run
%
dnssec-keygen -f KSK -a RSASHA256 -b 2048 -n ZONE example.com
and to generate the ZSK, run
%
dnssec-keygen -a RSASHA256 -b 2048 -n ZONE example.com
dnssec-keygen outputs two
files, the public and the private keys in files named
similar to Kexample.com.+005+nnnnn.key
(public) and
Kexample.com.+005+nnnnn.private
(private). The nnnnn
part of the file
name is a five digit key ID. Keep track of which key ID
belongs to which key. This is especially important when
having more than one key in a zone. It is also possible to
rename the keys. For each KSK file
do:
%
mv Kexample.com.+005+nnnnn.key Kexample.com.+005+nnnnn.KSK.key
%
mv Kexample.com.+005+nnnnn.private Kexample.com.+005+nnnnn.KSK.private
For the ZSK files, substitute
KSK
for ZSK
as
necessary. The files can now be included in the zone file,
using the $include
statement. It should
look something like this:
Finally, sign the zone and tell BIND
to use the signed zone file. To sign a zone
dnssec-signzone is used. The
command to sign the zone
example.com
, located in
example.com.db
would look similar
to
%
dnssec-signzone -o
example.com -k Kexample.com.+005+nnnnn.KSK example.com.db
Kexample.com.+005+nnnnn.ZSK.key
The key supplied to the -k
argument is
the KSK and the other key file is the
ZSK that should be used in the signing.
It is possible to supply more than one
KSK and ZSK, which
will result in the zone being signed with all supplied keys.
This can be needed to supply zone data signed using more
than one algorithm. The output of
dnssec-signzone is a zone file
with all RRs signed. This output will
end up in a file with the extension
.signed
, such as
example.com.db.signed
. The
DS records will
also be written to a separate file
dsset-example.com
. To use this signed
zone just modify the zone directive in
named.conf
to use
example.com.db.signed
. By default, the
signatures are only valid 30 days, meaning that the zone
needs to be resigned in about 15 days to be sure that
resolvers are not caching records with stale signatures. It
is possible to make a script and a cron job to do this. See
relevant manuals for details.
Be sure to keep private keys confidential, as with all cryptographic keys. When changing a key it is best to include the new key into the zone, while still signing with the old one, and then move over to using the new key to sign. After these steps are done the old key can be removed from the zone. Failure to do this might render the DNS data unavailable for a time, until the new key has propagated through the DNS hierarchy. For more information on key rollovers and other DNSSEC operational issues, see RFC 4641: DNSSEC Operational practices.
Beginning with BIND version 9.7 a new
feature called Smart Signing was
introduced. This feature aims to make the key management
and signing process simpler by automating parts of the task.
By putting the keys into a directory called a
key repository, and using the new
option auto-dnssec
, it is possible to
create a dynamic zone which will be resigned as needed. To
update this zone use nsupdate
with the new option -l
.
rndc has also grown the ability
to sign zones with keys in the key repository, using the
option sign
. To tell
BIND to use this automatic signing and
zone updating for
example.com
, add the
following to named.conf
:
After making these changes, generate keys for the zone
as explained in Section 29.7.8.2, “Authoritative DNS Server
Configuration”, put those
keys in the key repository given as the argument to the
key-directory
in the zone configuration
and the zone will be signed automatically. Updates to a
zone configured this way must be done using
nsupdate, which will take care of
re-signing the zone with the new data added. For further
details, see Section 29.7.10, “Further Reading” and the
BIND documentation.
Although BIND is the most common implementation of DNS, there is always the issue of security. Possible and exploitable security holes are sometimes found.
While FreeBSD automatically drops named into a chroot(8) environment; there are several other security mechanisms in place which could help to lure off possible DNS service attacks.
It is always good idea to read CERT's security advisories and to subscribe to the FreeBSD security notifications mailing list to stay up to date with the current Internet and FreeBSD security issues.
If a problem arises, keeping sources up to date and having a fresh build of named may help.
All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/
Questions that are not answered by the
documentation may be
sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.