MediaWiki:Welcome to the Howto page/FreeBSD/DNS

From wiki
Jump to: navigation, search

Introduction


This guide will show how to create DNS server inside a FreeBSD jail. Of course FreeBSD comes with a complete DNS environment setup that can be either installed as a package using the pkg_add tool or the ports collection. This article will focus on installing Bind9 using the ports tree inside a jail environment rather then on the base install itself.


The additional value to using BSD based jails on a single server setup is that one has the ability to pseudo physically separate each build from one another. This in turn creates a highly secure yet fully functional virtualized environment which doesn't affect the full system in anyway; meaning if one wants to test new configuration or a new service then it is much easier to get rid of and reinstall without having any impact on 'normal' operation.


Creating the Jail


To create the jail a jail root has been created in the /zfs directory called 'jail' and the jail directory called dns has been created in the path:


/zfs/jail/dns


From there the buildworld environment has been created using:

Test-BSD#cd /usr/src
Test-BSD#make buildworld


This will take approximately 45 minutes to complete depending on the system load and the CPU so it would be a good time to have a coffee break at this point!

The creation of the jail is the next step. First the path and destination directory of the jail will be created and then the buildworld environment will be installed into the jail.

Test-BSD# mkdir -p /zfs/jail/dns
Test-BSD# setenv D /zfs/jail/dns
Test-BSD# mkdir -p $D
Test-BSD# make installworld DESTDIR=$D
Test-BSD# make distribution DESTDIR=$D
Test-BSD# mount -t devfs devfs $D/dev


Once the jail is complete we can configure the rc.conf file to include it and the associated information that the jail will use in order work to specification.

jail_enable="YES"
jail_list="dns" 
jail_dns_rootdir="/zfs/jail/dns"
jail_dns_hostname="ns1.nova-tech.com"
jail_dns_interface="de0" 
jail_dns_ip="192.168.0.149"
jail_dns_devfs_enable="YES"

At this point we have the ability to start the jail however, before doing so a few pre-start checks are required so that services in general don't clash with each other. The interference of a service listening on all IP addresses that the server is using is a potential security risk and must be contained before any further action is needed.


The first part of these checks is to change the ListenAddress on the SSH server. This is so that the SSH service cannot be accessed by simply pointing a client to any 'aliased' IP address on the server and gain entry.


The top part of the /etc/ssh/sshd_config file should look like this:

#Port 22
#Protocol 2
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
ListenAddress 192.168.0.150


After the change has been applied restart the SSH daemon by running:


/etc/rc.conf/sshd restart


From here we can 'start' the jail and check that things are operational and working:

Test-BSD# /etc/rc.d/jail start dns
Configuring jails:.
Starting jails: ns1.nova-tech.com.


And ensure that the system is listed using the jls command:

Test-BSD# jls
   JID  IP Address      Hostname                      Path
     1  192.168.0.149   ns1.nova-tech.com             /zfs/jail/dns


Then we can login and start configuring as needed. Starting with modifying the /etc/hosts file and then the /etc/rc.conf file. As a prerequisite however. to this I first want to install the Nano text editor as it makes life much easier when cutting and pasting text between terminals or applications.


To start with we have to mount the ports collection inside /usr/ports directory in the jail:

Test-BSD# sh
# D=/zfs/jail/dns
# mkdir -p $D/usr/ports
# mount_nullfs /usr/ports $D/usr/ports
# mount | sort
/dev/ad0s1a on / (ufs, local)
/usr/ports on /zfs/jail/dns/usr/ports (nullfs, local)
ZPOOL_1 on /zfs (zfs, local)
devfs on /dev (devfs, local, multilabel)
devfs on /zfs/jail/dns/dev (devfs, local, multilabel)


Then come to building the port itself:

