OPNSense + PiHole

The issue I am facing:
Hi. I recently configured OPNSense router in my home network and I wanted to do it "right" so I did it like described in Pi-hole and OPNsense – Pi-hole
First of all, it didn't work (without unbound), PiHole Query log showed "REFUSED" for all queries in "Replay" column, after enabling DNSSEC it also showed "ABANDONED" in most cases. DNS names for local devices was resolved correctly (I think).
After adding unbound (which I didn't want but was forced to) it start working (Opnsense + PiHole - Do not resolve client hostnames - #2 by DanSchaper).
Now it seems that both remote devices and local devices are resolved correclty.

Two questions:

  • is it possible to configure everything like in the Guide without Unbound so it would work with normal DNS like google 8.8.8.8 (in my case I got "REFUSED")
  • but MORE important is it possible to configure "backup" DNS in case if PiHole is down (e.g. server update, PiHole update etc.), right now I can not "reinstall" all my docker setup because if I do that then PiHole will be down and docker won't be able to download images

Details about my system:
OPNSense: 22.1.5 (Celeron J4125 x4 2.5)
PiHole: docker pihole/pihole:latest, Docker Tag 2022.04.2 Pi-hole v5.9.1 FTL v5.14 Web Interface v5.11 (AMD Ryzen PC)

What I have changed since installing Pi-hole:

If your log shows REFUSED, can you check your "firewall log" or Suricata log if they block outgoing DNS queries, that would be most probably port 53.

I think the way to configure a backup DNS resolver is to use the fields in Upstream DNS servers called Custom 1, Custom 2 or check the preconfigured ones like Google, Cloudflare ...
https://discourse.pi-hole.net/uploads/default/original/3X/a/0/a045164feb79b41712a44eb4d3f4732c553e7431.png

If you want backup in case Pihole is unreachable, use the fields on the bottom called DNS servers,. but I think the clients might start using the backup DNS even when Pihole is available, not sure what the reason is for that,

Or are you more interested in a IP fail-over for Pihole.

PiHole was working before adding OPNsense as first DNS in chain. When it was first (set in DHCP) it was working fine.

I was thinking that this should work but in Guide there is note "Be sure that this is only Pi-hole, any other DNS server would be used and that would allow bypassing of the blocking features.".
Also I temporarily set 8.8.8.8 there and after turning PiHole off, DNS resolving was not working.
Right now if PiHole is down I have no "internet". Before OPNSense I had DHCP PiHole as first DNS and 8.8.8.8 as second DNS, I think this was working fine because clients was visible in PiHole and when I turn PiHole off, clientes was still able to resolve DNS queries through 8.8.8.8.

The reason I mentioned checking the logs, because there are new rules popping up especially the IPS rules, which basically block DNS queries not addressed to the firewall IP. Everything could be working fine and overnight bang!!!, updated rules causing "no internet complains". Just a thought.

Yes, that's a valid concern, I can't figure out if the clients start querying 8.8.8.8 only when the pihole is down, or is it random, or some type of rational algorithm.

When you had Pihole as the DHCP server, did it go down a lot?

Interesting that after the Pihole and DHCP was down your clients still functioned with the backup DNS 8.8.8.8
I wonder if there is a different setting in Pihole DHCP, and OPNSense DHCP

Maybe the different "lease expiration ?

I never used PiHole DHCP. Did it go down often, I would say not but every time it went down was because I was plying with my home server, right now I can't to that because I will "cut" my home from internet. For example I will not be able to download new PihHole Docker image if I delete old one.

I start thinking, why do I need DNSmasq on my OPNsesne router, I free time I will try to configure everything without it leaving PiHole as my first DNS in line, and Unbound on my router as second one, it should work if Unbound will resolve my local device names.
So instead of: Client -> Router (DNSmasq) -> PiHole -> Router (Unbound) i will go with Client -> PiHole -> Router (Unbound).
If this work I would be able to configure it like I had before with secondary DNS on DHCP list so if PiHole is down Clients will use something else (e.g. directly Unbound or 8.8.8.8).

I'm beginner so my configuration may have some drawback but it seems it is working.
So I disabled DNSmasq from my OPNsense Router, I set PiHole as my DNS1 server in DHCP and set DNS2 to be OPNSens router (Unbound).
It is working, when there is DNS query it goes through PiHole, if PiHole block it than it is blocked and client do not query other DNS servers. If it is not blocked it goes to Unbound where if its local device it is resolved to local IP and if its remote than it is resolved by Unbound.
Blocking was tested by trying to ping domain that was marked as blocked in PiHole query log, in respons I got: "Ping request could not find host fp.msedge.net. Please check the name and try again."

In case PiHole is down, clients query Unbound directly (it adds little delay but it is working).
192.168.100.1 = OPNsense Router
192.168.102.1 = server witch docker and PiHole




No, you need the Unbound on OPNsense to provide the LAN node names. And I'd enable DNSSEC on Unbound and leave it off Pi-hole.

Sure, add the additional DNS to the General settings:

Pi-hole is offline for the first nslookup and pi.hole doesn't resolve, but google.com does via the backup. Then after bringing Pi-hole back up I get a response for pi.hole again.

Screenshot 2022-04-12 154520

That is where you will have clients bypass Pi-hole. You want only the OPNsense IP there.


You can't have both on port 53, that's why the guide shows that dnsmasq is on 53 and unbound is on 5335 with Pi-hole using 192.168.100.1#5335 as the upstream.

Yes I know, when I was using setup from Guide I had Unbound on 5335 but right now I disabled DNSmasq so I switched Unbound to default 53. Now I have Client->PiHole->Unbound->world,
If PiHole is down then Client uses secondary DNS (from DHCP) which is Unbound so it looks like this:
Client->Unbound->world
Unbound=OPNsense router
Both my local and external DNS names seems to be resolved correctly:
image

DNSSEC - yes, enabled it yesterday, and verified it is working, also tuned Unbound a bit :slight_smile:

Not exactly. There is no such thing as primary and secondary DNS. The clients will use any DNS server available from the DHCP list. That means that some of the traffic will bypass Pi-hole and will not have any of the blocking applied.

I tested if my clients bypass PiHole, and yes, in 3.5% cases they do :frowning:
So I tried configuration like you described previously (same as in Guide + Unbound + 8.8.8.8 in System->General->DNS) but unfortunately it doesn't work. Not sure why, maybe because my PiHole is on docker so host isn't physically down, container and port are down but server is still up.
Here is my config:





When PiHole is down I get:

When it up:

192.168.100.1 = OPNsense router
192.168.102.1 = Server with docker running PiHole

Any idea how to make it working? Maybe use a macvlan in docker so PiHole would have "own" IP address?

Make sure you are not discarding blocked responses from Pi-hole:

Also disable DNSSEC on the dnsmasq service, we want Unbound to handle that.

This is set like in Guide

Oh, you are completely correct.

You do want that disabled. Sorry about that.

Where I think you have an issue is looping the DNS server, make sure that the DHCP server is not handing out a DNS server address.

Unfortunately removing DNS servers from DHCPv4 did not help. After turning down PiHole nslookup is failing.

What does an ipconfig /all show for that clients DNS servers?

And did you disable DNSSEC on the dnsmasq service?

ipconfig /all


I did renew after changing it in DHCP settings, but DNS IP is still the same 192.168.100.1 (OPNsense router).

And did you disable DNSSEC on the dnsmasq service?

Yes

Okay, then we'll have to take a look at the opnSENSE logs to see what is going on...

First let's look at the dnsmasq log at the debug level.