Configuring DoT with Unbound and Pi-hole on OPNsense
The configuration described using OPNsense’s Unbound DNS resolver set up with DNS over TLS (DoT) to encrypt all DNS queries, combined with Pi-hole on the same host to provide network-wide ad-blocking, with strict firewall rules and DNS redirect rules to prevent leaks is currently one of the most private and secure DNS setups available for a home or small office network.
Potential Additional Privacy Enhancements
Using a self-hosted, fully recursive Unbound instance on OPNsense without forwarding (making your own DNS root queries) enhances privacy but may require more maintenance and resources.
Combining DNS over HTTPS (DoH) alongside or instead of DoT could obscure DNS traffic further within HTTPS traffic, although OPNsense natively supports DoT best.
Regularly updating blocklists in Pi-hole and enabling DNSSEC validation in Unbound adds further robustness.
Using privacy-focused upstream DNS providers (e.g., Quad9, Cloudflare with privacy features) is recommended.
Overview
This setup represents a strong privacy-first DNS architecture for most users. It securely encrypts DNS, controls DNS traffic flow on the network, and filters unwanted content, all with open-source components and configurable controls.
Part 1: Enable and Configure DNS over TLS (DoT) with Unbound on OPNsense
Enable Unbound DNS Resolver:
Log into OPNsense Web UI.
Navigate to Services > Unbound DNS > General.
Check Enable Unbound and save.
Add Upstream DNS over TLS Servers:
Go to Services > Unbound DNS > DNS over TLS.
Click + Add and input trusted DNS servers supporting DoT (Cloudflare, Quad9, Google, etc.).
Leave Domain blank and enable Verify CN.
Save and apply.
Configure Unbound General Settings:
Enable DNSSEC Support for response validation.
Optionally uncheck Use System Nameservers to force use of configured DoT servers.
Save and apply.
Restart Unbound:
Restart Unbound under Services > Unbound DNS.
Part 2: Install and Integrate Pi-hole with OPNsense Unbound DNS
Install Pi-hole and Assign Static IP:
Deploy Pi-hole on a LAN device or VM.
Assign a static IP (example:
192.168.1.10
).Reserve this IP in OPNsense DHCP.
Configure Pi-hole Upstream DNS:
Access Pi-hole Admin UI.
Go to Settings > DNS.
Set upstream DNS server to OPNsense LAN IP (
192.168.1.1
).Add fallback DNS servers (Cloudflare, Quad9, etc.).
Optionally enable Conditional Forwarding with LAN subnet and OPNsense IP.
Configure Interface and Requests in Pi-hole:
Enable Respond only on interface for Pi-hole interface.
Adjust/request settings for multi-VLAN use if applicable.
Configure OPNsense DHCP to Use Pi-hole DNS:
Go to Services > DHCPv4 > LAN.
Enter Pi-hole IP (
192.168.1.10
) as DNS server.In System > Settings > General, uncheck Allow DNS server list to be overridden by DHCP/PPP on WAN.
Save and apply.
Test Pi-hole Integration:
Renew DHCP leases on clients.
Verify clients use Pi-hole for DNS.
Confirm Pi-hole receives and logs queries.
Test local hostname resolution if conditional forwarding enabled.
Part 3: Firewall Rules and CLI Commands for DNS Traffic Control
Rule 1: Allow Pi-hole to Query OPNsense Unbound DNS
Description:
This rule permits DNS traffic (TCP/UDP port 53) from Pi-hole’s IP to OPNsense LAN IP running Unbound.
Ensures Pi-hole can forward DNS requests to OPNsense.
Settings:
Action: Pass
Interface: LAN
Protocol: TCP/UDP
Source: Pi-hole IP (
192.168.1.10
)Destination: This firewall (OPNsense LAN IP)
Destination Port: 53
Description: Allow Pi-hole DNS queries to OPNsense Unbound
Place this rule at the top.
CLI Command:
opn-cli firewall rule create \
--interface lan \
--action pass \
--protocol tcp/udp \
--source 192.168.1.10 \
--destination <OPNsense LAN IP> \
--destination-port 53 \
--description "Allow Pi-hole DNS queries to Unbound" \
--enabled true
Replace IP addresses accordingly.
Rule 2: Block DNS Bypass from Other LAN Clients
Description:
Blocks all DNS queries (port 53) from LAN clients except those allowed by previous rules.
Prevents clients from bypassing Pi-hole for DNS resolution.
Settings:
Action: Block
Interface: LAN
Protocol: TCP/UDP
Source: LAN net (all clients)
Destination: Any
Destination Port: 53
Description: Block DNS bypassing Pi-hole
CLI Command:
opn-cli firewall rule create \
--interface lan \
--action block \
--protocol tcp/udp \
--source lan-net \
--destination any \
--destination-port 53 \
--description "Block DNS bypassing Pi-hole" \
--enabled true
Rule 3: Allow OPNsense Outbound DoT Queries on WAN Interface
Description:
Allows outbound TCP traffic on port 853 from OPNsense to upstream DoT servers to enable encrypted DNS queries.
Settings:
Action: Pass
Interface: WAN
Protocol: TCP
Source: This firewall (OPNsense itself)
Destination: Upstream DoT server IPs or Any
Destination Port: 853
Description: Allow OPNsense Unbound DNS over TLS outbound
CLI Command:
opn-cli firewall rule create \
--interface wan \
--action pass \
--protocol tcp \
--source 'this firewall' \
--destination any \
--destination-port 853 \
--description "Allow OPNsense Unbound DNS over TLS outbound" \
--enabled true
Part 4: Optional NAT Redirect Rule to Force DNS Requests to Pi-hole
Description:
Redirects all DNS (port 53) traffic from LAN clients to Pi-hole.
Enforces DNS queries use Pi-hole despite client DNS settings.
Settings:
Interface: LAN
Protocol: TCP/UDP
Source: LAN net
Destination: LAN net or Any
Destination Port: 53
Redirect Target IP: Pi-hole IP (e.g.,
192.168.1.10
)Redirect Target Port: 53
Description: Redirect DNS traffic to Pi-hole
CLI Command:
opn-cli nat rule add \
--interface lan \
--protocol tcp/udp \
--source lan-net \
--destination lan-net \
--destination-port 53 \
--redirect-address 192.168.1.10 \
--redirect-port 53 \
--description "Redirect DNS traffic to Pi-hole" \
--enabled true
Firewall Rule Order Summary After Parts 3 & 4
1
Allow Pi-hole DNS queries to OPNsense Unbound
LAN
Pass
TCP/UDP
Pi-hole IP
OPNsense LAN IP
53
Allow Pi-hole DNS queries
2
Block DNS bypass from other LAN clients
LAN
Block
TCP/UDP
LAN net
Any
53
Block DNS bypassing Pi-hole
3
(Optional) NAT redirect all DNS to Pi-hole
LAN
NAT
TCP/UDP
LAN net
LAN net
53
Redirect DNS traffic to Pi-hole
4
Allow OPNsense outbound DoT queries
WAN
Pass
TCP
This firewall
Upstream DoT IPs
853
Allow DNS over TLS outbound
Part 5: Prevent DNS Leaks from OPNsense Host Itself
Step 1: Clear External DNS Servers from System Settings
Navigate to System > Settings > General.
Remove any DNS servers listed.
Uncheck Allow DNS server list to be overridden by DHCP/PPP on WAN.
Save settings.
Step 2: Configure Unbound to Listen on Loopback and LAN
Go to Services > Unbound DNS > General.
Set Network Interfaces to include
127.0.0.1
and LAN IP.Save and apply.
Step 3: Block OPNsense Host Direct DNS Requests to External DNS
Description:
Block outbound DNS (port 53 TCP/UDP) from the OPNsense host to prevent DNS leaks outside Unbound.
CLI Command:
opn-cli firewall rule create \
--interface wan \
--action block \
--protocol tcp/udp \
--source 'this firewall' \
--destination any \
--destination-port 53 \
--description "Block OPNsense host direct DNS leaks" \
--enabled true
Step 4 (Optional): Allow DNS Queries to Localhost Only
Description:
Allow OPNsense to query only its local Unbound DNS resolver via loopback.
CLI Command:
opn-cli firewall rule create \
--interface wan \
--action pass \
--protocol tcp/udp \
--source 'this firewall' \
--destination 127.0.0.1 \
--destination-port 53 \
--description "Allow OPNsense host DNS to localhost" \
--enabled true
Step 5: Configure Services to Use Local DNS
This is a manual, configuration-specific step; OPNsense doesn't enforce this automatically, so regular review is recommended especially after adding new services or plugins.
Identify Services or Plugins that Use DNS:
Common services include VPN clients, proxy servers, monitoring tools, or packages installed on OPNsense.
Examples: OpenVPN client, Snort/Suricata, pfBlockerNG, or third-party plugins installed via the OPNsense interface.
Access Each Service’s Configuration:
In the OPNsense Web UI, navigate to the specific service/plugin configuration page.
Look for DNS-related settings or name server fields.
Set DNS Server to Local Unbound:
Change any DNS server IPs from external IPs (example: 9.9.9.9) to:
127.0.0.1
(localhost), orthe OPNsense LAN IP address on which Unbound DNS resolver is listening (e.g.,
192.168.1.1
).
Save and apply the changes.
Verify That Services Use Local DNS:
Use system logs or service-specific diagnostic pages to confirm DNS queries are resolved via the local Unbound.
This ensures DNS resolution remains encrypted and consistent with your DNS over TLS setup.
Check for Hardcoded External DNS in Config Files (Optional):
For deeper inspection, SSH into OPNsense and review service config files in
/usr/local/etc
or/usr/local/opnsense
.Replace any hardcoded external DNS IPs with
127.0.0.1
or LAN IP.
Rule Order Summary After Parts 3, 4 & 5
1
LAN
Pass
TCP/UDP
Pi-hole IP (e.g., 192.168.1.10)
This firewall (OPNsense LAN IP)
53
Allow Pi-hole DNS queries to Unbound
2
LAN
Block
TCP/UDP
LAN net (all clients)
Any
53
Block DNS bypass attempts to servers other than Pi-hole
3
LAN
NAT
TCP/UDP
LAN net
LAN net
53
(Optional) Redirect all DNS queries to Pi-hole
4
WAN
Pass
TCP
This firewall (OPNsense host)
Upstream DoT IPs or Any
853
Allow outbound DNS over TLS (TCP/853) queries from OPNsense
5
WAN
Block
TCP/UDP
This firewall (OPNsense host)
Any external addresses
53
Block direct DNS queries from OPNsense to external DNS servers (prevent leaks)
6
WAN
Pass
TCP/UDP
This firewall (OPNsense host)
127.0.0.1 (loopback)
53
(Optional) Allow DNS queries from OPNsense host to local Unbound
Rules by guide sections:
Part 3: Firewall Rules
Allow Pi-hole DNS / Block bypass DNS / DoT
1, 2, 4
Part 4: NAT Redirect Rule
Optional NAT redirect DNS to Pi-hole
3
Part 5: Host Leak Rules
Block host direct DNS leaks, allow localhost
5, 6
Summary
Rule #1: Allow Pi-hole DNS queries (LAN firewall rules, Part 3)
Rule #2: Block DNS bypass on LAN (Part 3)
Rule #3: NAT redirect all DNS traffic to Pi-hole (Part 4)
Rule #4: Allow outbound DNS over TLS from OPNsense (Part 3)
Rule #5: Block OPNsense host DNS leaks (Part 5)
Rule #6: Allow OPNsense host to query local DNS (Part 5) (optional)
Notes:
The allow rule (Order 1) must be at the top on the LAN interface to enable Pi-hole to forward queries to Unbound successfully.
The block rule (Order 2) prevents clients from circumventing Pi-hole by using external DNS servers directly.
The NAT redirect (Order 3) transparently forces all LAN DNS traffic through Pi-hole before firewall filtering; it applies at the NAT layer.
WAN interface rules (Orders 4-6) govern DNS requests originating from the firewall (OPNsense) itself, enforcing DoT usage and blocking DNS leaks by default.
The
(Optional)
tag indicates rules that can be omitted if not desired but are best practice for full DNS privacy.
How to verify and adjust order:
Go to Firewall > Rules > LAN (or WAN).
Use drag-and-drop handles or checkboxes with arrow buttons to reorder.
Click Apply Changes to save.
Testing & Validation
Renew DHCP leases on clients; check DNS server settings point to Pi-hole.
Verify Pi-hole receives DNS queries and blocks ads.
From OPNsense shell, run:
dig @127.0.0.1 example.com
to confirm Unbound resolution.
Use DNS leak test websites from clients and OPNsense host.
Review firewall logs for DNS traffic compliance.
How to reorder firewall rules in OPNsense Web UI:
Navigate to Firewall > Rules.
Select the interface tab, LAN or WAN, depending on where the rules are applied.
You'll see a list of the existing firewall rules in order from top to bottom.
To reorder:
Use the small drag handles (three horizontal lines) beside each rule to click and drag the rule up or down.
Alternatively, select one or more rules by checking the box(es) on the left, then use the up/down arrow buttons at the top of the rules list to move the selected rule(s).
After repositioning the rules in the desired order (such as allowing Pi-hole queries above block DNS bypass), click the Apply Changes button at the top to save and activate the new order.
When using CLI commands (opn-cli
):
opn-cli
):Rules created via CLI will appear at the top by default on the target interface.
If the order is not perfect after bulk CLI creation, simply use the above drag-and-drop UI technique to fine-tune rule positions.
This hybrid approach of CLI for creation + UI for ordering is common.
Why in this the order?:
OPNsense evaluates firewall rules top to bottom, stopping at the first match (first-match wins).
The allow rule for Pi-hole DNS queries must be above the block rule that blocks all other DNS port 53 traffic from LAN clients. This ensures legitimate DNS traffic to Pi-hole is allowed before general DNS blocking kicks in.
The block rule for other DNS traffic from clients is placed just below the Pi-hole allow rule, to catch all DNS attempts not directed to Pi-hole and block them.
The WAN rules allowing outbound DoT TCP/853 traffic from OPNsense itself are on the WAN interface and independent but must also be placed logically in a way that permits this encrypted DNS traffic.
The NAT redirect rule (optional) is processed before firewall rules and works at the NAT layer to transparently redirect DNS queries to Pi-hole.
Supporting Details:
According to OPNsense firewall best practices and documentation:
Put more specific rules first (allow Pi-hole IP on port 53).
Follow with broader block rules (block DNS port 53 from other clients).
Always confirm after rule creation in the UI under Firewall > Rules that rules appear in the expected order and adjust manually if needed.
Firewall logs and traffic monitoring help verify rules are applied correctly.
DNS Query Flow Overview
Clients → Pi-hole (ad blocking, caching) → OPNsense Unbound (resolves DNS queries via encrypted DoT) → Upstream DoT servers (Cloudflare, Quad9, etc.)
Additional Tips
Regularly update Pi-hole blocklists and OPNsense software for security enhancements.
Monitor Pi-hole and OPNsense logs for DNS query issues or anomalies.
Consider DNSSEC validation enabled on Unbound for protection against forgery.
Use test tools and packet capture to verify all DNS traffic is encrypted and forced through Pi-hole and Unbound.
Last updated