# exit
Test-BSD# jexec 1 tcsh
ns1# cd /usr/ports
ns1# ls
.cvsignore	arabic		emulators	mbone		shells
CHANGES		archivers	finance		misc		sysutils
COPYRIGHT	astro		french		multimedia	textproc
GIDs		audio		ftp		net		ukrainian
INDEX-8		benchmarks	games		net-im		vietnamese
KNOBS		biology		german		net-mgmt	www
LEGAL		cad		graphics	net-p2p		x11
MOVED		chinese		hebrew		news		x11-clocks
Makefile	comms		hungarian	palm		x11-drivers
Mk		converters	irc		polish		x11-fm
README		databases	japanese	ports-mgmt	x11-fonts
Templates	deskutils	java		portuguese	x11-servers
Tools		devel		korean		print		x11-themes
UIDs		distfiles	lang		russian		x11-toolkits
UPDATING	dns		mail		science		x11-wm
accessibility	editors		math		security
ns1# cd */nano
ns1# make install clean


From there the /etc/hosts file looks like this:

ns1# cat /etc/hosts
# $FreeBSD: src/etc/hosts,v 1.16.34.1.2.1 2009/10/25 01:10:29 kensmith Exp $
#
# Host Database
#
# This file should contain the addresses and aliases for local hosts that
# share this file.  Replace 'my.domain' below with the domainname of your
# machine.
#
# In the presence of the domain name service or NIS, this file may
# not be consulted at all; see /etc/nsswitch.conf for the resolution order.
#
#
::1			localhost localhost.my.domain
127.0.0.1		localhost localhost.my.domain
#
# Imaginary network.
#10.0.0.2		myname.my.domain myname
#10.0.0.3		myfriend.my.domain myfriend
#
# According to RFC 1918, you can use the following IP networks for
# private nets which will never be connected to the Internet:
#
#	10.0.0.0	-   10.255.255.255
#	172.16.0.0	-   172.31.255.255
#	192.168.0.0	-   192.168.255.255
#
# In case you want to be able to connect to the Internet, you need
# real official assigned numbers.  Do not try to invent your own network
# numbers but instead get one from your network provider (if any) or
# from your regional registry (ARIN, APNIC, LACNIC, RIPE NCC, or AfriNIC.)
#

192.168.0.149		ns1.nova-tech.com	ns1
192.168.0.149		ns1.nova-tech.com.


...and the /etc/rc.conf file looks like so:

hostname="ns1.nova-tech.com"
named_enable="YES"
named_chrootdir=""
sshd_enable="YES"


Currently the Bind9 environment has already been prepared here and just awaits being built from ports.


Another quick addition is to modify the /etc/resolv.conf file in order to gain DNS access:

nameserver 192.168.0.2


It actually would be a better idea at this point to restart the full system by issuing the:


/sbin/init 6


command in order to have the jail fully functional and the base system listening to the proper IP address.


Building Bind9


The task now is to build Bind9 into the jail. If the reboot was performed above then the ports collection needs to be remounted into the jail otherwise if no restart was performed the process is pretty simple.


First locate the Bind9 port, then issue the make command:

ns1# cd /usr/ports/*/bind9
ns1# make install clean


From here we need to remove the symlinks and recreate the full working Bind9 environment from the chrooted one. To start with let's remove the /etc/namedb link, change the name of the /var/named chroot jail, and copy the /var/named/etc/named folder into /etc:

ns1# cd /etc/
ns1# rm namedb
ns1# cd /var
ns1# mv named named_chroot
ns1# cd /var/named_chroot
ns1# ls
dev	etc	usr	var
ns1# cd etc
ns1# cp -r namedb /etc/


This is now sufficient in order to start the service:

ns1# /etc/rc.d/named start
wrote key file "/etc/namedb/rndc.key"
Starting named.


Now that the service has been started and is fully running we can create some zone files in order to use the system as an authoritative name server other then just a recursive lookup server.

ns1# mkdir named
ns1# cd named
ns1# nano nova-tech.db


From here the zone file looks like so:

;
; BIND data file for example.com
;
$TTL    1d
@       IN      SOA     ns1.nova-tech.com.  mail.nova-tech.com. (
                            2010091101         ; Serial
                                  7200         ; Refresh
                                   120         ; Retry
                               2419200         ; Expire
                                 86400)        ; Default TTL
;
			       		IN      NS      ns1.nova-tech.com.
