Chapter 13. Setting up DNS Part 1: ProjReality's name server

Our next goal is to set up DNS on our internet. The last time we accessed the webserver, we typed in its IP address into Firefox. After we set up DNS, we will be able to type in www.projreality.sam (and eventually other addresses) into Firefox and have them show up correctly.

A useful (and more in-depth) reference for the material in this chapter is [Aitchison05]

We will start by creating the nameserver for the projreality.sam domain. We will be using BIND on Linux for all of our nameservers.

First, clone Linux-Minimal.vdi to ns1-projreality-sam.vdi . Create a VM called "ns1.projreality.sam" using that hard disk. Set up the VirtualBox networking (refer to Figure 1.2), plus a temporary NAT network on Adapter 2, and boot up the VM. Edit /etc/rc.conf and set up the networking per Figure 1.3, and set the hostname:

...
HOSTNAME="ns1.projreality.sam"
...
eth0="eth0 172.16.211.10 netmask 255.255.255.0 broadcast 172.16.211.255"
INTERFACSE=(eth0)
...
gateway="default gw 172.16.211.1"
ROUTES=(gateway)
...

Next, we'll set up a temporary direct connection to the Internet:

sudo dhcpcd eth1

Install the package for BIND and dnsutils:

sudo pacman -Sy bind

sudo pacman -Sy dnsutils

dnsutils provides tools that will help us test the DNS setup. Once BIND is up and running on our nameserver, we will remove this package.

That's all we'll need to do with the temporary direct connection to the Internet, so we'll shut down the VM. That will also let all of our network settings kick in. Before starting the VM back up, disable Adapter 2 in Settings / Network.

Now, we'll set up the zone file for the projreality.sam domain. The zone file contains all of the information needed for DNS to function for the domain. This includes the IP addresses of the all of the servers with a domain name, as well as what the DNS servers for the domain are, etc.

Edit /var/named/projreality.sam:

$ORIGIN	projreality.sam.
$TTL	2d

These lines set some global settings. The value of $ORIGIN is appended to all non fully qualified domain names (FQDN). So now you can specify a domain name like "www", and BIND will consider that as "www.projreality.sam.".

@	IN	SOA	ns1	hostmaster (
	2010110200	; serial number
	3h		; refresh
	15m		; retry
	1w		; expire
	2d		; minimum TTL
)

The SOA (Start of Authority) record contains some general settings for the domain, and must come first in the zone file. The first line uses similar syntax as all other records in the zone file use:

The first parameter is the domain name. In this case, the @ symbol indicates that it is the value of the $ORIGIN parameter set earlier.

The second parameter "IN" refers to Internet - we'll use this for all entries in the zone file.

The third parameter indicates the type of record (in this case, an SOA record).

For the SOA record, there is another parameter - the nameserver for the domain.

Finally, for the SOA record, there is also a further parameter for an e-mail address.

@	IN	NS	ns1
@	IN	NS	ns2

An NS record specifies the name server(s) for a domain. In this case, the domain is again specified as @, meaning "projreality.sam.", and the nameserver is ns1.projreality.sam. and ns2.projreality.sam. (recall how BIND appends $ORIGIN if a domain name is not fully qualified).

@	IN	MX	10	mail

An MX record specifies the mail routing server for a domain. In this case, the mail server is mail.projreality.sam. The 10 doesn't do anything, but when you have redundant mail servers, the number ranks which servers get tried first. This will be used later when we set up e-mail on our internet.

ns1	IN	A	172.16.211.10
ns2	IN	A	172.16.211.11
mail	IN	A	172.16.211.15
www	IN	A	172.16.211.20

firewall	IN	A	172.16.212.1
firewall	IN	A	172.16.210.10
firewall	IN	A	172.16.211.1
router1		IN	A	172.16.210.1
router1		IN	A	172.16.101.100
router2		IN	A	172.16.210.2
router2		IN	A	172.16.126.100

employee	IN	A	172.16.212.50

The A records do what we're probably most familiar with in DNS - translate domain names to IP addresses.

Now we'll edit /etc/named.conf to set up the configuration for BIND.

Many of the settings should already be in the default config file that comes with the BIND package. However, we will go through the whole config file:

