I Thought Unbound Was Enough for My Home DNS
Table of Contents
- The Problem Was Outside My Network
- Why I Didn't Remove Unbound
- Separating DNS Policy From DNS Transport
- Why DNSCrypt-Proxy?
- Letting DNSCrypt-Proxy Pick the Resolver
- Unbound Still Remains the DNS Server Devices See
- What Actually Changed?
- Isn't Running Two DNS Services Overkill?
- One Important Limitation
- The Result
For a long time, Unbound was enough for my home network.
It ran on OPNsense and handled DNS for almost everything at home: local records for internal services, cache, and blocklists to prevent devices from reaching unwanted domains.
The setup was simple:
Home Devices
|
v
OPNsense
Unbound
|
v
Internet
Most of the time, it worked without issue.
The problem only appeared once DNS traffic left my router.
The Problem Was Outside My Network
Upstream DNS behavior on local consumer connections can be unpredictable.
Public resolvers occasionally become unreachable, certain domains get blocked at the provider level, and DNS handling varies depending on the ISP in use. A resolver that works cleanly on one connection might fail or get intercepted on another.
For everyone else in the house, this is frustrating.
They don't care which resolver is configured upstream, what filtering rules an ISP enforces, or why a specific domain suddenly stops resolving.
They just want the internet to work.
I could have configured DoH manually on each device, but that defeats the purpose of managing network DNS centrally.
I wanted the router to handle it transparently.
Why I Didn't Remove Unbound
Replacing Unbound entirely seemed like an obvious first thought.
If the objective is encrypted upstream transport, why keep another local resolver in front of it?
Because Unbound was already handling core local network duties:
- local DNS host overrides and DHCP registrations
- query caching
- internal domain resolution
- local blocklists
- centralized DNS policy for all connected clients
I wanted to bypass external ISP tampering without giving up local control over what my network resolves.
ISP decides what I can resolve -> I don't want this.
I decide what my network can resolve -> I still want this.
Dropping Unbound meant discarding a working internal resolver setup.
The practical fix was changing how queries were forwarded after Unbound processed them.
OPNsense Unbound DNS reporting overview showing query statistics, blocklist resolution metrics, and client activity over 24 hours
Separating DNS Policy From DNS Transport
The updated architecture separates internal resolution from external transport:
Home Devices
|
| DNS
v
+-----------------+
| Unbound |
| |
| Local records |
| Cache |
| Blocklists |
| Local policy |
+--------+--------+
|
| forwarded query
v
+-----------------+
| dnscrypt-proxy |
| |
| Resolver select |
| DoH transport |
+--------+--------+
|
| HTTPS / 443
v
Public Resolver
Unbound dictates how DNS behaves inside the local network.
dnscrypt-proxy manages how external queries leave the router.
Splitting those two responsibilities produced a cleaner setup than trying to force one tool to do both jobs.
Why DNSCrypt-Proxy?
Unbound can natively encrypt forwarded queries using DNS-over-TLS (DoT).
That would keep the architecture single-layered:
Device
|
v
Unbound
|
| DoT / 853
v
Public Resolver
For many setups, DoT is sufficient.
In my case, port-based filtering was the main issue. DNS-over-TLS uses TCP port 853, making it trivial for an ISP or middlebox to identify and drop.
DNS-over-HTTPS (DoH) transports queries over port 443, blending with standard HTTPS web traffic:
port 53 = plaintext DNS (easily intercepted)
port 853 = encrypted DNS (easily blocked by port)
port 443 = DoH over HTTPS (standard web port)
While DoH is not immune to IP-based blocking, it removes simple port-level restrictions. dnscrypt-proxy provides a lightweight way to put that transport directly behind Unbound.
Letting DNSCrypt-Proxy Pick the Resolver
I preferred not to hardcode a single upstream resolver.
dnscrypt-proxy maintains upstream source lists and can select responsive resolvers matching defined criteria.
Configured for DoH:
dnscrypt_servers = false
doh_servers = true
server_names = []
Leaving server_names empty allows dnscrypt-proxy to pick from all matching public DoH servers rather than tying the whole network to a single provider.
I also enforce privacy constraints on the resolver pool:
require_dnssec = true
require_nolog = true
require_nofilter = true
This guarantees upstream resolvers do not reapply third-party filtering on top of my own rules.
OPNsense DNSCrypt-Proxy configuration listening on 127.0.0.1:5353 with DNS-over-HTTPS, DNSSEC, NoLog, and NoFilter enabled
Unbound Still Remains the DNS Server Devices See
Client devices do not interact with dnscrypt-proxy directly.
DHCP continues handing out OPNsense as the primary DNS server on port 53.
Phone ------+
Laptop ------+
TV ----------+
IoT ---------+
|
v
Unbound
|
v
dnscrypt-proxy
|
v
DoH
This avoids per-device configuration across phones, laptops, and smart TVs.
Clients connect to Wi-Fi, receive their network lease, and automatically benefit from local blocklists and encrypted upstream transport.
OPNsense Unbound DNS Query Forwarding custom forwarding rule sending queries to 127.0.0.1:5353
What Actually Changed?
Latency remained largely unchanged. DNS still responds in standard lookup times.
The functional difference is reliability: domains previously affected by upstream interference or port hijacking resolve normally across all devices.
Once configured, the system requires no manual intervention.
Isn't Running Two DNS Services Overkill?
Chaining two daemons adds another process, configuration file, and potential failure point:
Unbound -> dnscrypt-proxy
If the only requirement were simple router-to-upstream encryption, native DoT in Unbound would be cleaner.
However, the complete set of requirements demanded more:
local DNS records
+ local ad/malware blocking
+ centralized DHCP distribution
+ encrypted upstream queries
+ DoH transport over port 443
+ automatic resolver failover
Breaking the system into distinct roles makes the architecture modular:
Unbound
+-- local DNS resolution
+-- caching
+-- blocklists
+-- client query policies
dnscrypt-proxy
+-- upstream resolver selection
+-- DoH encapsulation over HTTPS
One Important Limitation
DoH is not an impenetrable circumvention tool.
Network operators can still block known resolver IP ranges, inspect SNI during TLS handshakes, or restrict outbound HTTPS.
Its primary value is narrower: queries leave the local network as encrypted HTTPS traffic on port 443 instead of unencrypted UDP on port 53 or targeted TCP on port 853.
For home network reliability, that has solved the problem.
The Result
The final query path:
HOME NETWORK
|
v
+----------------------+
| OPNsense |
| |
| Unbound |
| |
| * local records |
| * cache |
| * blocklists |
| * local policy |
+----------+-----------+
|
| localhost
v
+----------------------+
| dnscrypt-proxy |
| |
| DoH-only resolver |
| selection |
+----------+-----------+
|
| HTTPS :443
v
+----------------------+
| Public Resolver |
+----------------------+
Unbound manages local policy, caching, and internal records. dnscrypt-proxy ensures external queries egress safely over DoH.
The setup has been running in the background without needing maintenance—which is the best quality network infrastructure can have.