Limit access to your Pi-hole with iptables on Ubuntu/Linux

I wanted to create a Pi-hole that I could use outside of home and share with friends and family. I did not, however, want to share it with the entire world. Since Pi-hole comes with an admin interface (if you choose to install), you helpfully have a webserver and php available.

What I did was to block everything with iptables, create a bash script that is called via php to add the visitng ip address to the port 53 allow udp/tcp in iptables.

The PHP script:

<?php
#/var/www/html/setdnsip.php

$ip = $_SERVER['REMOTE_ADDR'];

if($_GET['secret'] === "supersecret"){
	echo shell_exec('whoami');
	echo "adding ip " . $ip . " tcp/udp port 53 to iptables";
	echo "<br>";
	$m=shell_exec("sudo /home/saturn/setdnsipallow.sh " . $ip);
	echo $m;
}else{
	echo "404 not found";
}
?>

I added a $_GET check in there just in case. I call this file setdnsip.php and added it to /var/www/html/.

In /home/saturn/ I have the aforementioned shell script: setdnsallowip.sh:

#!/bin/sh
#/home/saturn/setdnsallowip.sh

IPTOADD=$1
TIME=$(date)
if [ $IPTOADD ]; then
  printf $IPTOADD; echo "added: "  $IPTOADD " on " $TIME " by " $USER"/"$(whoami) >> /home/saturn/ipadd.log;
  iptables -A INPUT -s $IPTOADD -i eth0 -p udp --destination-port 53 -j ACCEPT;
  iptables -A INPUT -s $IPTOADD -i eth0 -p tcp --destination-port 53 -j ACCEPT;
  iptables-save > /etc/iptables/rules.v4
else
  echo "no var sent"
fi

The default policy for the INPUT chain is DROP

iptables --policy INPUT DROP

In order to allow the owner of the lighttpd process to execute the script, you have to add permission: create a file in /etc/sudoers.d/ like setdns with the following:

#/etc/sudoers/setdns
www-data ALL=NOPASSWD: /home/saturn/setdnsallowip.sh

and your script will be allowed to run.

This is all it takes for a simple setup that you can use and share among friends/family. Just visit http://yourpiholeip/setdnsip.php?secret=supersecret and the ip address you are on will be added to the port 53 allow list so any device there can use your Pi-hole.

Any suggestions for improvements/upgrades welcomed.

This makes for a nice simple ad blocker that can be set up for a few bucks a month on something like Digital Ocean or Rackspace or something that you can share with friends or family. It also makes it easy to update when your ISP changes your ip address.

Why don't you use a VPN to access Pihole or route DNS traffic?

A potential risk I see for your approach (if I have understood correctly), would be that a friend is accessing your pihole from a public entry point. Imagine a open wifi at the airport. Your script would add the public IP of the airport to the allow rule. Everyone within the airport's wifi would get the same public IP and could access your pihole.

I'll be blunt:
This is not even barely an excuse for proper security precautions.

Your solution is sending an unencrypted plain text password over an unsecure channel to match it against a single hardcoded plain text equivalent.

Anyone along the path from a prospective client to your web server can read and access your supersecret in plain text.
Furhermore, that plain text password will get stored in any browser's cache that calls your URL, sitting there waiting to be readily accessed even long after the actual call has been made. The same would be true for any caching HTTP proxy along the path, so an attacker wouldn't even have to be lucky enough to be online at the moment of access to pry the password from an unknowing client. Attackers could conveniently scan the caches at their leisure. And that's just naming the primary weakness.

Effectively, you are but an inch away from running an open resolver.

Should your supersecret get in the hands of malevolent attackers and worst comes to worse, you'll have a hard time explaining to potential prosecutors why you have given those attackers your password to use your DNS server for an amplification attack, and if you succeed you haven't, they'll ask you why you didn't take measures to effectively protect it.

I'd advise strongly against using your solution.

That said, your use case for accessing a private Pi-hole instance in a cloud over public networks is valid.

Using a VPN is the proper way to allow secure access via encrytped connections to authenticated clients only.

3 Likes

If a VPN is not feasible, you're better off with a solution that supports DoT (e.g so you can just add the URL to the Private DNS field on Android (other OS's may vary)

I have set up DoT on my own network with some rules in traefik to recieve the request and forward it onto my Pi-hole.. I probably haven't done it very well, however, so I wont share how I've done it here!

