Usurping the BTHomeHub with a Raspberry Pi: Part 2 - DNS, DHCP and NTP

In Part One, we configured our RaspberryPi to act as a Wireless access point and bridged the wireless and wired interfaces so that WLAN client's were easily accessible from the LAN.

As part of that setup, we configured a DHCP server, however we haven't yet made it the DHCP server for the LAN - our tired old BTHomeHub is still the authoritative server for the network.

In this part, we'll be reconfiguring our DHCP server so that it takes responsibility for the entire LAN, configuring DNS services, and making our Pi the LANs central NTP (Network Time Protocol) Server

Step by step, we'll be configuring our Raspberry Pi to take over nearly all of the duties performed by the BTHomeHub.

 

Start with a Useful Utility

To make sure we can easily see what is going on, we're going to install a utility called DHCPDump. It outputs the contents of any DHCP related traffic that it detects, which can prove invaluable in locating the source of an issue.

sudo apt-get install dhcpdump

To get an idea of the output we expect to see, let's quickly run the utility whilst a phone/laptop is connecting

dhcpdump -i br0

TIME: 2014-01-19 16:56:40.004
IP: 0.0.0.0 (0:1a:a0:cf:87:18) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
OP: 1 (BOOTPREQUEST)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: bfee020a
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 00:1a:a0:cf:87:18:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 3 (DHCPREQUEST)
OPTION: 50 ( 4) Request IP address 192.168.1.70
OPTION: 12 ( 15) Host name milleniumfalcon
OPTION: 55 ( 13) Parameter Request List 1 (Subnet mask)
28 (Broadcast address)
2 (Time offset)
3 (Routers)
15 (Domainname)
6 (DNS server)
119 (Domain Search)
12 (Host name)
44 (NetBIOS name server)
47 (NetBIOS scope)
26 (Interface MTU)
121 (Classless Static Route)
42 (NTP servers)

---------------------------------------------------------------------------

TIME: 2014-01-19 16:56:40.017
IP: 192.168.1.254 (0:1f:9f:76:98:53) > 192.168.1.70 (0:1a:a0:cf:87:18)
OP: 2 (BOOTPREPLY)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: bfee020a
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 192.168.1.70
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 00:1a:a0:cf:87:18:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 5 (DHCPACK)
OPTION: 54 ( 4) Server identifier 192.168.1.254
OPTION: 51 ( 4) IP address leasetime 600 (10m)
OPTION: 1 ( 4) Subnet mask 255.255.255.0
OPTION: 28 ( 4) Broadcast address 192.168.1.255
OPTION: 3 ( 4) Routers 192.168.1.254
OPTION: 15 ( 4) Domainname home
OPTION: 6 ( 8) DNS server 192.168.1.254

What we've seen there is a DHCP request go out from a client with the hostname milleniumfalcon. In this case, it's asked to renew a lease - 192.168.1.70.

A DHCP server (in this case, the BTHomeHub - 192.168.1.254) has responded with a DHCPACK - confirming the lease and providing the details requested in the original parameter request list.

 

Removing the HomeHub from the equation

So what we're going to do now, is tell the Pi to be the authoritative DHCP server and then disable DHCP on the BTHomeHub.

nano /etc/dhcp/dhcpd.conf

# Find the line ;authoritative and uncomment
authoritative

Save and exit. We want to restart the DHCP server now, so

service isc-dhcp-server restart

Note: In the interest of safety, make a note of the IP that your PC/Laptop currently has - if for some reason we end up without a working DHCP server we'll want to assign this manually so that we can investigate/troubleshoot.

The next step is to tell the BTHomeHub not to worry about DHCP anymore. Log into the web interface at http://192.168.1.254 and disable DHCP by completing the following steps

  • Settings
  • Enter your password and click OK
  • Advanced Settings
  • Click 'Continue to Advanced Settings' (and mutter about why they felt the need to ask you to confirm)
  • Home Network
  • IP Addresses
  • Under DHCP Server set Enabled to No and click Apply

