Simple Home Internet Filter

posted Sep 7, 2017

The mission was to block access to all age restricted YouTube videos on our home network while allowing access to the rest. It's easy to do so using hosts file entries on a per-machine basis, but this is not always an option (on mobile devices and consoles for instance).

E.g. here are the hosts file entries I normally put on a computer the kids use to access the Internet, based on the details published over at OpenDNS... How to: Enforcing Google SafeSearch, YouTube, and Bing

# Google SafeSearch (forcesafesearch.google.com) 216.239.38.120    google.com www.google.com google.com.au www.google.com.au  # Youtube Restricted Mode (restrict.youtube.com) 216.239.38.120    youtube.com www.youtube.com m.youtube.com youtubei.googleapis.com youtube.googleapis.com www.youtube-nocookie.com

# Bing SafeSearch (strict.bing.com) 204.79.197.220    bing.com www.bing.com

Rather than reinventing the wheel, I started off looking for a public DNS that already does what I want. After probing ~500 public DNS servers with nslookups for YouTube and some other dubious domains, the only service that did any blocking or redirection of anything on my site list was Norton ConnectSafe (which presented a malware warning page for 4chan.com, but still allowed people to continue if they wanted to). It didn't force restricted mode, which was a bit sad, but the malware warnings and strict blocking of other non-kid friendly sites were a pretty good addition to the arsenal none the less. Norton ConnectSafe is free for home and personal use.

So now the mission is to find the a simple DNS server that can perform the function of the hosts file snippet above, plus forward the rest of the requests to Norton ConnectSafe. A proper router could do this, but I have a locked down Telstra T-Gateway (TG797n v3) which very limited DNS and DHCP configuration settings.

Dnsmasq

Dnsmasq happily reads your hosts files by default. I didn't realise it was anything more than a local DNS cache, but it's actually so much more. It's easily configured to be a full featured DNS and DHCP server. I don't have a home server, so I've decided to try using a Raspberry Pi to host this on. It's really handy since my router has a powered USB port, I can just hook the Pi up to the router for both ethernet and power, tuck it away nicely behind the router and forget about it.

Rather than using the real hosts file, I'm going to create a separate one dedicated to my DNS overrides called /etc/hosts.dns. The contents of the file is as mentioned above with some bonus entries for the Pi and the T-Gateway...

10.0.0.1          dns      # Raspberry Pi 10.0.0.138        router   # T-Gateway  # Google SafeSearch (forcesafesearch.google.com) 216.239.38.120    google.com www.google.com google.com.au www.google.com.au  # Youtube Restricted Mode (restrict.youtube.com) 216.239.38.120    youtube.com www.youtube.com m.youtube.com youtubei.googleapis.com youtube.googleapis.com www.youtube-nocookie.com

# Bing SafeSearch (strict.bing.com) 204.79.197.220    bing.com www.bing.com

Now the config file /etc/dnsmasq.conf will look like this (I'm assuming default T-Gateway network settings, and I'm going to dub my home network "home"):

listen-address=10.0.0.1       # Listen on this address  # DNS Settings no-hosts        # Don't read the hostnames from /etc/hosts domain=home     # Local domain local=/home/    # Don't forward requests for the local domain upstream addn-hosts=/etc/hosts.dns       # Static FQDN overrides and local domain hosts expand-hosts    # Expand local hostnames with our domain, e.g. hostname.domain local-ttl=600   # TTL when dnsmasq responds to a lookup  # Upstream DNS Settings no-resolv       # Don't add /etc/resolve.conf DNS servers to the upstream pool no-poll         # Don't poll /etc/resolv.conf for changes bogus-priv      # Don't forward reverse lookups on private IP ranges to upstream DNS domain-needed   # Never forward queries for non-FQND to upstream DNS server=199.85.126.30    # Upstream DNS (also sent to DHCP clients) server=199.85.127.30  # DHCP dhcp-range=10.0.0.10,10.0.0.137,255.255.255.0,12h      # Network and default lease dhcp-option=option:router,10.0.0.138    # Router (default gateway)  # Static leases (should match an entry in /etc/hosts.dns) #dhcp-host=<Raspberry Pi MAC>,10.0.0.1 #dhcp-host=<Router MAC>,10.0.0.138

I've commented out the last two lines, since those two devices will have static IP addresses anyway. You should be able to see how static leases could be added for other important devices on your network (if not just ignore those lines, they're not critical). Note, I've added Norton ConnectSafe IP addresses as the upstream DNS servers. Before you restart Dnsmasq, make sure to disable DHCP on your router (see the T-Gateway section at the very end if you need help on that). Here are some other helpful commands...

