OPNsense plugin · os-unbound-upstream 1.5

Unbound Upstream via Gateway

Sends Unbound's internet lookups to a resolver inside your VPN tunnels, through the best member of a gateway group, and switches with the group. When no tunnel is up, Unbound falls back to its own forwarders, or chosen clients fail closed.

Why this plugin

A VPN provider usually runs a resolver inside its tunnels, and policy routing sends your clients' traffic through them. Unbound's own queries do not follow: it forwards to one fixed list of servers, which leaves by the firewall's default route, the WAN. Pointing Unbound's forwarders at the provider's resolver by hand breaks whenever the tunnel it is reached through goes down, and nothing switches it to another tunnel or back.

The plugin makes the tunnels' gateway group decide. While the group has a usable member, Unbound's root zone forwards to that member's resolver, reached by a host route through that member's tunnel and kept off the WANs by a firewall rule. When the best member changes, so does the route. When none is usable, the root zone returns to Unbound's own forwarders (Query Forwarding or DNS over TLS), or to recursion, without flushing the cache.

How it works

Failing closed

By default the fallback keeps everyone resolving. Since 1.5 you can choose, instead, that some clients get REFUSED for internet names while no tunnel is up, so their lookups never leave by the WAN:

The firewall's own lookups from 127.0.0.1 are never refused. Local names keep resolving for a fail-closed client: host overrides and their reverse records, the system domain, DHCP lease names, domain overrides and the private reverse zones.

The set lives in an Unbound view, in the plugin's own file in core's unbound.opnsense.d include directory. Unbound loads it at every start already refused, so the set is refused from the first query after a boot, a restart or an upgrade, and lifted once a member is in use. Falling back arms the refuse again before the root returns to the forwarders. Apply restarts Unbound once when the set's networks change.

The page's Fail closed row shows the set and its state: lifted, armed, not armed (with the reason and the remedy), or stuck.

Settings

On Services > Unbound DNS > Upstream via Gateway, with its log under Upstream via Gateway Log.

SettingWhat it doesDefault
EnableForward the root zone through the group's best member, and fall back when none is usable. Off returns Unbound to its own forwarders.Off
Dry runDecide and log only: Unbound's forwarders and the routes are left alone; the block and pass rules are still loaded.On
Gateway groupThe saved group, all of one family, whose members are the tunnels to the resolver. Every member must be monitored.
Default resolverThe resolver's address inside the tunnels, for every member without its own row, for example 198.51.100.53.
Failback delay (seconds)How long a better member must stay usable before Unbound returns to it, 60 to 3600; at least the longest monitor period of the members.120
Probe nameThe name used to check that the resolver answers; . asks for the root..
Fall back to Unbound's own forwardersOff: every client gets REFUSED while no member is usable. The firewall's own lookups always fall back.On
Fail closed onInterfaces whose clients get REFUSED for internet names while no member is usable.none
Fail closed for networksSource networks routed to the firewall that fail closed the same way.none
Notify on switch, Notify URLPOST each switch as JSON, for example to a Home Assistant webhook.Off
Per-member resolversRows below the settings: a member and its own resolver.none

Save refuses for the fail-closed fields: a gateway-group member's interface, the loopback interface, an interface with no address, a network with host bits, 0.0.0.0/0 and ::/0, and a network that overlaps loopback or a member's network.

Status, notifications, Home Assistant

The page shows the mode (a member, or the fallback), the resolver, how long the member has been healthy, the last outage, the resolver's routes, the blocked-packet count and the Fail closed row. The privilege Status: Unbound DNS: Upstream via Gateway (API) reads the status and nothing else, for a poller's API key. Notify on switch POSTs each switch, and each change of a fail-closed problem, as JSON.

configctl unboundupstream state      # the status as JSON
configctl unboundupstream stop       # undo tunnel mode now (the minute job re-enters it while enabled)

Limits

Recovery

After a failed upgrade, a downgrade to 1.4, or a removal that could not finish, remove the view file and restart Unbound:

rm /usr/local/etc/unbound.opnsense.d/unboundupstream.conf
configctl unbound restart

Source and install

Install it from the LegoTypes repository: see Install. Source: LegoTypes/plugins, dns/unbound-upstream.