Now, in principal the Pi is the only DHCP server on the network (I say in principal, despite plainly being disabled, the BTHomeHub seems to like to send a DHCPNAK whenever a client asks the Pi if it can renew a lease.... I'll leave conclusions as to the quality of the hub to the reader).

 

Testing DHCP

Clearly we don't just want to assume that something as important as DHCP is working, so we need to verify that the Pi is providing IP's as it should. The DHCP server writes to the syslog, so we're going to watch that whilst we get a Phone/Laptop to connect to the Wifi (and then use DHCP to get an address).

On the Pi, run

tail -F /var/log/syslog 

and then connect your phone/laptop to the wifi. If all's working well, you should see something like the following appear in the log (if not, repeat the process with dhcpdump running to verify the DHCP request is actually going out)

Jan 19 17:09:04 raspRouter dhcpd: DHCPREQUEST for 192.168.1.70 from 00:1a:a0:cf:87:18 via br0
Jan 19 17:09:04 raspRouter dhcpd: DHCPACK on 192.168.1.70 to 00:1a:a0:cf:87:18 via br0

So DHCP is alive and working!

 

NTP

The next thing we want to get working is NTP (Network Time Protocol) so that all our systems can show and use the same time. This is quick and easy to set up, and we'll then reconfigure DHCP to provide the NTP server's details to all clients that request it.

On Raspbian, NTP is already installed and running, so we just need to reconfigure it to allow LAN clients to ask it what the time is;

nano /etc/ntp.conf

# Add the following broadcast 192.168.1.255

# Optional - Add BT's NTP server server ntp.homehub.btopenworld.com iburst

Restart NTP to make the changes take effect

service ntp restart

Finally, we want to update DHCP to push the time server

nano /etc/dhcp/dhcpd.conf
# Find where we defined the subnet as below
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.150 192.168.1.200;
option broadcast-address 192.1.0.255;
option routers 192.168.1.254;
default-lease-time 600;

max-lease-time 7200;
option domain-name "home";
option domain-name-servers 8.8.8.8, 8.8.4.4;
}

# We need to add the NTP server - option ntp-servers 192.168.1.250, which would make our entry
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.150 192.168.1.200;
option broadcast-address 192.1.0.255;
option routers 192.168.1.254;
default-lease-time 600;
max-lease-time 7200;
option domain-name "home";
option domain-name-servers 8.8.8.8, 8.8.4.4;
option ntp-servers 192.168.1.250;
}

Save and exit, followed by a restart of the DHCP server

service isc-dhcp-server restart

Now, if we run dhcpdump (leases renew every 10 minutes, so you can just wait, or you can force a client to renew) we should see the Pi provide an NTP server in it's response)

dhcpdump -i br0

TIME: 2014-01-19 17:14:36.005
IP: 192.168.1.250 (80:1f:2:8d:5f:52) > 192.168.1.70 (0:1a:a0:cf:87:18)
OP: 2 (BOOTPREPLY)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: 3f884e74
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 192.168.1.70
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 00:1a:a0:cf:87:18:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 5 (DHCPACK)
OPTION: 54 ( 4) Server identifier 192.168.1.250
OPTION: 51 ( 4) IP address leasetime 600 (10m)
OPTION: 1 ( 4) Subnet mask 255.255.255.0
OPTION: 28 ( 4) Broadcast address 192.168.1.255
OPTION: 3 ( 4) Routers 192.168.1.254
OPTION: 15 ( 4) Domainname home
OPTION: 6 ( 8) DNS server 8.8.8.8, 8.8.4.4
OPTION: 42 ( 4) NTP servers 192.168.1.250

Notice the final line of the response - our NTP server's details have been provided

I mentioned before that the BTHomeHub was a bit strange when it came to DHCP - you may well also capture a DHCPNAK response from the HH (despite DHCP being disabled)

TIME: 2014-01-19 17:14:36.007
IP: 192.168.1.254 (0:1f:9f:76:98:53) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
OP: 2 (BOOTPREPLY)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: 3f884e74
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 192.168.1.254
CHADDR: 00:1a:a0:cf:87:18:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 6 (DHCPNAK)
OPTION: 54 ( 4) Server identifier 192.168.1.254
OPTION: 56 ( 18) Message Lease is invalid.

The HH doesn't appear to try and issue leases when disabled though, so the above (whilst annoying) is really only harmful to BT's reputation

 

DNS

As the final step in the part, we're going to set up a recursive DNS resolver so that results can be cached. Previously we've been telling clients to use Google's DNS servers, but it'd be far more efficient to have one system responsible for going upstream as it saves using bandwidth (however negligible) requesting the same record for each of our LAN clients.

We're going to use Unbound as it's lightweight and pretty fast.

apt-get install unbound

Configuration is (like NTP) quick and easy. One thing to note - whitespace is significant, keep an eye on your tab-indents!

nano /etc/unbound/unbound.conf

# Many of the following are defaults, but worth checking
# In the server block, make sure we're listening on all interfaces interface: 0.0.0.0
# Make sure it'll fork into the background
do-daemonize: yes
# Make sure LAN clients can make recursive queries
access-control: 192.168.1.0/24 allow

# This should give you a server block similar to the one below
server:
# The following line will configure unbound to perform cryptographic
# DNSSEC validation using the root trust anchor.
auto-trust-anchor-file: "/var/lib/unbound/root.key"

# Listen on all interfaces
interface: 0.0.0.0
do-daemonize: yes
# Enable UDP, "yes" or "no".
do-udp: yes
# Enable TCP, "yes" or "no".
do-tcp: yes
# upstream connections use TCP only (and no UDP), "yes" or "no"
# useful for tunneling scenarios, default no.
tcp-upstream: no

# Allow the LAN to make recursive queries
access-control: 192.168.1.0/24 allow

