Usurping the BTHomeHub with a Raspberry Pi: Part 3 - Routing, Remote Administration and Utilities

In Part One we configured a RaspberryPi to act as a Wireless Access point, providing DHCP services to wireless clients. In Part Two we then configured our Pi to provide DHCP, DNS and NTP services to the entire LAN.

In this part, we'll be taking some more responsibility away from the BTHomeHub, as well as configuring a few conveniences, such as Remote administration and useful utilities, including

  • Wake On Lan
  • Network Troubleshooting Tools
  • Dynamic DNS Update Client (No-Ip.com)

 

Enabling Routing

With the possible exception of configuring NTP, this is far and away the easiest bit of configuration in the entire project. We want our Pi to act as the default gateway for all clients, as that'll allow us to implement additional functionality such as QoS or content filtering at a later date.

We need to enable IP forwarding, and disable ICMP redirects. We'll need to update the system settings to ensure the changes persist after reboot

# These change the setting now
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.send_redirects=0

# Now we want the changes to persist - the keys may already exist, so search the file for them
nano /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv4.conf.all.send_redirects=0

If we hadn't disabled send_redirects then everything would still have worked. However, the kernel would allow itself to be smart and realise that the LAN clients are on the same subnet as the gateway and so could talk directly to it - it'd send an ICMP redirect and the LAN clients would then go back to talking directly to the HomeHub

The final change is to update our DHCP config

nano /etc/dhcp/dhcpd.conf

# Find option routers 192.168.1.254; and change to
option routers 192.168.1.250;

Restart the DHCP server and clients should start using the Pi as their default gateway (or will do when their DHCP leases renew)

service isc-dhcp-server restart

 

Remote Administration

How you go about this is partially a matter of personal preference, but it would be nice to be able to SSH onto the Pi when not at home, whether to troubleshoot, as a stepping stone to another machine or simply to use one of the utilities we'll be installing shortly.

You could configure your BTHomeHub to forward SSH onto the Pi (Port 22), however that's not really an option for me - I already have a bastion host listening on port 22. Rather than open another port, and having another instance of openSSH listening on a public IP, I decided to open a reverse tunnel.

It's not often I'll need to use the tunnel, as I can connect via my bastion. However if the bastion is down, it'd still be helpful to be able to connect in and see what's happening.

As I've a number of servers off-site, I can quite easily SSH onto them and then connect through a tunnel if one exists. So what's needed is a simple script to open and maintain a reverse SSH tunnel. Run the following commands as the user pi, adjust the username/hostname to match the one you wish to use for SSH

mkdir ~/bin
ssh-keygen -t rsa
ssh-copy-id piuser@bensmachine.example.com
nano ~/bin/remote_management.sh

Now insert the following script, again adjusting the username/hostname for your endpoint

#!/bin/bash
#
ps aux | grep -v "grep" | grep "ssh -f -N -R 9080:localhost:22 piuser@bensmachine.example.com" > /dev/null

# Tunnel not open
if [ "$?" == "1" ]
then
echo "Opening tunnel"
ssh -f -N -R 9080:localhost:22 piuser@bensmachine.example.com&
else
echo "Tunnel already open"
fi

Save and close. Now we'll make it executable and add it as a cron job

chmod +x ~/bin/remote_management.sh
crontab -e
*/5 * * * * /home/pi/bin/remote_management.sh

Every 5 minutes, the Pi will now check to see if there's a tunnel open and if not, it'll attempt to create one. To connect to the Pi using this tunnel, we simply SSH onto our endpoint and then run

ssh pi@localhost -p 9080

The initial connection will be slow, but once connected things should run at a reasonable speed

 

NMap

NMap can be an incredibly useful tool, so it's worth getting installed (especially as we'll be using it shortly)

sudo apt-get install nmap

 

Wake On Lan

As we've got remote access to the Pi, it'd be helpful if we could use it to switch machines on. Enter Wake on Lan. The target machine's hardware has to support it, it has to be enabled in the BIOS (and sometimes also in the OS) but assuming all these requirements are met, it's actually rather simple.

Run the following as user pi.

cd ~
git clone https://github.com/bentasker/Wake-On-Lan-Python.git

We now have a small Python script that can send the Magic packet that makes Wake-On-Lan work. However, WOL works using Mac addresses so we need to build our config file. We could go around each individual client and get the hardware address, or we could cheat;

nmap -sP 192.168.1.0/24
# You wait - time passes

echo "[General]" > Wake-On-Lan-Python/.wol_config.ini
echo "broadcast=192.168.1.255" >> Wake-On-Lan-Python/.wol_config.ini
echo >> Wake-On-Lan-Python/.wol_config.ini

arp | grep ".home" | awk '{print $1,$3}' | sed 's/.home//g' | \
while read -r a ; do echo "[" `echo $a | awk '{print $1}'` "]" | tr -d ' ' >> Wake-On-Lan-Python/.wol_config.ini; \
echo "mac="`echo $a | awk '{print $2}'` >> Wake-On-Lan-Python/.wol_config.ini; echo >> Wake-On-Lan-Python/.wol_config.ini; done

So what we've done is to scan the local subnet for active systems. The brief communication with each will have added their details to the ARP table - we then simply grep out the relevant entries and use them to generate our config file

To use the script to wake a client with the hostname milleniumfalcon we'd then run

/home/pi/Wake-On-Lan-Python/wol.py milleniumfalcon

 

Dynamic DNS Updates

One of the other utilities that the HomeHub provides is a built in Dynamic DNS update client. I use NoIp.com as my Dynamic DNS provider, so we'll go through the steps of installing and configuring their client.

Grab and unpack the Dynamic Update Client

wget http://www.noip.com/client/linux/noip-duc-linux.tar.gz
tar xvzf noip-duc-linux.tar.gz

We now need to compile the client, so

cd noip-2.1.9-1
make

Now we need to make the configuration file

./noip2 -C -c /home/pi/.noip
# Answer the questions

Finally, we'll add a cronjob to make sure it's running (check every 15 minutes)

crontab -e
*/15 * * * * if [ ! `ps aux | grep noip2 | grep -v 'grep' | wc -l` -gt 0 ]; then /home/pi/noip-2.1.9-1/noip2 -c /home/pi/.noip; fi

We could also start the script manually, but it's worth waiting until the next 15 minute interval to ensure that cron actually starts it

 

In Part Four, we create OpenVPN tunnels and configure the Pi to route connections to specific destinations via VPN.