OPNsenseLab
Flat isometric illustration of two dark teal cubes with notched tops joined by a curved teal cable on a white pad, against a pale pink background
Security

OPNsense DNS Blocklists: Unbound Setup and Tuning

OPNsense blocks ads and tracker domains natively through Unbound DNSBL. How to choose lists, scope them per VLAN, and fix the breakage they cause.

By OPNsenseLab Editorial · ·Updated August 22, 2026 · 9 min read

You do not need a separate Pi-hole to filter DNS on an OPNsense network. Unbound, the resolver that OPNsense enables by default, has integrated blocklisting built in — remote list sources, per-network policies, an allowlist, and a match tester, all in the GUI. For most homelabs it replaces a second box entirely, and it keeps DNS resolution and DNS filtering in one service instead of two.

The work is not in switching the feature on. It is in three things the feature does not do for you: making clients actually use the resolver, keeping the lists fresh, and unblocking what you break.

What Unbound’s blocklisting actually is

Unbound is a validating, recursive, caching resolver, and it has been the OPNsense default since 17.7. The blocklist function downloads domain lists from external sources, then answers matching queries with either 0.0.0.0 or NXDOMAIN instead of the real address. Nothing is proxied, nothing is inspected — the connection simply never gets an address to dial.

That boundary matters when you decide what to expect from it:

LayerBlocks byCatchesMisses
Unbound DNSBLDomain nameAd, tracker, telemetry, and known-malicious domainsHardcoded IPs, DoH inside apps, CNAME-cloaked trackers
ZenarmorApplication and web categoryIn-page content, app identificationEncrypted payloads
Suricata IDS/IPSPacket and flow signaturesExploit attempts, C2 patternsWhat the ruleset does not describe

DNS filtering is the cheapest of the three by a wide margin — near-zero CPU cost, no inline packet path — which is why it is worth enabling even if you also run the other two.

Prerequisite: clients have to use your resolver

An enabled blocklist filters nothing if the devices on your network resolve elsewhere. Before touching the blocklist tab, make sure of three things.

DHCP hands out the firewall as the DNS server. In Services → DHCPv4 → [interface], set the DNS server to the firewall’s address on that interface. Per-VLAN this matters more than it sounds, because it is what lets you apply different policies to different segments later.

Unbound has an access list covering the client subnet. The documentation is explicit that a client can only query Unbound if an ACL under Services → Unbound DNS → Access Lists permits it. Configured interfaces gain one automatically; a network the firewall does not directly own does not, and its queries are refused.

Devices that ignore DHCP get redirected. Smart TVs, streaming sticks, and a good share of IoT hardware hardcode 8.8.8.8 and ignore whatever DHCP told them. The fix is a destination NAT rule that redirects any port-53 traffic from that segment to the firewall itself, paired with a block rule for known DNS-over-HTTPS endpoints. The mechanics of writing that pair correctly are in OPNsense port forwarding and NAT rules, and the site’s rule and alias recipe generator has a “Force all DNS to Pi-hole / block DoH” recipe that emits the redirect, the DoH URL-table alias, and a DoT block on 853 in creation order. Enter the firewall’s own address on that segment where the recipe asks for the Pi-hole IP and the same plan points every query at Unbound instead.

Step 1: Enable the blocklist and pick sources

Services → Unbound DNS → Blocklist. Tick Enable, then choose one or more entries under Type of DNSBL. The predefined sources OPNsense ships, with the upstream maintainers named in the documentation, include:

Entry in the dropdownWhat it targetsNotes
OISD - Domain Blocklist AdsAds and trackersUpstream calls this the “small” list: wildcard, conservative, low breakage
OISD - Domain Blocklist BigAds, trackers, malware, phishingWildcard list, the usual “one list only” pick
OISD - Domain Blocklist NSFWAdult contentWildcard list, sits alongside one of the two above
AdAway ListMobile adsSmall, focused on mobile hosts
AdGuard ListAds and trackersBroad general-purpose list
EasyList / EasyprivacyAds / trackingDerived from the browser filter lists
Abuse.ch - ThreatFox IOC databaseMalware command-and-controlSecurity rather than ad blocking
Blocklist.site, YoYo ListMixed categoriesOlder community lists, largely superseded by OISD
hageziMultiple tiersRanges from light to very aggressive

Two practical points. First, the OISD lists are wildcard lists, so a single entry covers every subdomain of a listed domain — that is what keeps them small while staying more effective than a flat list of hostnames. Second, stacking six overlapping lists does not multiply the benefit; it multiplies the false positives and the memory footprint. Start with one general list, run it for a week, and add the security-focused feed separately if you want malware coverage.

You can also add your own sources under URLs of Blocklists. The format is a plain text file of fully qualified domain names, or wildcard entries such as *.example.com. Nothing else parses.

Step 2: Choose NXDOMAIN or 0.0.0.0

Destination Address controls what a blocked lookup returns, defaulting to 0.0.0.0. Return NXDOMAIN overrides it with the “no such domain” response code instead.

Pick NXDOMAIN. The documentation calls out the specific reason: some devices, Apple hardware in particular, cope badly with being handed 0.0.0.0 and stall waiting on a connection to an address that will never answer. NXDOMAIN tells the client the name does not exist and it moves on immediately. Keep 0.0.0.0 only if you are deliberately pointing blocked names at a local web server that explains the block.

Step 3: Scope policies per VLAN