Incidentally, (at time of writing) to defeat BT's external DNS server block without disabling content filtering (though, really you should just turn it off), just set tcp-upstream to Yes. Again, it's left to the reader to guess at BT's competence on this one

Next, we need to add a forward zone to the same file (i.e. who should Unbound ask if it doesn't already have the answer?). Same file, add the following at the bottom

forward-zone:
name: "."
forward-addr: 8.8.8.8
forward-addr: 192.168.1.254

So when Unbound can't provide a record itself, it'll ask Google's DNS. As a means of last resort it'll then fall back to asking the BTHomeHub (we'll be changing this in a later part, but it's worth keeping in there until then)

Lets start the service, and enable it at boot

service unbound start
update-rc.d unbound enable

Before we tell our LAN clients to use our new DNS server, it'd probably be wise to check it's working, lets ask it for a record;

nslookup google.com 127.0.0.1
Server: 127.0.0.1
Address: 127.0.0.1#53

Non-authoritative answer:
Name: google.com
Address: 173.194.34.160
Name: google.com
Address: 173.194.34.174
Name: google.com
Address: 173.194.34.164
Name: google.com
Address: 173.194.34.161
Name: google.com
Address: 173.194.34.162
Name: google.com
Address: 173.194.34.169
Name: google.com
Address: 173.194.34.167
Name: google.com
Address: 173.194.34.163
Name: google.com
Address: 173.194.34.165
Name: google.com
Address: 173.194.34.166
Name: google.com
Address: 173.194.34.168

We got a response back, so things are obviously working. On a LAN client we can also run a check with

nslookup google.com 192.168.1.250

If we get results back, then we're good to go, we simply need to adjust our DHCP settings to push our nameserver

nano /etc/dhcp/dhcpd.conf

# Find option domain-name-servers 8.8.8.8, 8.8.4.4; and replace with
option domain-name-servers 192.168.1.250, 8.8.8.8;
#If for some reason the Pi doesn't respond to a DNS request, clients will fall back onto Google's DNS.

Save and exit.

Now we just need to restart the DHCP server to bring our changes into effect

service isc-dhcp-server restart

Again we can use DHCPDump to verify that the DNS server is being pushed, in our DHCPACKs we should see the line

OPTION:   6 (  8) DNS server                8.8.8.8, 8.8.4.4

Change to

OPTION:   6 (  8) DNS server                192.168.1.250, 8.8.8.8

Our Raspberry Pi is now providing DNS, NTP and DHCP services to the entire LAN

 

In Part Three, we configure the Raspberry Pi to provide Routing services, enable Remote Configuration and install a few useful utilities including a Wake On LAN Script.

If DHCP Broke

If you've ended up without a working DHCP server on your LAN, you'll want to manually assign a machine an IP so that you can investigate. This is why we kept note of a valid IP (though realistically we could just have picked one). Follow the steps below to assign the IP to your chosen terminal - replace 192.168.1.70 with the appropriate IP. Where you need to specifiy additional values, use the following

  • Subnet mask - 255.255.255.0
  • Default Gateway - 192.168.1.254
  • DNS Server 1 - 192.168.1.250
  • DNS Server 2 - 8.8.8.8

 

Linux

ifconfig eth0 192.168.1.70

 

Mac

Apple Menu -> System Preferences -> Network -> Select relevant interface -> Advanced -> TCP/IP -> set 'Configure IPv4' to Manually -> Set the IP details

 

Windows 8

Switch to Desktop Screen -> Press Windows + R keys to get run box -> Enter 'NCPA.CPL' and click OK -> Right click interface and choose Properties -> Choose Internet Protocol Version v (TCP/IPv4) -> Click Properties -> Choose 'Use the following IP address' -> Enter IP information -> Hit apply/close until you're out

 

Windows 7

Start Menu -> Network and Sharing Center -> Change Adapter Settings -> Right click interface and click properties -> Choose Internet Protocol Version v (TCP/IPv4) -> Click Properties -> Choose 'Use the following IP address' -> Enter IP information -> Hit apply/close until you're out

 

Windows Vista

Start Menu -> Right click Network -> Choose Properties -> Manage Network connections -> Right click interface and click properties -> Choose Internet Protocol Version v (TCP/IPv4) -> Click Properties -> Choose 'Use the following IP address' -> Enter IP information -> Hit apply/close until you're out

 

Windows XP

Right Click 'My Network Places' -> Properties -> Right click interface and click properties -> Choose Internet Protocol Version v (TCP/IPv4) -> Click Properties -> Choose 'Use the following IP address' -> Enter IP information -> Hit apply/close until you're out

 

You should now be able to SSH onto the Pi to investigate what's gone wrong. It's worth restarting the DHCP and networking services as a first point of call, and make good use of DHCPDump to see what's actually being sent over the network.

 

Part Three: Routing, Remote Administration and Utilities