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

  1. Enable Unbound DNS Resolver:

    • Log into OPNsense Web UI.

    • Navigate to Services > Unbound DNS > General.

    • Check Enable Unbound and save.

  2. 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.

  3. 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.

  4. Restart Unbound:

    • Restart Unbound under Services > Unbound DNS.


Part 2: Install and Integrate Pi-hole with OPNsense Unbound DNS

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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

Order
Rule Purpose
Interface
Action
Protocol
Source
Destination
Port(s)
Description

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.

  1. 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.

  2. 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.

  3. 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), or

      • the OPNsense LAN IP address on which Unbound DNS resolver is listening (e.g., 192.168.1.1).

    • Save and apply the changes.

  4. 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.

  5. 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

Order
Interface
Action
Protocol
Source
Destination
Port(s)
Description

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:

Step # in Guide
Description
Table Rule #s

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:

  1. Navigate to Firewall > Rules.

  2. Select the interface tab, LAN or WAN, depending on where the rules are applied.

  3. You'll see a list of the existing firewall rules in order from top to bottom.

  4. 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).

  5. 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):

  • 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