This is the feature that makes the built-in blocklist genuinely better than a single upstream filter for a segmented network. Each blocklist policy takes a Source Net(s) value, and you can define several policies with different lists against different networks.

A workable arrangement on a three-segment network:

SegmentPolicyRationale
TRUSTED 192.168.10.0/24OISD AdsLight filtering, minimal breakage on work devices
IOT 192.168.20.0/24OISD Big plus ThreatFoxDevices that have no business phoning anywhere unexpected
GUEST 192.168.30.0/24OISD Big plus NSFWGuests get the strict profile

The matching algorithm selects the most specific subnet when domains overlap between policies, and the documentation advises keeping source nets separate rather than relying on that resolution. Networks in a single policy should also be the same address family and the same prefix size to avoid priority ambiguity. If your VLANs are not yet built, OPNsense VLAN configuration covers the interface, DHCP, and inter-VLAN rule work this depends on.

Step 4: Add the cron job, or the lists rot

This is the step most setups skip, and the symptom is a blocklist that quietly ages into irrelevance. Blocklists are downloaded and cached locally; they are not refreshed on a schedule unless you create one.

Go to System → Settings → Cron and add a task for the command Update Unbound DNSBLs. Daily is the right interval — the upstream lists do not rotate faster than that, and the cache TTL on the blocklist page is set to match. Without this task the lists are whatever they were on the day you enabled the feature.

One more piece of behaviour worth knowing: applying blocklist settings does not restart Unbound. It signals the running resolver to reprocess the lists once they are downloaded, which can take up to a minute. During that window resolution keeps working normally, so there is no outage from an edit.

Step 5: Handle the breakage

Something will break. It is usually a shortened link, a retail or airline site with a tracking-heavy checkout, or a smart-TV app whose telemetry domain also carries its content.

Three tools handle it:

  • Allowlist Domains takes patterns; any blocklist entry matching one is dropped from the compiled result. A pattern like .*\.example\.com exempts a whole domain.
  • Blocklist Domains and Wildcard Domains add your own entries. Wildcards cover every subdomain; blocking a first-level domain such as com is not supported.
  • Reporting → Unbound DNS shows what was actually blocked, and domains you pass or block from that page appear back in the allowlist and blocklist fields.

The blocklist tab also has a built-in tester that reports whether a given domain matches a defined policy. It has one documented limitation: it is entirely local, so it cannot follow a domain that resolves through a CNAME into a blocked name. For that case, the documentation points at Interfaces → Diagnostics → DNS lookup, or this from a shell on the firewall:

drill -b <source ip> <domain> <record type>

The source IP must be an address that exists on the firewall, and choosing the interface address of a specific VLAN is how you test that segment’s policy rather than the default one.

Diagnose in that order — reporting page, then tester, then drill — before touching the lists. A domain that fails all three checks is usually not a DNS problem at all, and the firewall rules walkthrough covers reading the live log to confirm.

Interaction with DNSSEC, DoT, and query forwarding

Blocklisting and DNSSEC validation coexist without conflict. The blocklist answer is synthesised by your own resolver for a name it has decided not to resolve; DNSSEC validates answers that were resolved. Leave DNSSEC enabled.

DNS over TLS upstream is a different decision. Forwarding queries encrypted to an upstream resolver hides them from your ISP, but it also gives up recursive resolution and hands your entire query stream to one provider. Blocklisting still works either way, because the block happens locally before anything is forwarded.

One documented multi-WAN trap is worth repeating: do not enable “Use System Nameservers” when you have several DNS servers configured with separate gateways. Unbound reaches system nameservers through locally created routes, and those do not follow a failover event — which turns a dead uplink into a DNS outage. If you run dual uplinks, read that alongside multi-WAN failover with gateway groups.

Local name resolution while you are in here

Two settings on the Unbound general page turn the resolver into a working internal DNS zone, which is worth enabling at the same time:

  • Register DHCP Leases registers machines that supply a hostname with their lease, so nas.lan resolves without you maintaining anything.
  • Register DHCP Static Mappings does the same for static reservations, and it covers IPv4 and IPv6.

Host overrides under Services → Unbound DNS → Overrides give you manual records, including wildcards, and they generate matching PTR records for reverse lookups. That is also the clean way to solve hairpin access to your own published services: point the internal name straight at the internal address instead of bouncing it off the WAN interface.

Unbound DNSBL, Pi-hole, or AdGuard Home

OptionRuns whereCase for itCase against
Unbound blocklistsOn the firewall, built inNo extra host, per-VLAN policies, one service to maintainReporting is basic next to a dedicated dashboard
Pi-holeSeparate host or VMRich per-client dashboard, long history, large communityAnother machine in the DNS path, another thing to patch and keep alive
AdGuard Home pluginOn the firewallPer-client rules, built-in DoH and DoT serverDuplicates a resolver you already run

For most homelabs the built-in path wins on the argument that carries the most weight over time: DNS is infrastructure, and every extra hop in the resolution path is another thing that can take the network down while you are not home. If you have not yet done the groundwork this all sits on, the OPNsense initial setup guide covers interfaces, DHCP, and management hardening first.

Sources

  1. Unbound DNS — OPNsense documentation
  2. OISD — Domain Blocklist
  3. hagezi/dns-blocklists — list definitions and tiers
  4. Settings menu (Cron) — OPNsense documentation
#opnsense #unbound#dns#blocklist#dns-filtering#security

Related