However, a quick google turns up this:

(haven't 100% vetted it, but it looks like a good starting point)

Looks cool. Will check it out. Thanks for sharing.

It’s not supposed to be a “super secret secure can’t crack me” solution, it’s a personal, do-it-smartly-if-you-want type thing. Example is: I go to my family members house. I visit the php page to add the ip. I throw the pi-hole on their router dhcp as primary dns with cloudflare as backup. Rinse and repeat.

I’m not doing the vpn route because I can dhcp the pihole - I can throw it on my router and all devices on my lan use the pihole.

I’m not handing out the addip php page Willy nilly, and I wouldn’t advise anyone to do such. I’m also not worried about getting my traffic sniffed at my sister and laws house and would never add an IP address that I didn’t trust. Keep an eye on iptables and remove old entries and you’ll be fine. Realistically, isp dhcp addresses don’t change very often around here so not really worried about a former ip being allowed for too long either but something to be aware of surely.

Btw, I’ve been running this setup for 2+ years now with 0 issues.

Zero issues for you. :wink:

Not joking: Do you have IPv6 connectivity at home? Note that IPv6 rules will have to be added as well (or, at the very least, you should set the IPv6 INPUT policy also to drop). IPv6 is managed using ip6tables

Zero issues for anyone. I keep a close eye on it, and never have any clients show up save for the random scanners (shodan etc) every once in a while.

I'm not using ipv6 at home and it is not enabled on the pihole machine either.

Screen Shot 2020-09-14 at 10.40.02 AM

I'm just being cautious here, not trying to say what you do is crap :slight_smile:
Only to raise awareness for possible copycats that may not be well-aware of how to handle firewalls properly.

Just out of personal interest: How do you deal with dynamic IP addresses? Or do they all have static assignments?

So whenever they recognize that DNS is dead, they have to manually navigate to the address quoted above to re-register their IP with your server, right?

Be aware that there is nothing like such a "fallback" as you described here:

See this excellent explanation:

My expectations were different, too, but I can only confirm this on all sorts of network hardware I used to own myself.

The DNS may leak how you configured it.

1 Like

Oh interesting, I didn't know about that dns issue....thanks for bringing it up, will have to investigate.

Historically, over the last couple of years anyway, I've just let things run until adds started showing. When I start seeing ads (at my or family members house), I would check if the IP changed and if so would re-visit the addip php page.

Like mentioned in another reply, around here with my local ISP's, it's pretty rare for the DHCP IP address assigned to the cable modems to change. Typically only happens after power outage or it's manually triggered by support or myself trying to fix a connection issue or something. But that is how I've been doing it--DHCP changes, ads start appearing, re-add the IP to the pihole.

Are you certain that the primary/secondary isn't just a linux thing? I'm getting conflicting info:

That is not how it works, both DNS servers are equal and valid, but the order in which you specify them determines how a client will ask them, the only time a client will ask the secondary is if the primary doesn't respond or isn't there, if the primary doesn't know it doesn't send you to the second, the primary will do a lookup for you then reply with the address.

I presume your talking bout Windows ?
If it were that simple:

The DNS Client service keeps track of which servers answer name queries more quickly, and it moves servers up or down on the list based on how quickly they reply to name queries.

And this bit:

1 Like

Interesting, thanks. So I guess that only leaves Apple products? Do they honor primary/secondary dns? My Mac Pro seems to honor the settings in the network preferences. Also seems OK on my iPhone/iPad.

I typically only use iOS devices at home (except for a single pc which has uBlock origin and a FireTV), so maybe that's why I haven't had any issues with primary/secondary settings so far.

Does it matter ?
Only thing that matters is that different products have different implementations and you want to provision for all.
You cant have all Apple products at your home or in an enterprise.

EDIT: One that probably goes unnoticed from that link you posted previously:

Mike400
Mace
Mike400 This person is a Verified Professional Sep 5, 2017 at 7:15 PM

Also, when you have multiple DNS servers make sure they're configured to transfer all their zones back and forth.

Sure you can. Unless my dog started gaming while I'm at work...and if you have a small business, you can make your employees use whatever you want.

BUT, again, this is a hobby-do-it-if-you-want thing that I did and shared hoping maybe someone might find it useful. If you don't think it's useful, don't do it. :man_shrugging:

Or use ZeroTier does not req any open ports.

3 Likes

Well you said it was intended to "share with friends and family.".
I reckon they dont all share the same view on choosing hardware.
And you already mentioned not everything being Apple at your place:


Yes you can but Apple doesnt have enterprise capable servers, switches, routers, load-balancers, telephone systems, and so on that are essential for your business.

EDIT: Dell PowerEdge, HP ProLiant DL380 G7, NetApp FAS6200 ... they dont sound really Apple like :wink:

Again, for the nth time, this is not an enterprise solution. It’s a hobbyist, do-it-if-you-want use for the pihole. Use it or don’t. Make it better if you want. Or don’t use it at all!

It works for me and has for the last 2+ years. I’ve set up a couple family members and friends houses with it as well over the last 2+ years. Haven’t had any issues. Just my anecdotal experience, your mileage may vary.

Very cool. Will check it out. Thanks for sharing.

I see this advanced a bit, however, let me share some more insight I got over the past couple of years: The primary/secondary thing was never really "only use the secondary if the primary failed" in any product I have seen in my network. I first couldn't believe in @DL6ER's ultimate statement that such a thing does not exist, but the more I looked, the clearer the picture got.

Windows/Microsoft changed how they do it from XP to 7 and then 8. I don't have Windows at home, but I can only recommend to take a good look at the mentioned Windows version and/or the article timestamp. Otherwise, you may take something serious they have changed - again - meanwhile. I cannot say how it is done currently.

Pi-hole has settings to behave in three ways:

  • always use the fastest among the configured DNS servers (the default)
  • always send everything to all and just use the first reply (may be a little faster sometimes, but creates a notable amount of extra queries)
  • always respect the order of the servers as in /etc/resolv.conf (this is the true: "if 1 fails, ask 2. If 2 fails, ask 3, etc.")

You can stretch my description about "Pi-hole" to the entirety of Linux. It depends on the system, they can theoretically do all three.

I wouldn't give too much value on what they're writing. You should only trust technical descriptions or talking to people you can assume they know what they do. I do believe that the Pi-hole people know what they are saying - especially the main developers where one of them wrote the article I linked to above.

Just another example for why this link you found is not a good source:

If the primary lookup fails it falls over to the root DNS servers. These are defined and update by most DNS servers.

The root DNS servers only know one thing: What other (!) name servers are responsible for the top-level domains (TLDs) such as com, nl, de, etc. They can not provide any further replies, especially, they can not answer full requests like for pi-hole.net

Only special recursive resolvers know how to deal with the root servers. They query Who is net from the root server, then go to the next one, one (sub)domain after another. This is a tedious path and I highly doubt any end-user devices are doing this. This is precisely what the big players (Google, Cloudflare, OpenDNS, etc.) are doing. Not even routers are doing this.

Even when they said "this may be oversimplifying things", this is not the case: It is just plain wrong.

Another example is the last reply (which is the one you quoted). There is no proof and I did technical verification both on Linux and Windows that this is not true. I wouldn't just believe it because they say this. Maybe they expected something else from the "primary/secondary" vocabulary, did some very simple testing and say that DNS does still work when specifying an invalid primary IP address. This does not prove at all that the primary would be used exclusively otherwise.


TL;DR

To my knowledge, all operating systems worth mentioning default to the "measure and use the fastest" approach.

Typically, you cannot change this with the exception of Linux in general and maybe some routers based on Linux (like OpenWRT, etc.).

2 Likes

I'm trying to make it better by pointing out the wrong assumption that all devices will query primary first and only hop to secondary when primary failing.
With your home setup you probably are lucky the primary DNS is quicker responding as the secondary DNS at Google 8.8.8.8.
But whenever there is a glitch or slow response from the primary, the clients could hop to the secondary and stick with that one for a while.
Thats why below is important when configuring multiple DNS servers:

Mike400
Mace
Mike400 This person is a Verified Professional Sep 5, 2017 at 7:15 PM

Also, when you have multiple DNS servers make sure they're configured to transfer all their zones back and forth.

Both DNS servers need to hold the exact same records or you'll get erratic behaviour.
And you cant do zone transfers / sync Pi-hole's blocklists with Google's 8.8.8.8 :wink: