Changes in version 2.2:
If you are not familiar with BIND configuration, I highly recommend that you pick up a copy of DNS and BIND, by Albitz and Liu, published by O'Reilly and Associates.
Please feel free to share any suggestions or bug reports with me. Feedback is always welcome! Send all feedback to robt@cymru.com.
For our purposes, we will assume that our internal network is 7.7.7.0/24, and that our external network is 8.8.8.0/24. Our name server has a NIC in each subnet, with the internal NIC as 7.7.7.1 and the external NIC as 8.8.8.1. It is often the case that the name server is also the firewall, so the addressing scheme and dual NIC configuration likely fits many network topologies.
Ensure that you have the latest version of the BIND. You can obtain the latest version by visiting the Internet Software Consortium BIND site at http://www.isc.org/products/BIND/. The compilation and installation of the BIND is well detailed at this site. This template has been most recently tested with BIND version 9.1.0.
BIND 9.1.0 contains two interesting records in the CHAOS class - version.bind and authors.bind, both type TXT. The version.bind TXT record will return the version of BIND running on the server. The authors.bind TXT record will return a list of the authors of the BIND 9.1.0. While the version.bind TXT record may assist admins, it runs counter to the philosophy of "keep the miscreants guessing." For this reason, it is recommended that you hide these records from external hosts. This is done through a view, and it will be demonstrated in the template below.
You may wish to ensure that your BGP configuration does not dampen the netblocks that contain the DNS root servers. Please consult my Secure BGP Template for further details on this topic.
To view a chroot jail configuration for Solaris 7, click HERE.
To view a chroot jail configuration for FreeBSD, click HERE.
After building the chroot environment, create a small passwd file in each jail. The passwd file should contain only a root account and the BIND user. For the internal BIND jail, call the user intnamed. For the external BIND jail, call the user extnamed. Assign a UID greater than 100 to each named account, and remember to sync up the passwd file with the shadow file (pwconv in Solaris). Do not create passwords for the accounts. Instead, lock them with entries in the shadow file such as this one for the internal BIND:
root:*LK*:6445::::::
intnamed:*LK*:11136::::::
I recommend using a shell that will allow no access, such as /bin/false or my own denial shell, nocando. The nocando denial shell, which includes detailed logging, can be found in the Tools section of my web site. The home directories for these accounts will be the directories we create below.
Next, create two directory structures to contain our configuration files. For example, use /jail/external-bind/var/named for the external BIND and /jail/internal-bind/var/named for the internal BIND. In each directory, create a subdirectory named master for our master zones and slave for our slave zones, if such zones exist. Change the ownership of these subdirectories to the proper named UID, e.g.:
chown -R intnamed:intnamed /jail/internal-bind/var/named
Configure the zone files normally, and place them in the proper subdirectories. Remember to place the internal zone files in /jail/internal-bind/var/named, and the external zone files in /jail/external-bind/var/named. Each subdirectory must also have a hint file (often named db.cache) and a named.conf file. Don't forget to create a loopback zone file for each subdirectory! Details regarding the creation of the hint and zone files can be found in the August 2000 issue of "Inside Solaris," in the article entitled "Configuring BIND 8," by Don Kuenz. See also DNS and BIND, by Albitz and Liu, published by O'Reilly and Associates.
We will now configure the two named configuration files, one for internal DNS and another for external DNS. Pay close attention to the subtle differences between them.
// @(#)named.conf 20 DEC 2000 Rob Thomas robt@cymru.com
// Set up our ACLs
acl "xfer" {
none; // Allow no transfers.
If we have other
// name servers, place them here.
// Note that in the Netherlands, for example,
// the TLD servers 193.176.144.2 and 193.176.144.138
// are allowed to perform zone tranfers
// from the domains under .nl.
};
acl "trusted" {
// Place our internal and DMZ subnets in here
so that
// intranet and DMZ clients may send DNS queries.
This
// also prevents outside hosts from using our
name server
// as a resolver for other domains.
7.7.7.0/24;
8.8.8.0/24;
localhost;
};
acl "bogon" {
// Filter out the bogon networks. These are networks
// listed by IANA as test, RFC1918, Multicast, experi-
// mental, etc. If you see DNS queries or updates with
// a source address within these networks, this is likely
// of malicious origin. CAUTION: If you are using RFC1918
// netblocks on your network, remove those netblocks from
// this list of blackhole ACLs!
0.0.0.0/8;
1.0.0.0/8;
2.0.0.0/8;
10.0.0.0/8;
23.0.0.0/8;
31.0.0.0/8;
69.0.0.0/8;
70.0.0.0/8;
71.0.0.0/8;
72.0.0.0/8;
73.0.0.0/8;
74.0.0.0/8;
75.0.0.0/8;
76.0.0.0/8;
77.0.0.0/8;
78.0.0.0/8;
79.0.0.0/8;
82.0.0.0/8;
83.0.0.0/8;
84.0.0.0/8;
85.0.0.0/8;
86.0.0.0/8;
87.0.0.0/8;
88.0.0.0/8;
89.0.0.0/8;
90.0.0.0/8;
91.0.0.0/8;
92.0.0.0/8;
93.0.0.0/8;
94.0.0.0/8;
95.0.0.0/8;
96.0.0.0/8;
97.0.0.0/8;
98.0.0.0/8;
99.0.0.0/8;
100.0.0.0/8;
101.0.0.0/8;
102.0.0.0/8;
103.0.0.0/8;
104.0.0.0/8;
105.0.0.0/8;
106.0.0.0/8;
107.0.0.0/8;
108.0.0.0/8;
109.0.0.0/8;
110.0.0.0/8;
111.0.0.0/8;
112.0.0.0/8;
113.0.0.0/8;
114.0.0.0/8;
115.0.0.0/8;
126.0.0.0/8;
169.254.0.0/16;
172.16.0.0/12;
191.255.0.0/16;
192.0.2.0/24;
192.168.0.0/16;
198.18.0.0/16;
201.0.0.0/8;
223.255.255.0/24;
224.0.0.0/3;
240.0.0.0/4;
};
// Set options for security
options {
directory "/var/named";
pid-file "/var/named/named.pid";
statistics-file "/var/named/named.stats";
dump-file "/var/adm/named.dump";
query-source address 8.8.8.1;
transfer-source address 8.8.8.1;
// Return a bogus response to miscreants
// who query for our BIND version. Do
not
// use this trick if you are going to use
// the view trick detailed below.
version "Off with your head!";
// Prevent DoS attacks by generating bogus zone
transfer
// requests. This will result in slower
updates to the
// slave servers (e.g. they will await the poll
interval
// before checking for updates).
notify no;
// Generate more efficient
zone transfers. This will place
// multiple DNS records in a DNS message, instead
of one per
// DNS message.
transfer-format many-answers;
// Set the maximum zone transfer time to something
more
// reasonable. In this case, we state
that any zone transfer
// that takes longer than 60 minutes is unlikely
to ever
// complete. WARNING: If you have
very large zone files,
// adjust this to fit your requirements.
max-transfer-time-in 60;
// We have no dynamic interfaces, so BIND shouldn't
need to
// poll for interface state {UP|DOWN}.
interface-interval 0;
listen-on { 8.8.8.1; };
// Listen on our external
interface
// only.
allow-transfer {
// Zone tranfers limited
to members of the
// "xfer" ACL.
xfer;
};
allow-query {
// Accept queries from
our "trusted" ACL. We will
// allow anyone to query
our master zones below.
// This prevents us
from becoming a free DNS server
// to the masses.
trusted;
};
blackhole {
// Deny anything from
the bogon networks as
// detailed in the "bogon"
ACL.
bogon;
};
};
zone "." in {
type hint;
file "db.cache";
};
// Allow queries for the 127/8 network, but not zone transfers.
// Every name server, both slave and master, will be a master
// for this zone.
zone "0.0.127.in-addr.arpa" in {
type master;
file "master/db.127.0.0";
allow-query {
any;
};
allow-transfer {
none;
};
};
zone "ournetwork.net" in {
type master;
file "master/db.ournetwork";
allow-query {
any;
};
};
zone "8.8.8.in-addr.arpa" in {
type master;
file "master/db.8.8.8";
allow-query {
any;
};
};
// Now create a view for the CHAOS class - again, only if
// you are running BIND 9.1.0. The bind zone file will be
// detailed below. Set allow-query to trusted or none,
// depending on your policies.
view "external-chaos" chaos {
recursion no;
zone "." {
type hint;
file "/dev/null";
};
zone "bind" {
type master;
file "master/db.bind";
allow-query {
trusted;
};
allow-transfer {
none;
};
};
};
// @(#)named.conf 20 DEC 2000 Rob Thomas robt@cymru.com
// Set up our ACLs
acl "xfer" {
none; // Allow no transfers.
If we have other
// Note that in the Netherlands, for example,
// the TLD servers 193.176.144.2 and 193.176.144.138
// are allowed to perform zone tranfers
// from the domains under .nl.
};
acl "trusted" {
// Place our internal subnet in here so that
intranet
// clients may send DNS queries.
7.7.7.0/24;
localhost;
};
// CAUTION: If you are using RFC1918 netblocks on your
// network, remove those netblocks from this list of
// blackhole ACLs!
acl "bogon" {
0.0.0.0/8;
1.0.0.0/8;
2.0.0.0/8;
10.0.0.0/8;
23.0.0.0/8;
31.0.0.0/8;
67.0.0.0/8;
68.0.0.0/8;
69.0.0.0/8;
70.0.0.0/8;
71.0.0.0/8;
72.0.0.0/8;
73.0.0.0/8;
74.0.0.0/8;
75.0.0.0/8;
76.0.0.0/8;
77.0.0.0/8;
78.0.0.0/8;
79.0.0.0/8;
80.0.0.0/8;
81.0.0.0/8;
82.0.0.0/8;
83.0.0.0/8;
84.0.0.0/8;
85.0.0.0/8;
86.0.0.0/8;
87.0.0.0/8;
88.0.0.0/8;
89.0.0.0/8;
90.0.0.0/8;
91.0.0.0/8;
92.0.0.0/8;
93.0.0.0/8;
94.0.0.0/8;
95.0.0.0/8;
96.0.0.0/8;
97.0.0.0/8;
98.0.0.0/8;
99.0.0.0/8;
100.0.0.0/8;
101.0.0.0/8;
102.0.0.0/8;
103.0.0.0/8;
104.0.0.0/8;
105.0.0.0/8;
106.0.0.0/8;
107.0.0.0/8;
108.0.0.0/8;
109.0.0.0/8;
110.0.0.0/8;
111.0.0.0/8;
112.0.0.0/8;
113.0.0.0/8;
114.0.0.0/8;
115.0.0.0/8;
126.0.0.0/8;
169.254.0.0/16;
172.16.0.0/12;
191.255.0.0/16;
192.0.2.0/24;
192.168.0.0/16;
198.18.0.0/16;
201.0.0.0/8;
223.255.255.0/24;
224.0.0.0/3;
240.0.0.0/4;
};
options {
directory "/var/named";
pid-file "/var/named/named.pid";
statistics-file "/var/named/named.stats";
dump-file "/var/adm/named.dump";
listen-on { 7.7.7.1; };
// Return a bogus response to miscreants
// who query for our BIND version. Do
not
// use this trick if you are going to use
// the view trick detailed below.
version "Off with your head!";
// Prevent DoS attacks by generating bogus zone
transfer
// requests. This will result in slower
updates to the
// slave servers (e.g. they will await the poll
interval
// before checking for updates).
notify no;
// Generate more
efficient zone transfers. This will place
// multiple DNS records in a DNS message, instead
of one per
// DNS message.
transfer-format many-answers;
// Set the maximum zone transfer time to something
more
// reasonable. In this case, we state
that any zone transfer
// that takes longer than 60 minutes is unlikely
to ever
// complete. WARNING: If you have
very large zone files,
// adjust this to fit your requirements.
max-transfer-time-in 60;
// We have no dynamic interfaces, so BIND shouldn't
need to
// poll for interface state {UP|DOWN}.
interface-interval 0;
forwarders { 8.8.8.1; };
// Send all queries for external hosts to the
external
// named on this same host. The external
named daemon
// will recursively seek the answer to the internal
// query, then return the answer.
allow-transfer {
xfer;
};
allow-query {
trusted;
};
blackhole {
bogon;
};
};
zone "." in {
type hint;
file "db.cache";
};
zone "0.0.127.in-addr.arpa" in {
type master;
file "master/db.127.0.0";
allow-query {
any;
};
allow-transfer {
none;
};
};
zone "internal.ournetwork.com" in {
type master;
file "master/db.internal";
};
zone "7.7.7.in-addr.arpa" in {
type master;
file "master/db.7.7.7";
};
// Now create a view for the CHAOS class - again, only if
// you are running BIND 9.1.0. The bind zone file will be
// detailed below. Set allow-query to trusted or none,
// depending on your policies.
view "external-chaos" chaos {
recursion no;
zone "." {
type hint;
file "/dev/null";
};
zone "bind" {
type master;
file "master/db.bind";
allow-query {
trusted;
};
allow-transfer {
none;
};
};
};
; @(#)db.cache for internal DNS 12 AUG 2000 Rob Thomas robt@cymru.com
. 99999999 IN NS ns1.ournetwork.net.
;
; hotwire the addresses
;
ns1.ournetwork.net. IN A
8.8.8.1
; @(#)db.bind for internal and external DNS 25 JAN 2001 Rob Thomas
robt@cymru.com
;
$TTL 1D
$ORIGIN bind.
@ 1D
CHAOS SOA localhost. root.localhost.
(
2001013101 ; serial
3H
; refresh
1H
; retry
1W
; expiry
1D )
; minimum
CHAOS NS
localhost.
version.bind. CHAOS TXT "BIND 9.1.0-modified"
authors.bind. CHAOS TXT "A very silly query,
don't you think?"
cd /jail/external-bind
/usr/sbin/chroot /jail/external-bind usr/local/sbin/named -u extnamed
By typing the ps -fu extnamed command, you can verify that our external named daemon is running. To start our internal DNS service, type:
cd /jail/internal-bind
/usr/sbin/chroot /jail/internal-bind usr/local/sbin/named -u intnamed
Typing ps -fu extnamed will verify that our external name service is up and running. Typing ps -fu intnamed will verify that our internal name service is up and running.
Once you have /etc/resolv.conf properly configured (use the internal address for the nameserver line), you should be able to launch queries. Test a few basic queries for both internal and external names and addresses. Then test an intranet client to ensure that the forwarding is properly working. If you have secondary name servers, ensure that zone transfers are functional and complete. If possible, test the external name server from an external host to ensure that the ACLs are functional and that logging is working.
Once all testing is successfully completed, modify /etc/init.d/inetsvc to start two named daemons at boot. Comment out the current named lines and insert the following:
# Start external DNS
if [ -f /jail/external-bind/usr/local/sbin/named -a -f /jail/external-bind/usr/local/etc/named.conf
];
then
echo "Starting external BIND server."
(cd /jail/external-bind; /usr/sbin/chroot /jail/external-bind
usr/local/sbin/named -u extnamed)
fi
# Start internal DNS
if [ -f /jail/internal-bind/usr/local/sbin/named -a -f /jail/internal-bind/usr/local/etc/named.conf
];
then
echo "Starting internal BIND server."
(cd /jail/internal-bind; /usr/sbin/chroot /jail/internal-bind
usr/local/sbin/named -u intnamed)
fi
[ Articles ] [ ]
Rob Thomas, robt@cymru.com,