OPNsense 26.1: Unbound DNS Returns with Improved Stability
How I restored Unbound on OPNsense 26.1 after the 25.7 DNS mess, using dnsmasq for DHCP registration and reliable local hostname resolution.
When OPNsense 25.7 broke DNS in my homelab, I gave up on Unbound faster than I wanted to. I switched to dnsmasq-only because I needed the network to behave again, not because I thought it was the better long-term design. It solved the immediate pain, but it also felt like a compromise. I lost the resolver setup I actually preferred, along with some of the visibility and features that made Unbound worth using in the first place.
With OPNsense 26.1, I finally moved back.
What convinced me was not marketing language or optimistic forum posts. The important change is that the official OPNsense documentation now clearly describes the hybrid setup: Unbound as the primary DNS resolver for clients, dnsmasq as the DHCP server and local hostname authority on a non-standard port. That matters because it turns the setup from a workaround into a documented deployment model.
In my case, that hybrid design has been stable again. Local hostnames resolve properly, external DNS works without the random failures I saw in 25.7, and I get to keep Unbound as the front door for the network.
What Changed in OPNsense 26.1?
The practical difference is not that dnsmasq suddenly became unimportant. Quite the opposite. OPNsense now documents dnsmasq as the service that should handle DHCP leases and dynamic hostname registration in small and medium setups, while Unbound stays the validating recursive resolver.
That split matches how I wanted the system to behave all along:
- Unbound answers DNS queries from clients on port 53
- dnsmasq keeps track of DHCP leases and local hostnames
- Unbound forwards only the local zones to dnsmasq
- External domains stay in Unbound, either recursively resolved or forwarded upstream if you intentionally choose that mode
After the 25.7 upgrade, I did not trust any DNS setup that looked good only in the GUI. I wanted something I could reason about. This design is simple enough to debug, but still gives me the stronger resolver features that dnsmasq alone does not provide.
Why I Moved Back From Dnsmasq-Only
I do not want to overstate this. A dnsmasq-only setup can be perfectly valid, and if your network is stable and your requirements are modest, there is no moral victory in changing it just because a newer article told you to. Still, in my setup, dnsmasq-only always felt like the emergency mode I settled for after 25.7.
I wanted Unbound back for a few reasons:
- I prefer a validating recursive resolver at the edge of my network
- I like having Unbound statistics and blocklist features available again
- I want clients to talk to one DNS service on port 53, while the DHCP and lease registration logic stays behind the scenes
- I would rather follow the documented OPNsense layout than keep carrying an old workaround forward forever
The important point is this: dnsmasq did not disappear from my setup. It just moved into the role it is actually very good at.
The Role Split I Use Now
Before touching settings, I found it useful to think about the service boundaries first. That saved me from recreating the same confusion that bit me during the 25.7 migration.
Unbound
- Listens on port 53 for client queries
- Resolves internet domains recursively by default
- Validates DNSSEC for normal upstream lookups
- Caches answers for the whole network
- Forwards only local zones to dnsmasq
dnsmasq
- Hands out DHCP leases
- Registers hostnames from DHCP clients
- Listens on port 53053 for local DNS lookups from Unbound
- Acts as the authority for local zones such as
lan.internal
One detail worth calling out: OPNsense explicitly warns that domain-specific query forwarding in Unbound is not DNSSEC validated. That is fine here because those forwarded zones are my own internal names, not public internet domains.
My Working Configuration
This is the setup I would use again on a clean OPNsense 26.1 install, and it is also the path I used to move back from dnsmasq-only.
Put Unbound Back on Port 53
I started by making Unbound the DNS endpoint for clients again. The main thing I changed from some older guides is that I stopped forcing specific interfaces unless I had a real reason. The current OPNsense Unbound docs explicitly recommend leaving the listening and outgoing interfaces at their defaults unless you know why you need to tighten them.
Go to Services -> Unbound DNS -> General and set:
-
Enable: checked -
Listen Port:53 -
Network Interfaces: keep the default, usuallyAll, unless you have a very specific routing reason not to -
DNSSEC: enabled if you want validation, which I do
If you previously ran dnsmasq on port 53, move dnsmasq away from 53 first or Unbound will not start.
If Unbound does not come up, do not guess. Run
configctl unbound checkon the firewall shell or use the diagnostics page first.
Move dnsmasq to the Connector Role
The next step is the part that made the whole design click for me. dnsmasq does not need to be the client-facing DNS server. It only needs to be reachable by Unbound for the local zones.
Go to Services -> Dnsmasq DNS & DHCP -> General and set:
-
Enable: checked -
Listen Port:53053 -
Interface: choose the interfaces where dnsmasq should serve DHCP -
Do not forward to system defined DNS servers: checked -
Do not forward private reverse lookups: checked -
DHCP fqdn: checked -
DHCP default domain:internalor left empty if you intentionally want to use the system domain -
DHCP register firewall rules: checked
That DHCP fqdn option is the key piece. It ensures a lease like nas01 on my LAN becomes nas01.lan.internal, not just a bare hostname floating around with inconsistent suffix handling.
Forward Local Zones From Unbound to dnsmasq
Once both services were on the right ports, I linked them with Unbound query forwarding. This is the clean hand-off point between recursive DNS and local lease-based DNS.
Go to Services -> Unbound DNS -> Query Forwarding and add one forward zone and one reverse zone per network.
For a LAN on 192.168.1.0/24, I use:
| Field | Value |
|---|---|
| Domain | lan.internal |
| Server IP | 127.0.0.1 |
| Server Port | 53053 |
And for reverse lookups:
| Field | Value |
|---|---|
| Domain | 1.168.192.in-addr.arpa |
| Server IP | 127.0.0.1 |
| Server Port | 53053 |
If you have more than one VLAN or subnet, repeat the pattern for each range. In other words, do not try to fix a multi-network lab with one vague forwarding rule and hope it sorts itself out later.
The DHCP range domain and the Unbound forwarding domain must match exactly. Most local DNS failures I saw came down to that one mismatch.
Configure DHCP Ranges in dnsmasq
At that point I moved on to the DHCP side. This is where dnsmasq actually learns the hostnames it will later answer for.
Go to Services -> Dnsmasq DNS & DHCP -> DHCP ranges and create a range for each interface.
For my main LAN, the relevant fields look like this:
| Field | Value |
|---|---|
| Interface | LAN |
| Start address | 192.168.1.100 |
| End address | 192.168.1.199 |
| Domain | lan.internal |
| Lease time | 86400 |
If you use a guest VLAN as well, give it its own domain such as guest.internal and create matching forward and reverse entries in Unbound. I would not reuse the same local zone across unrelated segments unless I had a good reason.
Keep the Firewall Itself Pointing at Unbound
I also cleaned up the system DNS settings so the firewall does not quietly fall back to whatever the WAN hands it.
Go to System -> Settings -> General and set:
-
Primary DNS:127.0.0.1 - Remove stale external DNS entries unless you intentionally need them
- Disable
Allow DNS server list to be overridden by DHCP/PPP on WAN
That keeps the firewall itself aligned with the design instead of bypassing it behind your back.
Testing What Actually Matters
I never treat a saved configuration page as proof. DNS is too easy to misconfigure in ways that look fine until a lease renews, a reverse lookup happens, or one client starts using a stale resolver.
I test three things: external resolution, local hostname resolution, and whether the services are listening on the ports I expect.
Test External DNS From a Client
From a machine on the LAN, I start with plain queries against the firewall:
1
2
3
dig @192.168.1.1 github.com
dig @192.168.1.1 cloudflare.com
nslookup github.com 192.168.1.1
If that fails, I stop there. There is no point troubleshooting local names while the main resolver path is already broken.
Test Local Hostname Resolution
The next test is the one that mattered most in my lab because this is where 25.7 burned me.
1
2
3
dig @192.168.1.1 nas01.lan.internal
nslookup printer.lan.internal 192.168.1.1
ping laptop.lan.internal
Short names such as ping laptop may also work if your client picked up the DHCP search domain correctly, but I always test the full name first. It removes one whole layer of client-side guesswork.
Check That Both Services Are Listening
When I need to confirm what the firewall is really doing, I use the shell instead of assuming the UI state is truthful.
1
2
sockstat -4 -6 -l | grep -E 'unbound|dnsmasq'
configctl unbound check
What I want to see is simple:
- Unbound listening on port
53 - dnsmasq listening on port
53053 - no validation errors from
configctl unbound check
If you previously enabled KEA DHCP or still have legacy ISC DHCP pieces active, check those too. dnsmasq cannot serve DHCP cleanly if another service is already occupying the same role.
Troubleshooting the Common Failure Modes
This is the part I wish I had written down during the 25.7 migration. Most breakage in this setup is boring and predictable once you know where to look.
Local Names Still Do Not Resolve
If internet DNS works but host.lan.internal does not, I check these in order:
- The DHCP range domain matches the Unbound forwarding domain exactly
-
DHCP fqdnis enabled in dnsmasq - The client actually sends a hostname during DHCP
- dnsmasq is listening on
53053 - The lease was renewed after the configuration change
In practice, the mismatch between internal, lan.internal, and the firewall system domain is where I lost the most time.
Reverse Lookups Fail
Reverse DNS is easy to forget because many people do not test it until a log viewer or SSH tool starts showing raw IP addresses everywhere.
If PTR lookups fail, the reverse forwarding domain is usually wrong. For 192.168.1.0/24, the forwarder must be 1.168.192.in-addr.arpa. If you use another subnet, calculate the reverse zone properly instead of copying mine and hoping muscle memory will save you.
Unbound Starts, but Clients Still Use Something Else
I have hit this more than once on laptops and phones. The firewall can be perfect, but the client is still using an old DNS server from a stale lease, a manual override, or a VPN client.
On the client, verify the resolver directly:
- Windows:
ipconfig /all - macOS:
scutil --dns - Linux:
resolvectl statusor/etc/resolv.conf, depending on the distro
If the client is not pointing at the OPNsense interface address, the DNS stack you carefully fixed on the firewall is not the stack the device is actually using.
You Want Forwarding Instead of Full Recursion
I stayed with Unbound recursion because that is what I wanted. If you prefer upstream forwarding, OPNsense supports that through Unbound query forwarding or DNS over TLS. Just be deliberate.
I would only switch to forwarding mode if I had a clear reason, such as policy control, upstream filtering, or a resolver stack like NextDNS or AdGuard that I intentionally want to keep in the path. Otherwise, I would let Unbound do the resolver work it was built for.
Should You Switch Back If You Are Still on dnsmasq-Only?
My answer is yes, with one condition: do it because you want the hybrid design, not because you feel guilty about using the simpler workaround.
If your dnsmasq-only setup is stable and you do not care about Unbound features, there is no emergency here. On the other hand, if you originally moved away from Unbound only because 25.7 made it painful, OPNsense 26.1 gives you a clean path back.
That is exactly why I updated my own setup. I did not want to keep living on a workaround after the platform had caught up and documented the intended design properly.
References
- OPNsense Dnsmasq DNS & DHCP documentation
- OPNsense Unbound DNS documentation
- NLnet Labs Unbound manual
- IANA Special-Use Domain Names registry
Final Thoughts
This setup feels sane again, which is honestly what I wanted more than anything else. After the 25.7 detour, I did not need DNS to become more clever. I needed it to become understandable again.
For me, OPNsense 26.1 finally gets back to that point. Unbound handles the network-facing resolver job. dnsmasq handles DHCP and local names. Each service has a narrow role, and when something breaks I know where to look first.
That is a much better place to be than the half-broken confusion I dealt with during the last upgrade cycle.