Install Dnsmasq on Raspbian or some other Debian based distro (if it's not already installed):

sudo apt-get install dnsmasq

Restart dnsmasq:

sudo service dnsmasq restart

List current DHCP leases:

sudo cat /var/lib/misc/dnsmasq.leases

Raspberry Pi Notes

I tested this plan out on a Raspberry Pi 2 with Raspbian Strech Lite. An old 4GB SD card I had lying around turned out to be plenty of space for this project.

pi@raspberrypi:~ $ df -h Filesystem      Size  Used Avail Use% Mounted on /dev/root       3.6G  1.1G  2.4G  32% / devtmpfs        460M     0  460M   0% /dev tmpfs           464M     0  464M   0% /dev/shm tmpfs           464M  6.2M  458M   2% /run tmpfs           5.0M  4.0K  5.0M   1% /run/lock tmpfs           464M     0  464M   0% /sys/fs/cgroup /dev/mmcblk0p1   42M   21M   21M  51% /boot tmpfs            93M     0   93M   0% /run/user/1000

Before it can go headless, use the config tool to set setup some stuff. SSH is disabled by default and that's really the first priority in order to lose the keyboard and monitor.

# raspi-config

Go through all the options one by one. Changing the default password is obviously pretty critical. I changed the Hostname to "dns". Enable SSH from the "Interfacing Options" menu. Setting locale and timezone is probably a good idea. Also, drop the GPU memory to minimum.

Set Static IP

One SSH is working, set a static IP on both the management machine and the Raspberry Pi so that you can shut down the routers DHCP service without risk of losing connectivity.

sudo nano /etc/dhcpcd.conf

: : # Custom config for static IP interface eth0 static ip_address=10.0.0.1/24 static routers=10.0.0.138 static domain_name_servers=10.0.0.138

The interface "eth0" might change to something else, so just check first the name of it with the ifconfig command. It should be the first interface in the list.

I forced my ethernet interface label back to eth0 by googling something that mentioned 73-usb-net-by-mac.rules and 80-net-setup-link.rules. The workaround was to remove the file or hard code "eth0" in there and put a copy of the custom versions in /etc/udev/ so that updates don't overwrite them (or a symlink to /dev/null if you just need to remove the file). I guess if you're down with all the new trendy cool kids, just use whatever the system wants to call the ethernet adaptor. Makes reuse of configuration files a bit of a bloody pain though. Kids these days...

Anyway, compared to that the rest was easy once I realised that the cool kids were on to something with this newfangled Dnsmasq. Don't waste time on bind and isc-dhcp-server, that's the old skool biz and while Bind still works ok, isc-dhcp-server just wants to irreparably break my network settings. Dnsmasq does the work of both packages and it's so much easier to configure.

T-Gateway Notes

Thankfully there is an option to disable DHCP and it's pretty easy to find, the checkbox is located under Advanced | Local Network. Make sure you do this before you configure and restart Dnsmasq.

To prevent your kids from manually configuring their own DNS settings, you could try to set some firewall rules on the T-Gateway. Note that the firewall is pretty useless for anything other than local traffic rules. So you'd have to set one rule to allow access to DHCP port 53 on 10.0.0.1 (both UDP and TCP) then a second rule to block DHCP port 53 to any destination (leave the destination IP blank). I've not tested this configuration, but in theory that would work.

DHCP Settings

The DHCP service on the T-Gateway could almost do the job, except for a couple of things I didn't like about it. Firstly, you can only specify a custom primary DNS server, and the router would also send a Telstra DNS server as a secondary. This means that if my DNS server becomes unavailable, the requests would start going to Telstra when I'd really rather they fallback to using Norton ConnectSafe (although I've not configured any secondary server in the example above, the point is that I can if I want). The second issue I have with the router's DHCP server is that you can't change the IPv6 DNS server settings (which I'm assuming are Telstra ones). So kids might be able to use that to reach the IPv6 youtube servers some how. Now here I've also neglected to configure IPv6 too, instead I disabled IPv6 support on the router until there is a need to investigate the situation (Norton ConnectSafe doesn't have IPv6 support anyway).

If you want to configure additional DNS servers via Dnsmasq, have a read of this... [Dnsmasq-discuss] Secondary/tertiary dns servers in dhcp offers?