6 minutes
DNS & DHCP on Ubuntu 16.04
As per my last post, I am upgrading my home test environment to Ubuntu 16. One of the things I noticed is that I can’t seem to get it installed with 256MB of ram, it really is requiring 512 unlike good ol’ Trusty. I have also been having trouble with the ubuntu-vm-builder script, but that issue seems to be well documented, so I am sure it will be resolved soon. In the meantime I am building guests the old fashioned way, spinning them up off of the bootable iso. Either way, the first guest I need to put back on my network is my dhcp and dns server. So I went ahead and spun up a new ubuntu server. I like having an internal dns server, but I am aware that this is way overkill for most home networks. Most of the features that I need, I could simply get out of using dnsmasq on my router, but I like the challenge of running bind.
Pre-Req’s
Before I got started actually doing any work, I went ahead and changed the network settings over to a static address, so that the system itself isn’t reliant on a dhcp server. All I did was use nano to edit the /etc/network/interfaces file to the following.
# The primary network interface
auto ens3
iface ens3 inet static
address 192.168.80.2
netmask 255.255.255.0
broadcast 192.168.80.255
gateway 192.168.80.1
dns-nameservers 151.197.0.37 198.6.1.3 71.242.0.12
Installs
Starting with the easy part, I go ahead and install the software itself.
sudo apt-get install isc-dhcp-server bind9
Configure DNS
So, here is where it starts to get interesting. The first config file I am going to edit is at named.conf.options. To edit it you simply sudo nano /etc/bind/named.conf.options
acl internals {
localhost;
localnets;
};
options {
directory "/var/cache/bind";
// If there is a firewall between you and nameservers you want
// to talk to, you may need to fix the firewall to allow multiple
// ports to talk. See http://www.kb.cert.org/vuls/id/800113
// If your ISP provided one or more IP addresses for stable
// nameservers, you probably want to use them as forwarders.
// Uncomment the following block, and insert the addresses replacing
// the all-0's placeholder.
forwarders {
151.197.0.37;
198.6.1.3;
71.242.0.12;
};
allow-query {
internals;
};
allow-transfer {
internals;
};
allow-recursion {
internals;
};
//========================================================================
// If BIND logs error messages about the root key being expired,
// you will need to update your keys. See https://www.isc.org/bind-keys
//========================================================================
dnssec-enable no;
//dnssec-validation auto;
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};
Setting the Access Control List to a local host and local networks is a bit overkill as this server is well behind my firewalls, but it seems like a good idea. My forwarders are the public DNS servers that are fastest from where I am at. I use and recommend GRC DNS Benchmark Tool to determine your own DNS servers for this. I am also disabling DNSSEC for now.
Configure my DNS Zones
There are a couple files to edit here. Firstly the /etc/bind/named.conf.local file to add in the name of my zone file and my reverse zone file.
//
// Do any local configuration here
//
include "/etc/bind/rndc.key";
zone "home.aaron" {
type master;
file "/var/lib/bind/home.aaron.zone";
allow-update { key rndc-key; };
};
zone "80.168.192.in-addr.arpa" {
type master;
file "/var/lib/bind/home.aaron.rev.zone";
allow-update {key rndc-key; };
};
// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";
As you can see I have created a zone called home.aaron in my var/lib/bind folder and a reverse zone called home.aaron.rev in the same folder. Obviously you can make these names more meaningful for your network.
The Zone Files
So first I am going to create the lookup zone file. Simply creating a file called home.aaron.zone in my var/lib/bind/ folder. Obviously these will need to be tweaked to your network.
$ORIGIN .
$TTL 907200 ; 1 week 3 days 12 hours
home.aaron IN SOA ns1.home.aaron. aaron.home.aaron. (
2017012134 ; serial
28800 ; refresh (8 hours)
3600 ; retry (1 hour)
604800 ; expire (1 week)
38400 ; minimum (10 hours 40 minutes)
)
NS ns1.home.aaron.
$ORIGIN home.aaron.
ddwrt A 192.168.80.1
ns1 A 192.168.80.2
vhost A 192.168.80.3
vdns CNAME ns1
Next, I will setup the reverse zone file I alluded to above. This will be var/lib/bind/home.aaron.rev.zone.
$ORIGIN .
$TTL 907200 ; 1 week 3 days 12 hours
80.168.192.in-addr.arpa IN SOA ns1.home.aaron. aaron.home.aaron. (
2017012195 ; serial
28800 ; refresh (8 hours)
604800 ; retry (1 week)
604800 ; expire (1 week)
86400 ; minimum (1 day)
)
NS ns1.home.aaron.
$ORIGIN 80.168.192.in-addr.arpa.
1 PTR ddwrt.home.aaron.
2 PTR ns1.home.aaron.
3 PTR vhost.home.aaron.
These two files need to have read and write permissions from the bind group, so I go ahead and change permissions.
sudo chown bind:bind /var/lib/bind/home.aaron.zone
sudo chown bind:bind /var/lib/bind/home.aaron.rev.zone
sudo chmod 664 /var/lib/bind/home.aaron.zone
sudo chmod 664 /var/lib/bind/home.aaron.rev.zone
Test DNS
Next I will change the network interface of the dns server to use itself as a nameserver. Simply edit the etc/network/interface file and change the dns-nameservers to 127.0.0.1.
# The primary network interface
auto ens3
iface ens3 inet static
address 192.168.80.2
netmask 255.255.255.0
broadcast 192.168.80.255
gateway 192.168.80.1
dns-nameservers 127.0.01
Next restart the network and then restart the dns service
sudo sudo ifdown ens3 ; sudo ifup ens3
sudo bind9 restart
Check to make sure it works. If not, check the syslog for any notifications about typos in the text files. Bind is very picky about text file formatting.
Setup the dhcp server
So this part is way simpler than dns. In fact this is all in one config file, so I simply nano /etc/dhcp/dhcpd.conf.
ddns-updates on;
ddns-update-style interim;
update-static-leases on;
authoritative;
include "/etc/dhcp/ddns-keys/rndc.key";
allow unknown-clients;
use-host-decl-names on; d
efault-lease-time 86400; #24 hours
max-lease-time 86400; #21 hours
log-facility local7;
# home.aaron DNS zones
zone home.aaron. {
primary 192.168.80.2; # This server is the primary DNS server for the zone
key rndc-key; # Use the key we defined earlier for dynamic updates
}
zone 80.168.192.in-addr.arpa. {
primary 192.168.80.2; # This server is the primary reverse DNS server for the zone
key rndc-key; # Use the key we defined earlier for dynamic updates
}
# home.aaron LAN range
subnet 192.168.80.0 netmask 255.255.255.0 {
range 192.168.80.50 192.168.80.200;
option subnet-mask 255.255.255.0;
option routers 192.168.80.1;
option domain-name-servers 192.168.80.2;
option domain-name "home.aaron";
ddns-domainname "home.aaron.";
ddns-rev-domainname "80.168.192.in-addr.arpa.";
}
# Static hosts give an IP addr by MAC address group {
# # Fist static host
# host static1.dragon.lab {
# hardware ethernet 01:23:45:67:89:ab; fixed-address 10.1.200.120;
# ddns-hostname "static1";
# }
#}
Take care of app armor
To allow the use of the bind key I had to edit the app armor config file for dhcpd. This file is located at /etc/apparmor.d/usr.sbin.dhcpd. I commented the line that looked for the key in /etc/dhcp/ and added the line that listed the key in /etc/bind/.
# /etc/dhcp/ddns-keys/** r,
/etc/bind/rndc.key r,
Restart the server…
And then lastly, I simply restart the server. Pay attention to any messages in the syslog file as that will tell you if there were any issues during service startup.
sudo reboot now
Credits:
Beware here be musings has a great write up on this whole process. I just had to make some small changes to port this to 16 and to make it work on my network setup.