BLOCKING YOUTUBE ON YOUR KID’S DEVICES (ONLY) USING PFSENSE
desired outcomes by Dall-E 2
Background
It’s month 8 of a global pandemic and your kids are watching 5 hours of mind numbing YouTube videos on the daily. Surely there’s got to be an easy way to prevent this while still allowing yourself access to the same degenerate content after they go to bed. Unfortunately all of your internet searches only show you how to block sites wholesale, ie all or nothing to all devices, which is not what you want.
I present to you a method to selectively filter access to websites (not just YT) based on the IP of the device on your home network.
Pre-requisites
In my case I am running a pfSense firewall locally but the key to making this happen is the unbound recursive caching DNS server which it natively runs. The main requirement is a DHCP server which assigns static IPs (for the devices you want to block) and DNS addresses which point to the local unbound server which will do the filtering.
Static DHCP addressing
There are already existing instructions which cover how to do static DHCP addressing on pfSense which you can find here. You’ll have to do this for the devices you want to block websites for. It will start off with something like the below.
Enable custom configurations in unbound server
You’ll have to modify the unbound server on your pfSense FW to allow for custon configs. This is to ensure that any changes you make will remain after firmware updates and reboots. You can do so by logging into the web admin interface and then in the top menu, navigate to Services -> DNS Resolver which looks like the following:
Define a custom config file
Scroll to the bottom of the page and make sure that the Display Custom Options button is enabled which should toggle a Custom options text box right below it. You might see an existing configuration in there, in my case it’s settings for my external DNS provider, nextdns. Clients in my home LANs will be configured to use pfSense as their primary DNS server but requests will transparently sent upstream to nextdns to resolve as needed. You’ll want to add a statement below that to the effect of:
include: /var/unbound/your_custom_filename.conf
and then click the Save button
It should look something like this:
SSH to pfSense and create the custom config file
You’ll have to SSH into your FW for the next step which will require some basic familiarity with the *nix command line. If you don’t have SSH enabled, you can refer to this guide. Once you login, you’ll be presented with a menu and you’ll type 8 and hit enter to enter the ⭐shell⭐.
Edit the new config file
You’ll change to the /var/unbound
dir and then create a new file (with the same name that you used in the custom config box above) with the following contents (substituting your local device IPs as appropriate):
view:
name: "family"
local-zone: espn.com transparent # <- See explanation for transparent below
local-data: "espn.com. IN A 127.0.0.1"
local-data: "badsite.espn.com. IN A 127.0.0.1"
local-zone: youtube.com redirect # <- See explanation for redirect below
local-data: "youtube.com. IN A 127.0.0.1"
server:
access-control-view: 10.0.10.25/32 family # <- change your device IP here
The vi editor is natively installed on pfSense but if you’re not feeling up to it, you can run pkg update; pkg install nano
for a more pedestrian option.
Ok let’s break down the above:
We’re creating dns records for all of the sites we want to block in a view entry named family
. Feel free to call this whatever you want. We have two sites that we are concerned with blocking which we create local-zone info for: espn.com and youtube.com. There are a myriad of local-zone types which you can read about but for our purposes we only care about two: transparent
and redirect
youtube uses redirect
which means that any requests for foo.youtube.com or whatever.youtube.com or *.youtube.com or just plain youtube.com
will resolve to 127.0.0.1. This is a surefire way to shutdown any and all DNS requests for sites that you absolutely want no traffic going to and probably what you want to use for the sites you block.
espn uses transparent
which means that pfSense will respond to any DNS requests for the whatever records associated with the top level domain that are configured but anything else will be sent upstream for resolution. So in this case, that means espn.com and badsite.espn.com will resolve to 127.0.0.1 but a DNS request for www.espn.com will be sent outbound and resolve to 13.35.73.29
(as of this writing). This was more of a proof of concept which will likely be used less often in practice.
Finally make sure that the access-control-view
line contains the IP(s) of the devices you want controlled. Feel free to add multiple lines.
Restart the unbound server
After you save the above file, all that’s left to do is to restart the unbound server by issuing a:
pfSsh.php playback svc restart unbound
from within your SSH session
and that should be it. The sites you wish to be blocked should no longer be accessible.
Of course this isn’t 100% foolproof. Kids are clever these days but for the unsuspecting tech novice, this should prove effective.
As a follow-up goal I’d like to explore how to block access to sites based on time of day …