options {
	directory "/var/named";
	pid-file "/var/run/named/named.pid"
	auth-nxdomain yes;
	datasize default;

The directory option specifies the directory containing the zone files.

	listen-on { 172.16.211.10; };

The listen-on option contains the IP address that BIND will listen for DNS requests on; the default (if this option isn't specified) is to listen on all interfaces. The safest thing to do is to explicitly specify which interfaces you want BIND to listen on.

	allow-recursion { none; };

Since this is an authoritative DNS server (i.e. responsible for the projreality.sam. domain only, and not for helping the user look up any domain on the internet), we will not allow recursion.

	allow-transfer { none; };

We won't set up a slave server for now, so no need to allow zone transfers for anyone.

	allow-update { none; };

This is the master server, so we won't update from anyone.

	version none;
	hostname none;
	server-id: none;
};

By setting these options to none, we will give minimal information to potential attackers.

Next, we specify the zones. We start with the zone files for localhost. These are already provided in the BIND package.

zone "localhost" IN {
	type master;
	file "localhost.zone"
	allow-transfer { any; };
};

zone "0.0.127.in-addr.arpa" IN {
	type master;
	file "127.0.0.zone";
	allow-tranfer { any; };
};

Next, we'll specify the zone file for the projreality.sam. domain:

zone "projreality.sam" IN {
	type master;
	file "projreality.sam";
	allow-transfer { none; };
};

Finally, the logging section will set up the options for logging. This entire section should be in the config file by default.

logging {
	channel xfer-log {
		file "/var/log/named.log";
		print-category yes;
		print-severity yes;
		print-time yes;
		severity info;
	};
	category xfer-in { xfer-log; };
	category xfer-out { xfer-log; };
	category notify { xfer-log; };
};

That's it for the config. Start up BIND:

sudo /etc/rc.d/named start

Next, do a simple DNS query against the server:

dig @172.16.211.10 www.projreality.sam

dig will output a bunch of information. The line we're interested in is:

www.projreality.sam. 172800 IN A 172.16.211.20

That gives the IP address corresponding to the domain name "www.projreality.sam"

DNS also offers a way to look up the domain name associated with an IP address. The organization controlling a domain is generally responsible also for the zone files for the reverse lookup (going from IP addresses to domain names). Since ProjReality controls the 172.16.210.0/24, 172.16.211.0/24, and 172.16.212.0/24 net blocks, we will create zone files for them containing ProjReality's servers.

First, we'll create the file for the 172.16.210.0/24 netblock. Create /var/named/172.16.210.rev:

$ORIGIN	210.16.172.in-addr.arpa.
$TTL	2d

@	IN	SOA	ns1.projreality.sam.	hostmaster.projreality.sam. (
	2010110300	; serial number
	3h		; refresh
	15m		; retry
	1w		; expire
	2d		; minimum TTL
)

@	IN	NS	ns1.projreality.sam.
@	IN	NS	ns2.projreality.sam.

1	IN	PTR	router1.projreality.sam.
2	IN	PTR	router2.projreality.sam.
10	IN	PTR	firewall.projreality.sam.

Several things to note. First, we have written the *.projreality.sam. domain names all the way out, since $ORIGIN is set to 210.16.172.in-addr.arpa. now. Also, make sure you have the . at the end of arpa. Otherwise, you will have errors loading the zone file.

The PTR records are used for IP address to domain name translation (which we're doing here), while the A records are used for domain name to IP address translation.

The zone files for the other two netblocks are quite similar.

/var/named/172.16.211.rev

$ORIGIN	211.16.172.in-addr.arpa.
$TTL	2d

@	IN	SOA	ns1.projreality.sam.	hostmaster.projreality.sam. (
	2010110300	; serial number
	3h		; refresh
	15m		; retry
	1w		; expire
	2d		; minimum TTL
)

@	IN	NS	ns1.projreality.sam.
@	IN	NS	ns2.projreality.sam.

1	IN	PTR	firewall.projreality.sam.
10	IN	PTR	ns1.projreality.sam.
15	IN	PTR	mail.projreality.sam.
20	IN	PTR	www.projreality.sam.

/var/named/172.16.212.rev

$ORIGIN	212.16.172.in-addr.arpa.
$TTL	2d

@	IN	SOA	ns1.projreality.sam.	hostmaster.projreality.sam. (
	20101103	; serial number
	3h		; refresh
	15m		; retry
	1w		; expire
	2d		; minimum TTL
)

@	IN	NS	ns1.projreality.sam.
@	IN	NS	ns2.projreality.sam.

1	IN	PTR	firewall.projreality.sam.
50	IN	PTR	employee.projreality.sam.

Finally, we need to add the zone files into the BIND config. Edit /etc/named.conf and add the following lines before the logging section:

zone "210.16.172.in-addr.arpa" IN {
	type master;
	file "172.16.210.rev";
	allow-transfer { none; };
};

zone "211.16.172.in-addr.arpa" IN {
	type master;
	file "172.16.211.rev";
	allow-transfer { none; };
};

zone "212.16.172.in-addr.arpa" IN {
	type master;
	file "172.16.212.rev";
	allow-transfer { none; };
};

Issue the following command to restart BIND:

sudo /etc/rc.d/named restart

Check /var/log/daemon for errors loading any of the zone files. Check the zone files for syntax errors, or missing periods at the end of FQDNs.

Finally, add named to the DAEMONS list in /var/rc.conf so BIND will start up on boot.

Now issue the following commands to verify that reverse lookup works with all three netblocks (the -x parameter specifies a reverse lookup):

dig @172.16.211.10 -x 172.16.210.1

dig @172.16.211.10 -x 172.16.211.15

dig @172.16.211.10 -x 172.16.212.50

Finally, we will add firewall rules to allow outside requests to the nameserver. Go to the firewall.projreality.sam VM and edit /etc/pf.conf

First, in the # Servers section, add a macro for the nameserver:

ns1 = "172.16.211.10"

Then, at the end, just before the block log quick all line, add:

pass in quick on $Ext inet proto udp from any to $ns1 port domain
pass out quick on $DMZ inet proto udp from any to $ns1 port domain

Reload the firewall rules with:

pfctl -F all -f /etc/pf.conf

Finally, start up router1.projreality.sam, gateway.isp2.sam, backbone1, gateway.isp.sam, and customer. Go to the customer VM, and issue a

dig @172.16.211.10 www.projreality.sam

and you should see the IP address in the answer. If it hangs, go to the firewall.projreality.sam VM and do a

sudo tcpdump -netttvvli pflog0

and see what comes up when you try the dig command from the customer VM. Check the firewall rules we just added to make sure they were entered correctly.