Enterprise Installation of DNS and BIND
Created: 07/29/2007
General Information
DNS is at the very core of the Internet infrastructure and stands for Domain Name Server. DNS is a distributed, hierarchical database without which we would be typing IP addresses in our browsers instead of something like www.example.com. BIND can serve 1000s of host names and probably 1000s of zones. This how-to is aimed at that kind of installation. I will describe installing, configuring and maintaining BIND on a fresh FreeBSD installation in a secure chroot jail. I will also show how to set up zone files for one zone, multiple zones and a slave for other zones. I will also describe how to maintain your zones in a way that is easy. I will also include some tips. I will not cover caching or forwarding name servers. This document is meant to get you started -- it is not meant to be comprehensive.Requirements
If you know you are going to serve 100s of host names and 100s of zones and be a slave for many zones it is always best to install as much memory as you can purchase. At this level of using DNS you should ALWAYS build another server to use as your secondary. Also, you should make arrangements to have an off-network DNS arrangement with someone that acts as slave to your zones. If your DNS goes down you want some redundancy. You should always make arrangements to backup your configuration files and your zone data files.| # | cd /usr |
| # | ftp ftp://ftp.freebsd.org/pub/FreeBSD/ports/ports-current/ports.tar.gz |
| # | tar zxvf ports.tar.gz |
| # | rm ports.tar.gz |
Installation
Change directory to /usr/ports/dns/bind9| # | cd /usr/ports/dns/bind9 |
| # | make PORT_REPLACES_BASE_BIND9=yes all install clean |
|
+--------------------------------------------------------------------+ ¦ Options for bind9 9.3.4 ¦ ¦ +----------------------------------------------------------------+ ¦ ¦ ¦[X] REPLACE_BASE Replace base BIND with this version ¦ ¦ ¦ ¦[ ] THREADS Compile with thread support (NOT RECOMMENDED!)¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ +-+----------------------------------------------------------------+-¦ ¦ [ OK ] Cancel ¦ +--------------------------------------------------------------------+ |
|
************************************************************************* * _ _____ _____ _____ _ _ _____ ___ ___ _ _ * * / \|_ _|_ _| ____| \ | |_ _|_ _/ _ \| \ | | * * / _ \ | | | | | _| | \| | | | | | | | | \| | * * / ___ \| | | | | |___| |\ | | | | | |_| | |\ | * * /_/ \_\_| |_| |_____|_| \_| |_| |___\___/|_| \_| * * * * BIND 9 requires a good source of randomness to operate. * * It also requires configuration of rndc, including a * * "secret" key. If you are using FreeBSD 4.x, visit * * http://people.freebsd.org/~dougb/randomness.html for * * information on how to set up entropy gathering. Users * * of FreeBSD 5.x or later do not need to do this step. If * * you are running BIND 9 in a chroot environment, make * * sure that there is a /dev/random device in the chroot. * * * * The easiest, and most secure way to configure rndc is * * to run 'rndc-confgen -a' which will generate the proper * * conf file, with a new random key, and appropriate file * * permissions. * * * ************************************************************************* ===> Compressing manual pages for bind9-base-9.3.4 ===> Registering installation for bind9-base-9.3.4 ===> SECURITY REPORT: This port has installed the following files, which may act as network servers and may therefore pose a remote security risk to the system. /usr/sbin/rndc-confgen /usr/sbin/named-checkconf /usr/sbin/dnssec-keygen /usr/sbin/rndc /usr/sbin/lwresd /usr/bin/nsupdate /usr/bin/dig /usr/sbin/named /usr/bin/host /usr/sbin/dnssec-signzone /usr/bin/nslookup /usr/sbin/named-checkzone |
|
# # # |
cd /usr rm -Rf ports/* rm ports.tar.gz |
Create the chroot Environment
We need to now create a FreeBSD 6.x chrooted environment. Perform the following as root user.|
# # # # # # # # # # # # # |
mkdir -p /var/chroot/named/etc/namedb/log mkdir -p /var/chroot/named/dev mkdir -p /var/chroot/named/var/run cd /var/chroot chown -R bind:bind named chmod 700 named cp /etc/localtime /var/chroot/named/etc cp /etc/namedb/named.root /var/chroot/named/etc/namedb/ cd /var/chroot/named/dev mknod zero c 2 12 ln -s /dev/random . mknod null c 2 2 chmod 666 zero random null |
/etc/namedb directory and then create a symbolic link to the /etc directory.|
# # # |
cd /etc mv namedb old.namedb ln -s /var/chroot/named/etc/namedb . |
Configuration
The first thing we want to do is create the rndc key. This is easy to do. While still in the /etc directory:| # | rndc-confgen -a -c /etc/namedb/rndc.conf -k dnsadmin -b 256 |
|
wrote key file "/etc/namedb/rndc.conf" |
|
key "dnsadmin" { algorithm hmac-md5; secret "1fA/Awv2C/SBkF/pAUfjMDjzQdezXQUkHwxR3bQVI5w="; }; |
Note: Don't be lazy and copy the contents you see above. Actually, create the file with your own key.
Next we need to make some additions to the/etc/rc.conf. This will make certain that named will start when FreeBSD reboots.|
named_enable="YES" named_program=/"usr/local/sbin/named" named_chrootdir="/var/chroot/named" named_flags="-c /etc/namedb/named.conf" named_pidfile="/var/run/named.pid" |
|
options { directory "/etc/namedb"; pid-file "/var/run/named.pid"; allow-transfer { 123.123.123.123; }; // Only allow trusted hosts to freely lookup any host allow-query { trusted; }; recursion no; }; |
Note: In the named.conf file a comment can be // . In your zone data files it is different. We will cover the zone data files shortly. The // in the named.conf file is the only comment token you can make and the comment continues to the end of the line.
You should never allow recursion for security and performance reasons on a public facing DNS server unless there is a reason to allow it. Also as a security precaution I would always set up an internal DNS that sits behind a firewall that does name resolution for your client computers on your LAN. This will help prevent cache poisoning. This link gives an excellent description of the problem. There are other measures you can take to secure your DNS.|
controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { dnsadmin; }; }; |
|
key "dnsadmin" { algorithm hmac-md5; secret "551/aS/MXIbmWRZTb6nhUA=="; } |
|
logging { channel systemlog { file "log/named.log"; severity debug; print-time yes; }; channel audit_log { file "log/security.log"; severity debug; print-time yes; }; channel xfer_log { file "log/xfer.log"; severity debug; print-time yes; }; category default { systemlog; }; category security { audit_log; systemlog; }; category config { systemlog; }; category xfer-in { xfer_log; }; category xfer-out { xfer_log; }; category notify { audit_log; }; category update { audit_log; }; category queries { audit_log; }; category lame-servers { audit_log; }; }; |
|
zone "." { type hint; file "named.root"; }; zone "localhost" { type master; file "db.localhost"; }; zone "1.0.0.127.in-addr.arpa" { type master; file "db.127.0.0"; }; |
| # | cd /etc/namedb |
| # | dig > named.root |
|
# cat named.root ; <<>> DiG 9.3.4 <<>> ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43680 ;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;. IN NS ;; ANSWER SECTION: . 517251 IN NS E.ROOT-SERVERS.NET. . 517251 IN NS F.ROOT-SERVERS.NET. . 517251 IN NS G.ROOT-SERVERS.NET. . 517251 IN NS H.ROOT-SERVERS.NET. . 517251 IN NS I.ROOT-SERVERS.NET. . 517251 IN NS J.ROOT-SERVERS.NET. . 517251 IN NS K.ROOT-SERVERS.NET. . 517251 IN NS L.ROOT-SERVERS.NET. . 517251 IN NS M.ROOT-SERVERS.NET. . 517251 IN NS A.ROOT-SERVERS.NET. . 517251 IN NS B.ROOT-SERVERS.NET. . 517251 IN NS C.ROOT-SERVERS.NET. . 517251 IN NS D.ROOT-SERVERS.NET. ;; Query time: 106 msec ;; SERVER: 208.67.222.222#53(208.67.222.222) ;; WHEN: Sat Jul 14 19:14:26 2007 ;; MSG SIZE rcvd: 228 |
|
--db.localhost-- $TTL 604800 @ IN SOA localhost. root.localhost. ( 2007070700 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL IN NS localhost. IN A 127.0.0.1 IN CNAME localdomain. --db.127.0.0-- $TTL 604800 @ IN SOA localhost. root.localhost. ( 2007070700 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL IN NS localhost. 1 IN PTR localhost. |
$TTL - Time To Live, the number of seconds remaining on a cached record before it is purged. For authoritative records the TTL is fixed at a specific length. If a record is cached, the server providing the record will provide the time remaining on the TTL rather then the original length it was given.@ - Is a BIND macro.IN - short for InternetSOA - Start Of Authority recordNS - Name Server recordA - Address recordPTR - Pointer recordMX - Mail Exchanger recordCNAME - canonical name or alias record which points to the canonical or original name of the device.Configuring A Zone You Own
To keep things orderly, you should create a separate zone data file for each zone. In order for this to work you must purchase a name from an Internet Registrar. A list of registrars can be found here: http://www.internic.net/alpha.html at Internic. If you skip this step it is OK but the Internet will not be able to query your zone until the name is registered. You can set up a DNS zone and test it locally before you purchase your name. I will use as my new name myexample.net.|
# # # |
cd /etc/namedb cp db.localhost db.myexample.com cp db.127.0.0 db.192.168.1 |
|
--db.myexample.com-- $TTL 604800 @ IN SOA dns.myexample.com. root.localhost. ( 2007070700 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; list master and slave name servers below IN NS dns.myexample.com. IN NS dns.someother.com. ; My cable modem is internet facing cablemodem IN A 123.456.777.1 ; My firewall is ip'ed behind the the cablemodem which has a public IP address firewall IN A 123.456.777.2 ; My DNS server dns IN A 123.456.777.3 ; My Web server www IN A 123.456.777.4 ; My glue points to my domain myexample.com. IN A 123.456.777.5 ; mail server and aliases mail IN A 123.456.777.6 mailhost IN CNAME mail.myexample.com. myexample.com. IN MX 10 mail.myexample.com. myexample.com. IN MX 20 mail.someother.com. smtp IN CNAME mail.myexample.com. pop3 IN CNAME mail.myexample.com. imap IN CNAME mail.myexample.com. |
MAIL EXCHANGE RECORDS - If you have mail delivered to your domain for example juser@myexample.com, you will need MX records. To accomplish this you can map your domain name to mail.myexample.com with a high priority (low number).REVERSE ZONE DATA FILES - The DNS RFCs state that every host on the Internet should have a reverse lookup. Even though it is a good idea this is not always followed. You should have reverse lookups for mail since many mail servers check for this.|
--db.123.456.789-- $TTL 604800 @ IN SOA dns.myexample.com root.myexample.com. ( 2007070700 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL IN NS dns.myexample.com. IN NS dns.someother.org. 1 IN PTR cablemodem.myexample.com. 2 IN PTR firewall.myexample.com. 3 IN PTR dns.myexample.com. 4 IN PTR www.myexample.com. 6 IN PTR mail.myexample.com. 5 IN PTR myexample.com. |
| # | cd /etc/namedb |
|
options { directory "/etc/namedb"; pid-file "/var/run/named.pid"; allow-transfer { 123.123.123.123; }; // Only allow trusted hosts to freely lookup any host allow-query { trusted; }; recursion no; }; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { dnsadmin; }; }; key "dnsadmin" { algorithm hmac-md5; secret "551/aS/MXIbmWRZTb6nhUA=="; }; logging { channel systemlog { file "log/named.log"; severity debug; print-time yes; }; channel audit_log { file "log/security.log"; severity debug; print-time yes; }; channel xfer_log { file "log/xfer.log"; severity debug; print-time yes; }; category default { systemlog; }; category security { audit_log; systemlog; }; category config { systemlog; }; category xfer-in { xfer_log; }; category xfer-out { xfer_log; }; category notify { audit_log; }; category update { audit_log; }; category queries { audit_log; }; category lame-servers { audit_log; }; }; zone "." { type hint; file "named.root"; }; zone "localhost" { type master; file "db.localhost"; }; zone "1.0.0.127.in-addr.arpa" { type master; file "db.127.0.0"; }; // ZONE myexample.com zone "myexample.com" { type master; file "db.myexample.com"; }; // ZONE reverse zone for myexample.com zone "789,456.123.in-addr.arpa" { type master; file "db.123.456.789"; }; |
Configuring Zones For Multiple Domains
Suppose someone realizes how good you are at DNS and they don't want to mess with it and asks you if you would host their zone. How is this done? They are on a separate network, have a different domain and don't know how to run their own DNS. It is simple you can do this the same way every time. Here are the steps.| # | cd /etc/namedb |
|
zone "someother.org" { type master; file "db.someother.org"; }; zone "543.211.999.in-addr.arpa" { type master; file "db.999.211.543"; }; |
Configuring named To Be A Slave To Other Zones
This is rather simple to do but requires cooperation between the DNS servers. The master server for the zone must allow transfers from the slave server. If you find this does not work when you first try it make sure the master server located somewhere else is allowing transfers from your slave server. Again you will need to edit the named.conf file and add the following lines at the bottom of the file.|
// Forward zone zone "myotherzone.net" { type slave; masters { 222.333.444.2; }; file "db.myotherzone.net"; }; // Reverse zone zone "444.333.222.in-addr.arpa" { type slave; masters { 222.333.444.2; }; file "db.444.333.222.in-addr.arpa"; }; |
Author: Terry Funk
terryfunk at gmail dot com