Disabling Blocking on Dual Pi-Hole DNS Servers with a Shell Script - Justin Ribeiro, Ph.D.
Some time ago, tired of the endless updating of kid devices and the increasing amount of random device spam—I’m looking at you LG—I setup Pi-Hole as my networks end-all DNS server. If you’re unfamiliar, Pi-Hole is a network-wide ad and tracking blocking sinkhole server, routing a known set of matching domains to basically nothing (e.g., non-routable addresses). It’s easy to use, easy to setup on old hardware, and generally a seamless joy to use.
Until I or the someone in the house has healthcare related things to do.
Between the multitude of trackers and odd starting endpoints that healthcare and insurance companies use, I’ve found that my very big mix of block lists (1.6 millions domains and counting) causes all kinds of problems to getting connected when you actually really need them to work. There is an easy fix; you can temporarily disable blocking in the Pi-Hole UI.
Then I added a second Pi-Hole server to the network to handle redundancy, and clicking two different UIs was just too much effort. Luckily, Pi-Hole has an API and good docs, and where there is an API there is a hacky Justin related shell script to get the job done.
#!/bin/sh<br># Pausing Ad Blocking/Tracking for Dual Pi.Hole DNS Servers<br># I hate healthcare web portals for appointments, but the only way to make them<br># work with my rules is to temp turn off the blocking. Since I have two PiHole<br># DNS servers running, this temp disables them for 60 seconds.<br># Dependencies:<br># * curl<br># * jq
# how long to disable; I could make this a command line option, but nah, I just<br># need 60 seconds<br>timeSeconds=60
# My two PiHole DNS servers; you do you.<br>dns1="PI_HOLE_DNS1_ADDR"<br>dns2="PI_HOLE_DNS2_ADDR"
# I am lazy, same password for both servers<br>password=YOUR_PASSWORD
# Don't change these; these are the endpoints yo<br>dns1loginEndpoint="$dns1/api/auth"<br>dns2loginEndpoint="$dns2/api/auth"<br>dns1BlockEndpoint="$dns1/api/dns/blocking"<br>dns2BlockEndpoint="$dns2/api/dns/blocking"
# Don't change this, this is for curl<br>loginJson='{<br>"password":"'$password'"<br>}'
echo "Getting Pi.Hole auth tokens for DNS1 and DNS2..."<br>dns1token=$(curl -s -X POST $dns1loginEndpoint -d "$loginJson" | jq -r '.session.sid')<br>dns2token=$(curl -s -X POST $dns2loginEndpoint -d "$loginJson" | jq -r '.session.sid')<br>echo "SID tokens acquired!"<br>echo "DNS1: $dns1token DNS2: $dns2token"
echo "Pausing Blocking for $timeSeconds seconds..."<br>dns1Status=$(curl -s -X POST $dns1BlockEndpoint --data '{"sid": "'$dns1token'", "blocking": false, "timer": '$timeSeconds'}' | jq -r '.blocking')<br>dns2Status=$(curl -s -X POST $dns2BlockEndpoint --data '{"sid": "'$dns2token'", "blocking": false, "timer": '$timeSeconds'}' | jq -r '.blocking')<br>echo "Blocking Status updated!"<br>echo "DNS1: $dns1Status DNS2: $dns2Status"
echo "Go login to the stupid health care provider thing, you have $timeSeconds seconds go go go!"
Is this script fancy? No, not in the slightest. It simply grabs an auth token from each server, then calls the blocking endpoint and pauses blocking for 60 seconds. Why 60 seconds? Because that’s all we generally need in the house to make this work. “Justin, you could make this better with AI.” Take your bullshit elsewhere; it’s a freakin’ shell script with curl and jq. I don’t need to burn the world up to write such a utility.
The script is effective for dealing with the annoyance of trying to talk to a doctor—which I blame not on Pi-Hole or my blocklist, but rather the shitty trackers everyone has on their links. Simple, to the point. Just how I like my scripts.
Justin Ribeiro, Ph.D.<br>Dr.<br>Justin<br>D.<br>Ribeiro<br>Ph.D.
I ♥ the open web. Film photographer and mediocre darkroom printer. Maker of sometimes interesting things. Coder of open source curiosities.<br>Researcher of creativity. Always exploring.
Web site<br>Mastodon<br>Codeberg<br>Github<br>YouTube<br>justin@justinribeiro.com<br>justin.ribeiro@case.edu<br>justin.ribeiro@stevens.edu