Blocking Websites on a Schedule With Pi-Hole

I’ve written about blocking adds and distracting websites before as part of my digital minimalism crusade. I’m a big fan of thinking through your lifestyle design and automating decisions as much as possible.

For instance, after 9pm at night and before 7am there’s a set of distracting websites that I do not want myself, or anyone in my family, to be able to access. This introduces just enough friction to bad behavior (like scrolling Twitter at 9pm) that it prevents me from doing the wrong thing.

Below I’ve described how I block (and then subsequently allow) websites on a schedule, and some other misc related trick with the Raspberry Pi & Pi-Hole.

Block Sites on a Schedule

I wanted to block my Roku TV based on my cron schedule. However, the TV uses a bunch of different subdomains across various services. With a /etc/hosts blocking method, you can’t block domains based on a pattern, but you can with pi-hole.

The --wild command converts your domain into a wildcard regex to match the domain of any subdomains.

For example, if you have a blocklist file containing a simple list of URLs:

facebook.com
pinterest.com
amazon.com
netflix.com
feedbin.com
disneyplus.com
roku.com
youtube.com
twitter.com

Your block.sh would look like:

blockDomains=$(<blocklist)

for domain in ${blockDomains[@]}; do
  pihole --wild $domain
done

Note that the position of the -d is significant in your allow.sh:

blockDomains=$(<blocklist)

for domain in ${blockDomains[@]}; do
  pihole --wild -d $domain
done

Here’s a great discussion about how to block groups in Pi-hole.

Running Pi-Hole & Scheduled Blocking on Docker

I’ve codified most of this into a docker container and related docker-compose.

Whitelist Alexa-related Domains

If you block amazon (which I recommend to avoid buying stuff or getting sucked into prime video), you may want to whitelist alexa-related domains so they work inside "blocked hours". Here are the domains you want to whitelist (and here’s a script to do it):

bob-dispatch-prod-na.amazon.com
avs-alexa-14-na.amazon.com
api.amazon.com
api.amazonalexa.com
latinum.amazon.com

DDNS with Dreamhost

Sometimes, if you are running a VPN or a node on a service (like Storj) you’ll want to have an external domain available which points to your network IP.

I have a dreamhost server that runs a couple of WordPress sites for me. They have a nice API for modifying DNS records that can be used to dynamically update a domain record which points to my home network.

Here’s the modified dreamhost script that worked for me (I couldn’t get the PR for this merged). Here’s how to set it up as a cron on the pi:

crontab -e
@hourly bash -l -c 'DREAMHOST_API_KEY=THEKEY DREAMHOST_UPDATE_DOMAIN=subdomain.domain.com /home/pi/Documents/dreampy_dns/dreampy_dns.py'

Watch the logs:

tail -f /var/log/cron.log

To test to make sure it’s working (from a server outside your network):

telnet node.thesite.com 28967

Even better: DDNS with Dreamhost + Docker

You can also run this as a docker image. Here’s an example docker-compose.

Blocking DNS over HTTP

iOS and specific websites on macos use DNS over HTTP. This breaks the blocking rules you setup on pihole. You can configure pihole to reject all DNS over HTTP queries.

Here’s what this looks like in the pi-hole interface:

Here’s how to do this on the command line.

Blocking Spam, Porn & Other Sites on Raspberry Pi

Block List Project has a great index of various site groups you can block, including porn. Here’s another block list.

Navigate to Group Management > Ad List and then pick the "Original" version of the lists on the blocklist project.

Here’s a script which does this.