Before everything, please note:
- Pi-Hole has dropped support for Ubuntu 18.04. If your Firewalla is using Ubuntu 18.04, follow our guide to reflash your box:
- This is a tech doc only for advanced users.
- This is for Firewalla in Router mode.
- 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.
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
Use the values above unless you know exactly what you are doing and have a reason to change them.
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 ip -4 rule add from all iif br-$(sudo docker network inspect pi-hole_default |jq -r '.[0].Id[0:12]') lookup lan_routable priority 5003
sudo docker-compose up --detachIf you are using Gold SE, run one more command to add SNAT for the docker network.
sudo iptables -t nat -A POSTROUTING -s 172.16.1.0/16 -o eth0 -j MASQUERADEIf 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 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-holeAnd you are ready to go.
BONUS: Use DoH on Pi-hole
Only available for Gold and Gold Pro
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/24Restart 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. We strongly recommend keeping DNS Booster enabled.
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.
Known Issue
Note: This was fixed in our 1.976 release so this step is no longer necessary.
On ubuntu 22.04 and later, when docker starts up, it may load a kernel module br_netfilter which conflicts with ubuntu 22.04 if you are using Smart Queue. Dockers managed by Firewalla will automatically handle this, but if you create docker instance, you may need to run:
sudo rmmod br_netfilterafter starting docker service or the firewalla routing function may break.
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
118 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?
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:
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?
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?
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
@Donny - Firewalla has plenty of built-in DNS services available. See these articles for more info.
https://help.firewalla.com/hc/en-us/articles/4570608120979-Firewalla-DNS-Services-Introduction
https://help.firewalla.com/hc/en-us/articles/360007210473-Where-Firewalla-Can-Block-
Installing Pi-hole on Firewalla is for advanced users who would prefer to use Pi-hole instead of Firewalla's built in services for DNS based ad blocking. You may be fine simply using the built in services provided by Firewalla. It's just nice that Firewalla does allow expansion like this to add enhanced functionality where needed.
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.
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.
@Firewalla
I made a small change and used the latest image for the docker pull.
From:
To:
Bringing the pihole into my gold seems to have increased my internet performance and now I can turn on all of the firewalla features. Although per device statistics is a nice to have, turning off DNS booster doesn't work for me because it's an all or nothing and all new devices get it turned on. Perhaps this will be fixed in the future but not a big deal.
The firewalla gold is incredible and it has also dramatically simplified my home segmentation strategy.
10/10
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...
@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.
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!
Is anyone aware of how to enable IPV6 support?
Here is the script I use.
$ cat update_pihole.sh
#!/bin/bash
cd /home/pi/.firewalla/run/docker/pi-hole
sudo docker-compose pull
sudo docker-compose down
sudo docker-compose up --detach
sudo systemctl start docker-compose@pi-hole
@ chris, I also run this at the end:
to remove unused old Docker containers
The admin page for pi-hole is actually at: http://172.16.0.2/admin
Bookmark this link for future use.
I followed these instructions like exactly but am unable to access http://172.16.0.2 or http://172.16.0.2/admin from my Firewalla LAN network, I receive an address unreachable error in the browser. Thoughts?
Poorly written.
I run the latest.
@chris hewitt nice script, it almost worked for me. It doesn't appear that the YAML file that is created from your cat command turns out as valid YAML though, so when starting the docker-compose command came with with errors.
I used http://www.yamllint.com/ to validate the YAML and paste that in to the script instead and that seemed to fix the problem.
What exactly doesn't persist between reboots? the entire docker? or that the docker doesn't start automatically? or...
Hmm, seems that the startup script does not persist if I put it in /etc/init.d/ like most do.
@Chris Hewitt thanks, good tip. I didn't realize that was what was happening. How do you make your startup script run in this situation then? /media/root-ro/etc/init.d/ is not write-able for good reason, I would assume.
I found that the docker container was intact after a reboot, but docker was just not started and neither was the pi-hole docker container. So, as such, do you think your start up script really needs to redo the whole thing? why couldn't you just run the last few commands to start the docker container up?
The folder /media/root-ro/etc/init.d/ is not writable and for good reason. It keeps people like me from breaking my toys permanently. It also helps support people, like our friends at Firewalla, have an enjoyable life. All they have to do is tell people with issues to reboot and the machine is back to a known-good state.
Running my script
For me, I just run ...
... after rebooting.
I haven't had enough time to really look into this to figure out everything it's doing.
I'm not sure....huh interesting. When I used your whole script, it failed. When I paste in from YAML lint, it works. I have no idea *shrug*
OK, so you have not found a way to make the script auto execute.
Did you find that having DNS booster enabled and applying to devices on the Firewalla caused problems with pi-hole? For example, I was having issues with devices that were covered by the family filter and DNS booster function not showing up as hitting the pi-hole for DNS requests. Once I removed them from the DNS booster, then they started showing up.
This appears to make sense because DNS booster functionality is supposed to intercept DNS traffic and redirect it to the FWG. But, for some reason, it's going to the FWG internal DNS server, and not to the configured DNS server I had set in the LAN configuration.
I haven’t tried to auto execute. But you should be able to do that with an “@reboot” crontab entry.
I don’t use the DNS Booster. This links seems to say DNS Booster will work with Pi Hole - https://help.firewalla.com/hc/en-us/articles/360034635473?fbclid=IwAR15r7_G4XsSKEWcU-IipIsMyNNDUikubBP9EGWzlrCXfenmuYNcvih9sos
Actually, I think that the article you linked seems to imply that family guard (and by extension, anything to do with filtering by DNS, including DNS booster) will not work with pi-hole. This makes sense--it all depends which DNS server is the "upstream" server in your network.
Quoting:
Warning: The conflict of DNS blocking between Pi-Hole and Firewalla
If you install Pi-Hole on Firewalla, Pihole will become the upstream DNS server of Firewalla. All DNS traffic will route through Firewalla first then to Pi-Hole, so that you will only be able to see localhost and Firewalla on the Pi-Hole portal.
Devices -> Firewalla -> Pi-Hole -> further upstream DNS servers
To get individual stats on devices, you will have to install Pi-Hole on a separate device and use it as DNS server in your router DHCP setting. But in this way, you will lose all the per-device DNS features (Family Protect, Ad-Block, Safe search, etc.) on Firewalla, because Firewalla will only see DNS traffic from Pi-Hole.
Devices -> Pi-Hole -> Firewalla -> further upstream DNS servers
--and--
Step 3. Turn off Family Protect on Firewalla App. Family Protect Feature and Pi-Hole can't be activated at the same time.
@Support thank you, perfect explanation and what I was needing to know concerning the "order" of DNS servers when DNS booster is enabled.
I think my additional complication to this is that IF that upstream DNS server is on the LAN, DNS booster should NOT be enabled on the DNS server in the LAN. (I have a DNS server running on my windows server box to serve up my local domain DNS)
My setup:
192.168.1.118 = Windows server DNS to serve up DNS for domain, set to forward DNS requests to 172.0.0.2
192.168.1.1 = FWG
172.0.0.2 = Pi-hole docker running on FWG
192.168.1.xxx = Client covered by DNS booster
DHCP settings are set such that DNS server 1 is 192.168.1.118 (my windows server)
If I disable DNS booster on 192.168.1.118 (windows DNS server), this setup works. FWG is "downstream" from my windows DNS server, so any (uncached) domain name lookup is passed from the FWG to my windows DNS server, which then passes to pi-hole and I see the resulting activity.
Effective DNS request chain: client->FWG via DNS booster intercept->192.168.1.118->172.0.0.2->public DNS (this is acceptable for me)
If i enable DNS booster on 192.168.1.118, then I no longer see ANY activity in pi-hole.
Effective DNS request chain: client->FWG via DNS Booster intercept->loops back to FWG via DNS booster intercept?????....but somehow the domain names resolve, despite no logged activity on the pi-hole.
Tried a different way:
Set DHCP settings so that DNS server 1 is set to the pi-hole directly, 172.0.0.2.
In this situation, ANY device that has DNS booster enabled on it will not have any activity show up on pi-hole.
Effective DNS request chain: Client -> FWG via DNS booster intercept -> loops back to FWG via DNS booster intercept????? No activity logged in pi-hole....but somehow, still resolving the domain name.
But if you disable DNS booster on a client with DNS server set to the pi-hole, then it starts working and pi-hole shows activity from that client.
Effective DNS request chain: client->172.0.0.2->public DNS
Of course, disabling DNS booster on a client removes many of the DNS based protection, as mentioned previously so this is not desired for me.
I don't know how to explain this behavior. I theorize that maybe DNS booster is applied to 172.0.0.2 automatically, but there's no way in the UI to disable it for an IP not in the LAN.
@Hans
Setup 1:
In theory, the DNS loop will occur and the DNS query will not work. However, Firewalla has a mechanism to automatically disable DNS booster on devices that are set as DNS resolver on the box. The periodical check is done once every minute and very likely the DNS booster was automatically disabled on 192.168.1.118 soon after you enabled it.
Setup 2:
If you enable DNS booster on a device, the DNS request chain is: client -> FWG -> 172.0.0.2 -> public DNS. In theory, you should see activities from FWG on pi-hole.
If you disable DNS booster on a device, the DNS request chain is: client -> 172.0.0.2 -> public DNS.
DNS booster is only applied to devices that are monitored by Firewalla. It is not applied to docker container.
@Support
When your say "devices that are set as DNS resolver on the box" you mean any ip that is set as a dns server in the dhcp config? As there is no other way I know of to set dns servers...
I would like to get setup 2 to work (client->fwg via dns booster->pi-hole), but as I have tried, turning on dns booster on devices makes it such that no dns requests hit the pi-hole. Shall I open a support ticket and have you all take a look?
Please sign in to leave a comment.