ns1.nova-tech.com.			IN 	A	192.168.0.149
wiki.nova-tech.com.			IN	A	192.168.0.151


Now a file called named.conf.local will be created in the /etc/namedb directory. The contents of this file contain information pointing to the database file for the zone:

ns1# cd /etc/namedb
ns1# ls
dynamic		named.conf	rndc.key
master		named.root	slave
ns1# nano named.conf.local


The contents of named.conf.local is so:

ns1# cat named.conf.local
//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

    zone "nova-tech.com" {
       type master;
       file "/var/named/nova-tech.db";
    };


This file now needs to be called from the main /etc/namedb/named.conf file and this can be done by adding the lines:

        allow-recursion {
                        127.0.0.1;
                        192.168.0.0/24;
                        };
listen-on       { 192.168.0.149; };
include "/etc/namedb/named.conf.local";


From here restart the service:


/etc/rc.d/named restart


Now we can use the netstat and ps tools in order to see if the named service is up and running:

ns1# netstat -ap udp
netstat: kvm not available: /dev/mem: No such file or directory
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address       (state)
udp4       0      0 ns1.domain             *.*                    
udp4       0      0 ns1.syslog             *.*

ns1# ps -aux | grep named
bind   1359  0.0  0.3 19180 11532  ??  IsJ   1:44PM   0:00.07 /usr/sbin/named -


Since it looks like it is up and running and configured on the appropriate port using the correct layer-4 transport protocol, we can now direct our system to use the internal name service and check if everything is up and running as expected:

nameserver 127.0.0.1

ns1# dig @192.168.0.149 www.google.com

; <<>> DiG 9.6.1-P1 <<>> @192.168.0.149 www.google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62818
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 4, ADDITIONAL: 0

;; QUESTION SECTION:
;www.google.com.			IN	A

;; ANSWER SECTION:
www.google.com.		604779	IN	CNAME	www.l.google.com.
www.l.google.com.	279	IN	A	209.85.229.99
www.l.google.com.	279	IN	A	209.85.229.104
www.l.google.com.	279	IN	A	209.85.229.147

;; AUTHORITY SECTION:
google.com.		172779	IN	NS	ns1.google.com.
google.com.		172779	IN	NS	ns2.google.com.
google.com.		172779	IN	NS	ns3.google.com.
google.com.		172779	IN	NS	ns4.google.com.

;; Query time: 5 msec
;; SERVER: 192.168.0.149#53(192.168.0.149)
;; WHEN: Sat Sep 11 14:15:11 2010
;; MSG SIZE  rcvd: 172


The authoritativeness of the server can also be tested against our domain name:

ns1# dig @192.168.0.149 ns1.nova-tech.com

; <<>> DiG 9.6.1-P1 <<>> @192.168.0.149 ns1.nova-tech.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62367
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;ns1.nova-tech.com.		IN	A

;; ANSWER SECTION:
ns1.nova-tech.com.	86400	IN	A	192.168.0.149

;; AUTHORITY SECTION:
nova-tech.com.		86400	IN	NS	ns1.nova-tech.com.

;; Query time: 0 msec
;; SERVER: 192.168.0.149#53(192.168.0.149)
;; WHEN: Sat Sep 11 14:24:19 2010
;; MSG SIZE  rcvd: 65


The last thing to do before the DNS server is fully functional is point the main server /etc/resolv.conf file towards the newly created jailed named service; and of course test the functionality:

Test-BSD# cat /etc/resolv.conf
domain  nova-tech.com
nameserver      192.168.0.149

Test-BSD# nslookup www.google.com
Server:		192.168.0.149
Address:	192.168.0.149#53

Non-authoritative answer:
www.google.com	canonical name = www.l.google.com.
Name:	www.l.google.com
Address: 209.85.229.99
Name:	www.l.google.com
Address: 209.85.229.104
Name:	www.l.google.com
Address: 209.85.229.147

Test-BSD# nslookup ns1.nova-tech.com
Server:		192.168.0.149
Address:	192.168.0.149#53

Name:	ns1.nova-tech.com
Address: 192.168.0.149


Example Configuration Files