BLOCKING YOUTUBE ON YOUR KID’S DEVICES (ONLY) USING PFSENSE

and local client based DNS filtering, while you continue to indulge
Published

February 4, 2023


kid_adult.png
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.

static-dhcp.png

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:

custom_dns.png

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:

custom_dns_box.png

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⭐.

pfSense-ssh.png

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 …

References