Every plaintext DNS query reveals which websites and services your users access — visible to the ISP, any man-in-the-middle, and potential attackers on the local network. DNS over TLS (DoT) encrypts DNS communication between your resolver and upstream DNS servers. In OPNsense, DoT can be configured directly in the built-in Unbound resolver — no additional software needed.
How DNS over TLS Works
Traditional DNS transmits queries and responses in plaintext over UDP port 53. DNS over TLS wraps DNS communication inside a TLS-encrypted connection over TCP port 853. The resolver (OPNsense/Unbound) establishes a TLS session with the upstream server and validates its certificate — exactly like a browser does with HTTPS.
| Feature | Standard DNS | DNS over TLS |
|---|---|---|
| Transport | UDP/TCP Port 53 | TCP Port 853 |
| Encryption | None | TLS 1.2/1.3 |
| Authentication | None | Certificate validation |
| ISP visibility | Full (domain visible) | Only DNS server IP |
| Manipulation possible | Yes (DNS spoofing) | No (TLS protected) |
Choosing Upstream Servers
For DNS over TLS, you need upstream servers that support DoT. The major providers:
Cloudflare (1.1.1.1)
- IP: 1.1.1.1 and 1.0.0.1
- IPv6: 2606:4700:4700::1111 and 2606:4700:4700::1001
- TLS hostname:
cloudflare-dns.com - Port: 853
- Advantages: Fastest response times, no-logging policy (audited by KPMG)
Quad9 (9.9.9.9)
- IP: 9.9.9.9 and 149.112.112.112
- IPv6: 2620:fe::fe and 2620:fe::9
- TLS hostname:
dns.quad9.net - Port: 853
- Advantages: Built-in malware domain filtering, Swiss data privacy law, non-profit
Mullvad DNS
- IP: 194.242.2.2
- TLS hostname:
dns.mullvad.net - Port: 853
- Advantages: No-logging policy, Swedish data privacy, optional ad/tracker filtering
Configuring OPNsense Unbound
Step 1: Enable DNS over TLS
Navigate to Services > Unbound DNS > General:
- Ensure Enable Unbound is checked
- Optionally disable DHCP Registration and DHCP Static Mappings temporarily (simplifies debugging)
Switch to Services > Unbound DNS > DNS over TLS:
- Click + to add a new upstream server
- Enter:
- Server IP:
1.1.1.1 - Server Port:
853 - Verify CN:
cloudflare-dns.com
- Server IP:
- Repeat for the second server (
1.0.0.1)
Add at least two servers from different providers to ensure redundancy:
| Server IP | Port | Verify CN |
|---|---|---|
| 1.1.1.1 | 853 | cloudflare-dns.com |
| 1.0.0.1 | 853 | cloudflare-dns.com |
| 9.9.9.9 | 853 | dns.quad9.net |
| 149.112.112.112 | 853 | dns.quad9.net |
Step 2: Enable Forwarding
Under Services > Unbound DNS > General, enable Enable Forwarding Mode. Without this setting, Unbound resolves queries recursively via root servers — DoT only applies in forwarding mode.
Step 3: Restrict Outgoing DNS Traffic
Create a firewall rule on the WAN interface that blocks outgoing DNS traffic (UDP/TCP 53) from the OPNsense IP. This ensures DNS queries exclusively use port 853 (TLS):
Firewall > Rules > Floating:
Action: Block
Interface: WAN
Direction: out
Protocol: TCP/UDP
Source: This Firewall
Destination: any
Destination Port: 53
Description: Block unencrypted DNS from firewall
Important: This rule must not block DNS traffic from internal clients to OPNsense — only traffic from the firewall itself to the internet.
Step 4: Custom Configuration (Optional)
For advanced settings, navigate to Services > Unbound DNS > Advanced and enter in the Custom Options field:
# Enforce TLS certificate validation
tls-cert-bundle: /etc/ssl/cert.pem
# Minimum TLS version
tls-ciphersuites: "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
# TCP keepalive for persistent connections
tcp-upstream: yes
Enabling DNSSEC
DNSSEC and DNS over TLS complement each other: DoT encrypts the transport, DNSSEC validates the integrity of DNS responses. Together, they provide maximum protection.
Enable DNSSEC under Services > Unbound DNS > General:
- Check Enable DNSSEC
- Click Apply
Test DNSSEC validation:
# From a client on the network
dig @<opnsense-ip> dnssec-failed.org +dnssec
# Expected: SERVFAIL (invalid DNSSEC signature correctly rejected)
dig @<opnsense-ip> cloudflare.com +dnssec
# Expected: NOERROR with RRSIG records
Performance Impact
DNS over TLS adds latency — the TLS handshake and TCP overhead noticeably slow down the first query. After the handshake, Unbound reuses the existing TLS connection for subsequent queries (connection reuse).
Benchmark Comparison
| Scenario | First Query | Subsequent Queries | Cache Hit |
|---|---|---|---|
| Standard DNS (UDP) | 15-30 ms | 15-30 ms | < 1 ms |
| DNS over TLS | 80-150 ms | 20-40 ms | < 1 ms |
The higher latency on the first query is barely noticeable in practice, since Unbound uses an aggressive cache and keeps connections open. For most business environments, the difference is negligible.
Optimizing the Cache
To maximize performance, increase the cache under Services > Unbound DNS > Advanced:
# Increase cache size (in MB)
msg-cache-size: 128m
rrset-cache-size: 256m
# Prefetch: renew entries before expiration
prefetch: yes
prefetch-key: yes
# Serve-stale: briefly serve expired entries
serve-expired: yes
serve-expired-ttl: 86400
Running a DNS Leak Test
After configuration, verify that DNS queries actually go through the encrypted upstream servers:
Method 1: Online Tools
Visit from a client on the network:
- dnsleaktest.com — runs standard and extended tests
- browserleaks.com/dns — shows the DNS server in use
- 1.1.1.1/help — checks Cloudflare-specific DoT/DoH status
Expected result: Only the configured upstream servers (Cloudflare, Quad9) appear — not the ISP DNS.
Method 2: Packet Capture on OPNsense
# SSH into OPNsense
tcpdump -i em0 -n port 53
# Expected: NO traffic on port 53
tcpdump -i em0 -n port 853
# Expected: TLS-encrypted traffic to 1.1.1.1, 9.9.9.9 etc.
Method 3: Unbound Statistics
Enable Unbound statistics under Services > Unbound DNS > Advanced:
statistics-interval: 300
extended-statistics: yes
Check statistics via CLI:
unbound-control stats_noreset | grep total.num
# total.num.queries=12345
# total.num.cachehits=9876
DNS over TLS vs. DNS over HTTPS
| Feature | DNS over TLS (DoT) | DNS over HTTPS (DoH) |
|---|---|---|
| Port | 853 (dedicated) | 443 (shared with HTTPS) |
| Blockability | Easy (block port 853) | Hard (port 443 is HTTPS) |
| Proxy compatibility | Low | High |
| Latency | Slightly lower | Slightly higher (HTTP overhead) |
| Enterprise control | Better (clearly separable) | Problematic (browser bypass) |
For enterprise environments, we recommend DoT: it is clearly identifiable, can be specifically allowed or blocked on the network, and browsers cannot use it independently (unlike DoH, which Chrome and Firefox implement directly).
Monitoring and Alerting
Monitor the DNS service with DATAZONE Control: DNS response times, cache hit rates, and TLS handshake errors feed into the central dashboard. Automatic alerts warn about DNS outages, unusually high latency, or certificate errors — before users notice problems.
Frequently Asked Questions
Does DoT work with split DNS?
Yes. Unbound in OPNsense supports domain overrides: internal domains are forwarded to the local DNS server, while all other queries go via DoT to external upstream servers.
Can I use DoT and DoH simultaneously?
OPNsense Unbound natively supports only DoT. For DoH, you need an additional proxy such as cloudflared or dnscrypt-proxy. Running both simultaneously is possible but rarely necessary.
What happens if all DoT servers fail?
Unbound does not automatically fall back to unencrypted DNS. Configure multiple upstream servers from different providers to handle outages.
Want to set up DNS over TLS on your OPNsense firewall? Contact us — we configure encrypted DNS and DNSSEC for your enterprise network.
More on these topics:
More articles
Backup Strategy for SMBs: Proxmox PBS + TrueNAS as a Reliable Backup Solution
Backup strategy for SMBs with Proxmox PBS and TrueNAS: implement the 3-2-1 rule, PBS as primary backup target, TrueNAS replication as offsite copy, retention policies, and automated restore tests.
OPNsense Suricata Custom Rules: Write and Optimize Your Own IDS/IPS Signatures
Suricata custom rules on OPNsense: rule syntax, custom signatures for internal services, performance tuning, suppress lists, and EVE JSON logging.
Systemd Security: Hardening and Securing Linux Services
Systemd security hardening: unit hardening with ProtectSystem, PrivateTmp, NoNewPrivileges, CapabilityBoundingSet, systemd-analyze security, sandboxing, resource limits, and creating custom timers.