"view" Behavior Seems Inconsistent With Documentation

I’ve read through both the unbound.conf(5) man page and unbound.conf.sample for unbound Version 1.7.0 many times and am finding it hard to understand the logic behind how a specific query is resolved against a view and global data alone, not to mention my eventual desire to include stub/forwarded zones into the mix. Most of what an Internet search on views in unbound discusses Python-driven approaches, not the more recent, native implementation.

First, are there any other resources on how the logic among the various sources (view local data, view stub/forwarders, global stub/forwarders, global local data, external authoritative DNS) for getting an “answer” is intended to work?

Functional specs, design docs, or a pointer to the code would be generally helpful.

In the minimal test case that returns unexpected results, the goal is that there is “public” data that all subnets care resolve, a “private” name that all subnets should get the same value for (gld.example.com), and another name that a specific subnet should get a different answer that the other subnets, overriding the “public” value (maps.example.com).

(This can be tested by substituting example.com for an appropriate domain that supports the “maps” host name.)

As I understand the view-first directive it is “use the view’s local data first, if not present, then check as if the request was made at the global level”. I would expect this to check the global local data.

       **view-first:** *<yes* *or* *no>*
              If  enabled,  it  attempts  to  use  the  global  local-zone and
              local-data if there is no match in the  view  specific  options.
              The default is no.

Goals:

However, when I configure

local-zone: "example.com." typetransparent

local-data: "gld.example.com. A 10.0.0.1"
local-data: "maps.example.com. A 10.0.0.2"

access-control-view: 192.168.0.0/24 "classC"

view:
name: "classC"
view-first: yes
local-zone: "example.com." typetransparent
local-data: "maps.example.com. A 192.168.0.2"

If I query from an address not on the 192.168.0.0/24 subnet, the results are as expected:

[www.example.com](http://www.example.com) (resolved by example.com's DNS)
gld.example.com 10.0.0.1
maps.example.com 10.0.0.2

If I query from an address in the 198.168.0.0/24 subnet (“in” the view), it looks like the global data isn’t consulted for gld.example.com

[www.example.com](http://www.example.com) (resolved by example.com's DNS)
gld.example.com NXDOMAIN from example.com's DNS (expected 10.0.0.1 from "global" data)
maps.example.com 192.168.0.2 (as expected from the view)

Changing to view-first: no (or omitting it completely) does not change the behavior.

Changing the view’s local-zone to static (thinking that the view might have tried external resolution before deferring to the global zone definition) ends up with an NXDOMAIN result for all but maps.example.com from the unbound instance (no authority section)..

view:
name: "classC"
view-first: yes
local-zone: "example.com." static
local-data: "maps.example.com. A 192.168.0.2"

[www.example.com](http://www.example.com) NXDOMAIN (expected to be resolved by example.com's DNS)
gld.example.com NXDOMAIN (expected 10.0.0.1 from "global" data)
maps.example.com 192.168.0.2 (as expected from the view)

(Yes, this simple, two-name configuration could be replicated in the view, but the target operational configuration involves many more zones, names and views.)

What am I missing in my thinking, in my configuration?

TIA,

Jeff

FreeBSD 11.1-RELEASE-p13 #9

Version 1.7.0
linked libs: libevent 2.1.8-stable (it uses kqueue), OpenSSL 1.0.2k-freebsd 26 Jan 2017
linked modules: dns64 respip validator iterator

Hi Jeff,

I've read through both the unbound.conf(5) man page and
unbound.conf.sample for unbound Version 1.7.0 many times and am finding
it hard to understand the logic behind how a specific query is resolved
against a view and global data alone, not to mention my eventual desire
to include stub/forwarded zones into the mix. Most of what an Internet
search on views in unbound discusses Python-driven approaches, not the
more recent, native implementation.

It seems what you found it a problem in the code, where this feature
check is simply missing. I added such a check, so that zones that are
transparent have their queries check for content defined outside of
views with view-first is enabled. This makes your test cases work.
Thanks for the report. It should work with zones that are transparent,
typetransparent, always-transparent and type inform.

Best regards, Wouter

TL;DR - Appears resolved in 1.8.0rc1

Hi Jeff,

I've read through both the unbound.conf(5) man page and
unbound.conf.sample for unbound Version 1.7.0 many times and am finding
it hard to understand the logic behind how a specific query is resolved
against a view and global data alone, not to mention my eventual desire
to include stub/forwarded zones into the mix. Most of what an Internet
search on views in unbound discusses Python-driven approaches, not the
more recent, native implementation.

It seems what you found it a problem in the code, where this feature
check is simply missing. I added such a check, so that zones that are
transparent have their queries check for content defined outside of
views with view-first is enabled. This makes your test cases work.
Thanks for the report. It should work with zones that are transparent,
typetransparent, always-transparent and type inform.

Best regards, Wouter

[...]

Goals:

* most-anything.example.com resolved by public example.com DNS
* gld.example.com resolved by "global, local" data in unbound (local
host names with no public DNS)
* maps.example.com resolved by
* global, local data for many subnets
* view-specific data for some other subnets

However, when I configure

local-zone: "example.com." typetransparent

local-data: "gld.example.com. A 10.0.0.1"
local-data: "maps.example.com. A 10.0.0.2"

access-control-view: 192.168.0.0/24 "classC"

view:
name: "classC"
view-first: yes
local-zone: "example.com." typetransparent
local-data: "maps.example.com. A 192.168.0.2"

If I query from an address *not* on the 192.168.0.0/24 subnet, the
results are as expected:

www.example.com (resolved by example.com's DNS)
gld.example.com 10.0.0.1
maps.example.com 10.0.0.2

If I query from an address in the 198.168.0.0/24 subnet ("in" the view),
it looks like the global data isn't consulted for gld.example.com

www.example.com (resolved by example.com's DNS)
gld.example.com NXDOMAIN from example.com's DNS (expected 10.0.0.1
from "global" data)
maps.example.com 192.168.0.2 (as expected from the view)

[...]

FreeBSD 11.1-RELEASE-p13 #9

Version 1.7.0
linked libs: libevent 2.1.8-stable (it uses kqueue), OpenSSL
1.0.2k-freebsd 26 Jan 2017
linked modules: dns64 respip validator iterator

Thanks!

I've just tweaked the FreeBSD port to use the 1.8.0rc1 source and new library versions and it appears to work as expected.

Version 1.8.0rc1
linked libs: libevent 2.1.8-stable (it uses kqueue), OpenSSL 1.0.2k-freebsd 26 Jan 2017
linked modules: dns64 respip validator iterator

Jeff