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) 22.214.171.124 google.com www.google.com google.com.au www.google.com.au # Youtube Restricted Mode (restrict.youtube.com) 126.96.36.199 youtube.com www.youtube.com m.youtube.com youtubei.googleapis.com youtube.googleapis.com www.youtube-nocookie.com
# Bing SafeSearch (strict.bing.com) 188.8.131.52 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 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) 184.108.40.206 google.com www.google.com google.com.au www.google.com.au # Youtube Restricted Mode (restrict.youtube.com) 220.127.116.11 youtube.com www.youtube.com m.youtube.com youtubei.googleapis.com youtube.googleapis.com www.youtube-nocookie.com
# Bing SafeSearch (strict.bing.com) 18.104.22.168 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=22.214.171.124 # Upstream DNS (also sent to DHCP clients) server=126.96.36.199 # 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
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.
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.
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.
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?