Before everything, please note:
- This is a tech doc only for Pros
- Incorrect settings of port forwarding will result in ports being opened on your WAN interface
- Pi-hole won't work with the following features of Firewalla on the same device. Firewalla's features always have a higher priority. These features are: Family Protect, Adblock, and DNS over HTTPS.
- You should not enable conditional forwarding in most cases or it might create a DNS loop.
- This is for Firewalla in router mode. For Red and Blue, please refer to this guide: https://help.firewalla.com/hc/en-us/articles/360034635473
1. Create Configuration Files
You have to choose
- a network as your docker network, we use 172.16.0.0/24 in this tutorial
- a static IP for your pi-hole instance, we use 172.16.0.2 in this tutorial
- a password for your pi-hole management console, we use firewalla in this tutorial
Create the following folder/files
/home/pi/.firewalla/run/docker/pi-hole/docker-compose.yaml
version: "3"
# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
services:
pihole:
container_name: pihole
image: pihole/pihole:v5.1.2
environment:
# set a secure password here or the default will be firewalla
WEBPASSWORD: 'firewalla'
# Volumes store your data between container upgrades
volumes:
- '/data/pi-hole/etc-pihole/:/etc/pihole/'
- './etc-dnsmasq.d/:/etc/dnsmasq.d/'
- '/etc/localtime:/etc/localtime:ro'
restart: unless-stopped
cap_add:
- NET_ADMIN
networks:
default:
# static IP address for pi-hole
ipv4_address: 172.16.0.2
networks:
default:
driver: bridge
ipam:
config:
# your chosen docker network here
- subnet: 172.16.0.0/24
2. Start and Test Pi-hole
run the following commands to install and start pi-hole
cd /home/pi/.firewalla/run/docker/pi-hole sudo systemctl start docker sudo docker-compose pull sudo docker-compose up --no-start sudo ip route add 172.16.0.0/24 dev br-$(sudo docker network inspect pi-hole_default |jq -r '.[0].Id[0:12]') table lan_routable sudo ip route add 172.16.0.0/24 dev br-$(sudo docker network inspect pi-hole_default |jq -r '.[0].Id[0:12]') table wan_routable sudo docker-compose up --detach
If everything is good, pi-hole will be booted and you can now access its management portal by visiting http://172.16.0.2 in your browser.
If you use docker_compose.yaml from above, your docker web password is "firewalla"
3. Set Pi-hole as DNS for your network.
Now proceed to the network settings on Firewalla App, assign 172.16.0.2 as the primary DNS server for the networks that you want to enable Pi-Hole.
- Tap on Network Button
- Tap on the Top right edit button
- Tap on the LAN segment you want to change DNS to pi-hole
- Scroll down and change the primary DNS to 172.16.0.2
- Save and you should be able to see DNS requests coming up in the management console.
4. Persisting The Configuration
You must be on firewalla 1.971 or later for this
create folder /home/pi/.firewalla/config/post_main.d and the following file
/home/pi/.firewalla/config/post_main.d/start_pi_hole.sh
sudo systemctl start docker sudo ipset create -! docker_lan_routable_net_set hash:net sudo ipset add -! docker_lan_routable_net_set 172.16.0.0/24 sudo ipset create -! docker_wan_routable_net_set hash:net sudo ipset add -! docker_wan_routable_net_set 172.16.0.0/24 sudo systemctl start docker-compose@pi-hole
And you are ready to go.
BONUS: Use DoH on Pi-hole
Change your docker-compose file as following
version: "3" # More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/ services: cloudflared: container_name: cloudflared # Restart on crashes and on reboots restart: unless-stopped image: cloudflare/cloudflared:2020.12.0 command: proxy-dns environment: - "TUNNEL_DNS_UPSTREAM=https://1.1.1.1/dns-query,https://1.0.0.1/dns-query,https://9.9.9.9/dns-query,https://149.112.112.9/dns-query" # Listen on an unprivileged port - "TUNNEL_DNS_PORT=5053" # Listen on all interfaces - "TUNNEL_DNS_ADDRESS=0.0.0.0" # Attach cloudflared only to the private network networks: default: ipv4_address: 172.16.0.3 pihole: container_name: pihole image: pihole/pihole:v5.1.2 environment: # set a secure password here or the default will be firewalla WEBPASSWORD: 'firewalla' DNS1: '172.16.0.3#5053' DNS2: 'no' # Volumes store your data between container upgrades volumes: - '/data/pi-hole/etc-pihole/:/etc/pihole/' - './etc-dnsmasq.d/:/etc/dnsmasq.d/' - '/etc/localtime:/etc/localtime:ro' restart: unless-stopped networks: default: # static IP address for pi-hole ipv4_address: 172.16.0.2 networks: default: driver: bridge ipam: config: # your chosen docker network here - subnet: 172.16.0.0/24
Restart your docker service and it's done
sudo systemctl restart docker-compose@pi-hole
Notes:
1. If the DNS booster is enabled. The DNS requests from clients will be first redirected to the local DNS cache on Firewalla, which further uses pi-hole in docker as the upstream DNS server. So you will see all DNS requests from Firewalla's IP of docker network, which is 172.16.0.1.
2. In case docker service doesn't start, please follow this guide to reset your docker service. https://help.firewalla.com/hc/en-us/articles/360060535553
3. For those who have a local search domain, you might also want to check: Difference between Search Domain and Local Domain
All product names, logos, and brands are the property of their respective owners. All company, product, and service names used in this website are for identification purposes only. The use of these names, logos, and brands does not imply endorsement.
References:
https://github.com/pi-hole/docker-pi-hole/
https://docs.docker.com/compose/
https://mroach.com/2020/08/pi-hole-and-cloudflared-with-docker/
Comments
89 comments
@Support Yes, I do have DNS over HTTP turned on as well as family protect for some devices, and Ad block for all devices.
I would like to layer these features together, and basically use pi-hole as the final upstream DNS before going to public DNS. My goal is to have the robust and thorough ad-blocking capability of pi-hole for my whole network, but still use FWG's additional protection features (family protect, DoH, domain blocking rules) for specific groups of devices. Is there a way to do this?
I managed to get all client ips to show up in pihole on docker on my firewalla gold. just needed to create this config file on the firewalla:
/home/pi/.firewalla/config/dnsmasq_local/00-config.conf
add the following two lines:
add-subnet=32,128
add-mac
and restart the service
Now I can see what each client is going to instead of just 172.16.0.2
Be careful about using this on your Firewalla. It works great, for sure. BUT, the default for the logging database retention (365 days) is not overridden. Consequently, the database will continue to grow until it fills up the /data partition. This causes other problems with Firewalla.
If one does wish to retain this solution running on the Firewalla, updating the pihole-FTL database retention period is recommended.
As a general rule, I am now leaning toward not running anything but the core Firewalla services on the Firewalla Gold. The storage space seems pretty small and is likely sized for the core purpose of the Firewalla solution and updates.
I've purchased a Raspberry Pi for the purpose of running ancillary solutions (Pi-hole, Homebridge, etc.). Although the prospect of running multiple services (containers) on the Firewalla is really attractive, weigh that desire against potentially losing Firewalla functionality.
Hello all,
I have managed to get pi-hole working as per the tutorial above. My only issue is that I cannot get it to stay persistent. I followed the steps shown in part 4 precisely. However if I restart the Firewalla I am left with a DNS issue as the pi-hole docker does not start on its own. If I manually run the .sh file created or run all commands manually it works without issue again. Any suggestions on how to make the firewalla run that .sh file on start-up?
Let me reboot and check it again. I created a "tools" folder where we keep our goodies and notes. We also save things on /sata-drive, our 500GB SSD drive. But that's another post :-)
You can't save anything on any of the tmpfs mounts. You might think you are putting it in /etc/init.d/ but what is actually happening is that it's getting overwritten by /media/root-ro/etc/init.d/ on reboot.
Of course, I could also be 100% wrong.
What error are you getting? When I post the code it's clean?
So far this looks great. We're pretty lazy and since this isn't persistent across reboots we created a script to perform all the steps above.
Wont give all the details - if you need more than what is presented here then you might not be ready to play with this.
We created a script named start-pihole with this content:
@Rob Dennison:
The network is defined between the services tage specifying "pi_hole" and the network tag specifying "default".
As to your issue, I have a question: any chance you didn't delete the ~ or # that appears by default in some editors when you create a new file? It just sounds to me like the issue is that the network line (at least) somehow got commented out in your .yaml file. Reopen it in nano or vi or whatever you use and check.
It’s awkward on mobile devices to interact with a Pi-Hole through a browser.
Try this iPhone app:
https://apps.apple.com/us/app/pi-hole-remote/id1515445551
Very well-designed UI.
Thanks for responding @Larry Lindenbaum, but I cannot see "pi_hole" in the YAML file at the top of this page, just "pihole".
The only underscores in the YAML file are in "container_name", and "ipv4_address".
In answering your second question, no there aren't any rogue tildes or hashes... screencap here:
Not asking for a review of my code... just a quick look at the OP's YAML file to see if I've got this right or wrong.
Thanks again!
DNS booster actually intercepts DNS traffic and redirects them to the local DNS server on the box. All kinds of DNS-based features, e.g., safe search, family protect, AD block, DNS over HTTPs, and domain-based blocking are implemented on the local DNS server. Some of them simply return static domain IP mapping, others will further query the configured upstream DNS server, e.g., OpenDNS, Cloudflare DoH server, etc.
So if the pi-hole in docker is set as the upstream DNS server, it will see all requests coming from Firewalla. If you run a pi-hole in another device, it will see requests coming from different devices in the same network segment, but still from Firewalla if original requests are from devices in a different segment.
In conclusion, if the DNS booster is enabled, all DNS traffic going through the box will be redirected to the local DNS server. The local DNS server may further query the upstream DNS server if necessary.
Warning...absolutely clueless when it comes to docker networking...
For the docker network, can I use my existing scheme?
For example, I use 192.168.250.0/24 for addressing.
Ideally, I'd like to set the pi-hole instance to 192.168.250.2.
Thank you in advance for entertaining a rookie question. :-)
bks
Nice! I like that portainer has the ability to autoremove the container (I have never used it). Your point on using the latest release bothers me as well on the Gold. I should probably modify the autostart script to delete all existing docker containers and let it pull the latest image again though. I don't know why I didn't think about that before your comment!
Or maybe just try portainer... lol
In the meantime I need to get back to making AdguardHome work on the Gold. And still do my xmas shopping...
@Hans, sorry, I meant to include that.... I am not using Family Protect, Ad block or DNS over HTTPS on FWG. I tried disabling DNS booster for this client and I got the same results with or without DNS booster enabled. This particular client is hard wired to a switch connected directly to the FWG. I also tried clearing the cache of the DNS Booster using the app. No change.
Totally agree with @Joel, if you do plan to use a lot of storage, please leave the service off Firewalla. (or you can get a USB storage and use that instead) We get too many of these cases in our support, and it is wasting us a lot of time (which we can use for other things) supporting and debug disk full errors.
Wow. Mine is about 729 MB. So do I trim this thing down?
Any guidance on installing on a Blue Plus?
Here's the environment:
Following the Gold guide for pi-hole my docker-compose.yaml file is identical except my network is as such:
In STEP 2 of the guide is where I hit the roadblock:
Error: argument "lan_routable" is wrong: "table" value is invalid
Any advice on how to proceed?
@Brian Shimkus
While you can change the network driver from the config file to specify "host" instead of "bridge" and create your container in the existing network space, it does not get assigned an ip address and would use the localhost address for everything. Also, I THINK that Firewalla has already pre-assigned the Docker network to be 172.17.0.0/24 so my guess is you'd end up with an address in that space unless you also go ahead and reassign the entire docker network to use the host driver. Anyway, this seems overly complicated and I am not sure what you're really going to get out of it in the end. It's potentially helpful if you're running something in a container that requires a whole lot of port forwarding, as that eliminates the need to specify the ports.
@Mauricio Guerrero: Should not interfere with anything if you enable it and should still work as intended.
Ok, I'm confused! :)
Pi-Hole setup and working perfectly, configured for Cleanbrowsing DNS servers.
1) If I turn on "Conditional Forwarding" in Settings > DNS, so I can see hostnames from the Firewalla, then the DNS query figures stop incrementing, but it shows hostnames. If I turn it off, I lose hostnames but the stats increment!
2) I downloaded the Pi-Hole Remote App as above, and when using it, clicking on Statistics, it is telling me to check API and Privacy. API QR scanned, and Privacy setting set to everything.
Might be whiskey .. but feeling a little confused!
Btw, anyone tried this docker image that includes pihole and unbound yet?
https://github.com/chriscrowe/docker-pihole-unbound/tree/master/one-container
I'm considering giving it a go...
Thanks Andy!
I was looking and I don't have that directory, in .... /pi-hole/ I only have docker-compose.yaml and etc-dnsmasq.d, which has 01-pihole.conf and 06-rfc6761.conf...
No etc-pihole to be seen...
Any reason why, for Cloudflared, the version needs to be
instead of 2022.3.1?
Tried it with 2022.3.1 and doesn't seem to work for now.
Will try again with the older version...
@Ma At
Not sure what you mean. Can you explain what you mean that your “set-up [is] regularly breached?” What “exploit” do you think you are seeing?
What “Cloudflared container”? Are you using Cloudflare DNS over HTTPS in your Pi-Hole docker?
Can you share the logs?
The solution was here: https://help.firewalla.com/hc/en-us/community/posts/4593345581331-cloudflared-exec-format-error
@mariusz figured out that the docker version that is being referred to in the opening post doesn't work for the architecture of the Firewalla Purple (maybe it does work for Gold, can't verify).
It appears to me that there is some kind of exploit in cloudflared container. I have my setup regularly breached and the logs are pointing to a large amount of activity in dockerd.
https://help.firewalla.com/hc/en-us/community/posts/1500001172701-Pihole-and-Unbound
Have a look at this before you try.
Firewalla are looking into it, but I failed to get it work
Is there a way to set maxdbdays and dbinterval with this approach?
In a 'non-docker' setup, this would be set in pihole-ftl.conf...
Thanks in advance!
If anyone is interested in an ansible implementations of this post, more coming soon.
https://github.com/hhcalder92/ansible-firewalla-role/
After moving the YAML file into docker/pi-hole, the "up" won't work because "pool overlaps with other one on this address space"
I removed the old route ("sudo ip route del 172.16.0.0/24"), so the only route left that's close is 172.17.0.0/16. There is also a default route through my WAN IP, but I don't think I should touch that ;)
The rest are VPN, upstream DNS and LAN.
shows no containers (running or not), but
shows the following networks
That docker_default looks suspect because I learned earlier in this thread that the network created is based on the folder the YAML file is in, so this could have been created when I UPed the container from run/docker. The network name "docker_default" is scary, but when I inspect it:
This looks like the culprit. Before I go all "sudo docker network rm eb90dc2fedb3" on this, is there something I'm missing?
I don't want to irreparably break things here so I have to reflash the Gold and rebuild the network config, rules, groups, etc.
I've tried everything but I can't even ping the ip I selected for the pi-hole, I believe the docker has another ip and I don't know how to change it ... my network uses the 192.168.25.0/24 range
if someone can help me, I will be more thanked!
I am having odd results. I've followed the directions and I end up with my clients having their DNS queries resolved, but nothing gets logged (or blocked) by pi-hole.
Here is dig output from one of my clients
$ dig @172.16.0.2 a-ads.com
; <<>> DiG 9.9.5-9+deb8u19-Raspbian <<>> @172.16.0.2 a-ads.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38369
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;a-ads.com. IN A
;; ANSWER SECTION:
a-ads.com. 300 IN A 104.26.14.247
a-ads.com. 300 IN A 172.67.69.167
a-ads.com. 300 IN A 104.26.15.247
;; Query time: 24 msec
;; SERVER: 172.16.0.2#53(172.16.0.2)
;; WHEN: Wed Sep 30 13:04:46 EDT 2020
;; MSG SIZE rcvd: 86
And here is the dig output from the firewalla box itself
(Firewalla) $ dig @172.16.0.2 a-ads.com
; <<>> DiG 9.11.3-1ubuntu1.11-Ubuntu <<>> @172.16.0.2 a-ads.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40266
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;a-ads.com. IN A
;; ANSWER SECTION:
a-ads.com. 2 IN A 0.0.0.0
;; Query time: 1 msec
;; SERVER: 172.16.0.2#53(172.16.0.2)
;; WHEN: Wed Sep 30 13:04:32 EDT 2020
;; MSG SIZE rcvd: 43
The pi-hole UI reflects these results too, sort of. The query from the FWG box shows as "172.16.0.1" and there is no record at all from the client machine.
The really odd thing is that I followed these instructions for 1.970 (back when the ip address was 172.0.0.2 and there were not the post_main.d instructions) and everything worked then. I saw all of my clients activity in pi-hole and things were being blocked (I even had to whitelist somethings for my kid's school.)
Anyone have any ideas?
Please sign in to leave a comment.