Temporary bypass by IP address

Edit: Good night I didn't realize I had typed such a freaking long post. If someone knows how to shorten it so it doesn't show all at once until you click on it, let me know.
Edit edit: Thank you @Bucking_Horn for the editing tips

If you only have a Pi-hole install and do NOT own a MikroTik, I'm sorry, but this post is not for you.

I know what I am about to list won't help everyone that uses the Pi-hole software,
but it should help anyone with a custom router running MikroTik OS, or maybe pfSense or DD-WRT and they also use Pi-hole for filtering.

I designed a way to temporarily allow a person to bypass the filtering offered by Pi-hole.
This method works per IP address, but also requires that client/IP have a web browser to
use the automated bypass method I will explain. If you have a device that doesn't have a
web browser, and still need to bypass filtering, you can either set that devices DNS to NOT
use your Pi-hole for DNS, or access the MikroTik router to add the device to the bypass list.
I know there are other methods out there where you statically set your client devices mac-address
into a dnsmasq area of your Pi-hole, but my method can be dynamically implemented on the fly by the client.

Requirements are as follows
1. MikroTik router.(as I stated before, you might be able to use pfSense or DD-WRT)

2. Web server. This is not a strict requirement. You can use the built in web server
that is installed by Pi-hole if you want to(lighttpd). So you can use just a MikroTik and just a
raspberry pi to achieve your goal. The web server is only there if you want a "pretty splash" page
for your Pi-hole block page.
If you want my html example pages, can someone tell me how to include them on this post?
If I paste the html code it doesn't include it all. Yes I know how to upload the files to an external media host, or host them myself, but yeah, uploading the files to here is escaping me for some reason.

For the networking geniuses out there, I will include the MikroTik direct export commands at the
kind of beginning so you can get cracking.

For the Pi-hole or web server geniuses out there, maybe you can take what I did and integrate it
into your web server or Pi-hole install better. Maybe Pi-hole could integrate a way to take commands
and cause users to bypass their filtering, maybe, who knows. I'm good at networking, not so much
web servers and how they function.

Pro's of what I designed
-Allows a single user in your household to bypass your DNS filtering provided by Pi-hole
-Allows a single user in your household to bypass DNS filtering no matter the provider
-Allows the web server to also run on your Pi-hole install. (I didn't "invent" running a web server on a Pi-hole install, this should be obvious)

Con's of what I designed
-I used lighttpd for authentication on the web server serving the splash page, I stink at it so it doesn't work all the time when you push Logout on the web page
-Sub folders that serve out the 30minute or 60minute splash page won't display images(I'm a networking guy, not web server guy. Didn't bother figuring this out)

MikroTik rules

For my fellow networking guys/gals, as promised here are the MikroTik commands.
These rules detect traffic coming IN to the router. If you want the rules to be triggered
with traffic passing THRU the router change the chain=input to chain=forward.

/ip firewall filter
add action=add-src-to-address-list address-list=filterDNSbypass
address-list-timeout=30m chain=input comment=
"Port knock rule to bypass DNS filters for 30 minutes" dst-address=
X.X.X.X dst-port=30 in-interface-list=WAN-IN protocol=tcp
src-address-list="Public-IP's_we-OWN"

add action=add-src-to-address-list address-list=filterDNSbypass
address-list-timeout=1h chain=input comment=
"Port knock rule to bypass DNS filters for 1 hour" dst-address=
X.X.X.X dst-port=60 in-interface-list=WAN-IN protocol=tcp
src-address-list="Public-IP's_we-OWN"

The above rules set all TCP requests for port 30 or 60 that are destined for an IP address
of your choosing to be added to a dynamic Address List in your MikroTik. These rules do NOT
allow you to bypass your Pi-hole filtering yet. But they do add your IP address to a list that will be used on the next rules.

/ip firewall nat
#Rule1
add action=dst-nat chain=dstnat comment=
"Port Forward for Web Filter - FilterBypass Web server" dst-address=
X.X.X.X dst-port=80 protocol=tcp src-address-list=
"Public-IP's_we-OWN" to-addresses=192.168.X.X to-ports=80

#Rule2
add action=dst-nat chain=dstnat comment=
"Port Forward for Web Filter - FilterBypass - TCP Rule" dst-port=53
protocol=tcp src-address-list=filterDNSbypass to-addresses=192.168.X.X
to-ports=53

#Rule3
add action=dst-nat chain=dstnat comment=
"Port Forward for Web Filter - FilterBypass - UDP Rule" dst-port=53
protocol=udp src-address-list=filterDNSbypass to-addresses=192.168.X.X
to-ports=53

#Rule4
add action=dst-nat chain=dstnat comment=
"Port Forward for Web Filter - Ads - TCP Rule" dst-address=
X.X.X.X dst-port=53 protocol=tcp src-address-list=
"Public-IP's_we-OWN" to-addresses=192.168.X.X to-ports=53

#Rule5
add action=dst-nat chain=dstnat comment=
"Port Forward for Web Filter - Ads - UDP Rule" dst-address=
X.X.X.X dst-port=53 protocol=udp src-address-list=
"Public-IP's_we-OWN" to-addresses=192.168.X.X to-ports=53

The first rule is only needed if you want external users to see the splash page you create.
If you host the Pi-hole software internally, the first rule is not needed.
You will also notice that all of the rules are limiting who can see/use my filtered DNS.
Yes, that means I had these rules on a public facing DNS server firewall(MikroTik).
I created an Address List with public IP addresses that we own and are only allowing those IP's
to use our filtered DNS. They are NOT forced to use them, it is opt-in.
The 2nd and 3rd rules allow clients that have triggered the secret TCP port to bypass
the 4th and 5th rule where I direct their DNS requests to internal NATTED IP addresses that host
filtered Pi-hole installs. These rules MUST be in this order otherwise they will not allow you
to bypass filtering.

If you offer the Pi-hole DNS IP addresses thru DHCP from your MikroTik, you only need
rules 2 and 3 in your /ip firewall nat
If you want to FORCE internal household users to ALWAYS use your Pi-holes for DNS and only allow them
to bypass filtering when they trigger the secret port, replace rules 4 and 5 with the following.
I would lean away from forcing public IP customers of yours to use your Pi-hole DNS servers.
The below rules if implemented in a public scenario would force their traffic to use your DNS,
even if they have static DNS applied to their network adapter.

/ip firewall nat
#Rule4
add action=dst-nat chain=dstnat comment=
"Force HOME inside users to use only specified DNS" dst-port=53 protocol=
tcp src-address=192.168.XX.0/24 to-addresses=
10.10.10.2/31 to-ports=53

#Rule5
add action=dst-nat chain=dstnat comment=
"Force HOME inside users to use only specified DNS" dst-port=53 protocol=
udp src-address=192.168.XX.0/24 to-addresses=
10.10.10.2/31 to-ports=53

You will notice the "to-addresses" is listed as a /31, which indicates two IP addresses.
Yes this is a type of High Availability mode I also run. Instead of telling your clients to
only use a single IP for DNS, I direct their traffic towards 2 IP addresses at once and the
Pi-holes respond to the clients. It has caused no problems when implemented on an internal
household environment. It should also work on a public setting if you wanted backups for each
public facing DNS server.
If you only have a single Pi-hole server, then change the /31 to a /32.

If you plan on only implementing the MikroTik bypass rules, then you can stop reading.
The rest of this post is for the splash page and authentication.

If you made it thru reading the above about the MikroTik rules and want a simple splash page
with buttons that trigger the MikroTik rules, please continue your journey downward.



access%20granted

VERY detailed explanation of how the bypass system works

##NOTES##
You do not have to build a splash page to bypass your
pihole filtering, but you will need a router like a MikroTik.
If you use somebody else's filtered DNS servers, you can still use a MikroTik
to bypass the filtering for you by using the "secret" URL method I explain below.

If you do build a splash page, you do not have to use the authentication
method I propose in my instructions below. You could simply build a splash page
with buttons that point to your secret URL that triggers the MikroTik rules.

You don't have to enter the IP address of your pihole to bring up the splash page,
you can alter your hosts file under the /etc/ folder (path is /etc/hosts) to "trick"
everyone's device into thinking the IP address of your pihole is also accessible thru say
bypass..example.com. HOWEVER!! That hosts file is ONLY read by your device WHILE you are
using the pihole for DNS. If you use the trick to bypass your filtering, well guess what,
your computer no longer knows how to get to bypass..example.com, and won't be able to get
back there until your MikroTik timer rule times out and you start using your pihole for filtered
DNS again. That might be EXACTLY what you are looking for, and it might not be.

If you put a real domain name into your pihole servers hosts file and the pihole servers are publically
accessible because you didn't firewall them correctly,and you don't own that domain name,
be expecting a nice letter from
the owner of that domain or a legal authority. You have now spoofed the name of a
legitimate domain name which is a crime in some countries. Make sure your pihole servers are
firewalled correctly.

The username and password method to access the "secret" URL uses the
lighttpd built in functions for authentication. They stink. I cannot get the Logout
button in my html files to work all the time. Sometimes yes, sometimes no. The only
100% method to NOT let someone bypass the filtering again by looking in their web
browsing history, is to delete their web browsing history.

If you are running Ubuntu inside a Microsoft Hyper-V virtual machine,
run the below command to get rid of the floppy drive error message during boot.

echo "blacklist floppy" | sudo tee /etc/modprobe.d/blacklist-floppy.conf
sudo rmmod floppy
sudo update-initramfs -u
sudo shutdown -r now

The html files I wrote that you place inside your 30m, 60m or 24h folders contain
the "secret" URL pointed at an image source. I needed a way for the URL to be visited or triggered,
but didn't want the URL to be contained in your browsing history.
##NOTES##

These instructions are going to assume that you do NOT have pihole installed, but you
DO have an operating system installed. Raspian for a Raspberry Pi or Ubuntu for
virtual machine.
So on a blank install of Raspian(this works in Ubuntu as well) follow the below.
Install Webmin first. It will allow you web gui access to your files so you don't
have to use a monitor all the time.

sudo apt-get install perl libnet-ssleay-perl openssl libauthen-pam-perl libpam-runtime libio-pty-perl apt-show-versions python
wget http://prdownloads.sourceforge.net/webadmin/webmin_1.930_all.deb
sudo dpkg --install webmin_1.930_all.deb

If you are running Ubuntu, install git before you run the pihole install.

sudo apt-get install git

Then perform the pihole install using the below commands.

sudo git clone --depth 1 GitHub - pi-hole/pi-hole: A black hole for Internet advertisements Pi-hole
cd Pi-hole/automated\ install/
sudo bash basic-install.sh

During the pihole install, it will ask you if you are using a static IP(you should be),
And it will ask several other items but the most important is installing lighttpd web
server. Go ahead and choose that option for these instructions.
When the pihole install is finished, it will give you the url you need to log into
your pihole web gui. Ignore it for now and change the random password the install
generated for you with the below command.

pihole -a -p

We are still ignoring the web gui for pihole and going to change a few things using
Webmin. Log into Webmin using https://your-ip-here:10000/
Once inside Webmin, access the "Others" options on the left, then "File Manager" underneath
it. Then access /etc/pihole/pihole-FTL.conf and add one of the below lines to the file.

BLOCKINGMODE=NXDOMAIN
or
BLOCKINGMODE=IP-NODATA-AAAA

NXDOMAIN kills the DNS request. It makes your web browsing a lot faster because it's
not redirecting you but doesn't allow a splash page when it blocks something.
IP-NODATA-AAAA tries to grab IPv6 requests and throw them towards
your IPv4 filtering while also responding to IPv4 requests.
IP-NODATA-AAAA allows you to display a splashpage when you are blocked.

Now in your Webmin gui, back up a little and go to /etc/lighttpd/lighttpd.conf
Supposedly when the pihole software is updated, it writes over changes made in lighttpd.conf,
so you can of course add the below commands to lighttpd.conf, but they might delete
themselves later after a pihole system update.
Check the lighttpd.conf file and make sure the below line(s) are there. We will instead
be adding our changes to the external.conf file.

include_shell "cat external.conf 2>/dev/null"

Before you close out of lighttpd.conf, comment out the below line. To comment out
something so the line isn't used, place a # in front of it. We will be changing
where pihole's block page is located. Comment out this line, save the file and close it.

server.error-handler-404 = "/pihole/index.php"

Next open up external.conf in the same lighttpd folder.
Add the below.

server.error-handler-404="pihole/CustomBlockPage.html"
server.modules += ( "mod_auth" )
auth.debug = 2
auth.backend = "plain"
auth.backend.plain.userfile = "/home/lighttpd/.lighttpdpassword"
auth.require = ( "/bypassfilter/" =>
(
"method" => "basic",
"realm" => "Password protected area",
"require" => "user=admin|user=guest"
)
)

What we just did is change which file pihole uses to display
the block page. This file will be located under /var/www/html/pihole but we'll get to
that later. We also added a section that forces the directory /var/www/html/bypassfilter
to be password protected. We will place our pihole "bypass" files in that folder.
We still need to create a username and password file in /home/lighttpd/ named .lighttpdpassword
and we need to adjust what usernames we want available to bypass the pihole filter.
The "require" line above shows one user as admin and one as guest. Add as many as you want making
sure to leave a pipe | between each user. Save and close the file.
In Webmin go to /home and create the folder lighttpd inside of it. Then inside /home/lighttpd
create the file named ".lighttpdpassword"
Add your usernames and passwords to the file like in the below example

admin:password
guest:password

The authentication method we chose is basic. The username and password are transmitted
unencrypted across your network. If you worry about that method, or are using this
in a public setting, then don't use it. There are other ways to authenticate.
Save and close .lighttpdpassword
Open a terminal window inside Webmin under Others>Command Shell
Enter the below to make sure lighttpd can use your password file.

sudo chown www-data:www-data /home/lighttpd/.lighttpdpassword

Now in Webmin go to Others and File Manager. Then go to /var/www/html
Create a folder called "bypassfilter" inside your html folder. Create folders inside your
bypassfilter folder that correspond to the time frames you want to to bypass your pihole filter.
I created one for 24hours, one for 60minutes and one for 30minutes.
The folder structure will look like this with the html index files inside each of them.

/var/www/html/pihole/CustomBlockPage.html (this html file has clickable button links that point to the files in the other folders below)

/var/www/html/bypassfilter/24h/index.html
/var/www/html/bypassfilter/60m/index.html
/var/www/html/bypassfilter/30m/index.html

Build your CustomBlockPage.html and other index files and upload them to the correct directories.
Yes you can use Webmin to upload your files.
I have included samples of the files I am using on my raspberry pi's.
Once you have everything loaded, reboot your pihole server. You can test your block page
and bypass filter buttons by browsing to the IP of your pihole server.
The way the bypass works is by loading a secret URL from within the 30m, 60m or 24h html files.
The index.html file contains an image link that isn't an image. It's actually a URL link
to your MikroTik/router that signals it to allow your computer to bypass filtering. The pihole
just makes the process "prettier", it in NO WAY allows your computers to bypass filtering.

Now for the actual bypass filtering part which uses a MikroTik router.
You CANNOT use the bypass method on a normal home router. You will need a MikroTik router
or maybe pfSense. I believe the pfSense operating system can perform the following.

The way the bypass works is by using a "port knock" rule to detect traffic hitting a
particular port either passing thru(forward rule) or hitting(input rule) your router.
The port knock rule adds the source(client) IP to a dynamic address list in your MikroTik which
then times out after a period of time. 30minutes, 60minutes, 24hours etc. While the timer
is ticking away, a dstnat rule picks up your traffic and FORCES you to bypass your pihole
filtering and use another DNS server until the timer finishes counting down. When the timer
is finished/done, you will again start using your pihole for filtering.
Granted, filtering doesn't IMMEDIATELY pick back up because you still have DNS cached on
your machine but oh well.
Yes this works on a private network, and yes this will work on a public network,
like an internet service provider.

So for example if I choose to type into my browser 10.10.10.10:30 and create a
port knock rule to listen to requests destined for 10.10.10.10 TCP port 30, I can have the
MikroTik add my source(client) IP to an address list that will time out in 30 minutes.
Which TCP port doesn't matter unless you are destining the request towards an IP address
that is active or being used. You could still use the port knock rule, but you might
want to pick a port that isn't used by the remote device.

On an internal/private network, you can perform the filtering and bypass process in
several ways. If your clients are being handed filtered DNS through DHCP or have static
DNS set to their devices, you only need the aforementioned rules. One port knock rule for
each time frame(30minutes 60minutes etc) and two dstnat rules. One dstnat is for TCP traffic,
the other for UDP traffic. This method will also work if you are using a publically offered
filtered DNS service, and want to bypass it without getting into your NIC settings or your
router settings.
Another method is to FORCE all DNS requests coming through your home router to use your
filtered pihole DNS, and then while they are using your filtered DNS, if they visit a
special secret URL, your MikroTik will now force their traffic to use an unfiltered DNS
server of your choosing, be it another pihole inside your home or an external DNS server.

If you are using the DNS servers on a public setting, you need to place them behind your
MikroTik/router by using port forwarding so the public ports are forwarded to your pihole's
private ports. Your MikroTik would look for requests coming from YOUR public IP addresses
destined for the "secret" ports, add that source/client IP to an address list, and then
force that traffic to use a non-filtered DNS server that is also behind your MikroTik.
How well does it work? Really well. I can statically set a public filtered DNS IP on my computers NIC,
then while I am browsing the internet, visit the secret URL, and now my traffic
destined for the filtered DNS is automatically forwarded
to my non-filtered DNS servers. I never had to change the settings on my NIC, and I am back
to using filtered DNS within a short time period.
For your pihole to be publically used or used by another subnet that it currently is not
a member of, you have to enable the following.

Access your pihole gui thru the web interface, go to Settings and then the DNS tab.
Choose the option "Listen on all interfaces, permit all origins" and click save.

Fair warning about using the DNS filtering provided by Pi-hole on a public network.
One: They restrict your usage of their brand and name in a public setting in such a way
where you can't broadcast the fact that you are using the name Pi-hole and that you created
the name Pi-hole. I would consult Pi-hole directly before blasting the fact that you have
a publically available Pi-hole that your customers can use.
Two: This should be fairly obvious. If you open up ports in your firewall so the outside
world can access your DNS filtering, make sure you firewall that sucker so only certain
IP addresses or subnets that YOU are in control of are allowed to use it.

Once you have the MikroTik port knock rule in place, and the dstnat rules for TCP and UDP,
you are ready for testing. You can now visit your secret URL and for whatever time period
you specified, you are now unfiltered.
Of course if you build your splash page on your Pi-hole install, you can now have a nice
web gui to allow users to bypass your filtering.strong text