A caching and zone refresh problem with Unbound

July 16, 2016

Like many people, we have internal resolving DNS servers that everyone's laptops and so on are supposed to use for their DNS. These used to run Bind and now run Unbound, mostly because OpenBSD switched which nameservers they like. Also like many people, we have a collection of internal zones and internal zone views, which are managed from a private internal master DNS server. This has led to a problem with our Unbound setup that we actually don't know how to solve.

When we make an update to internal DNS and reload the private master with it, we want this to be reflected on the resolving DNS servers essentially immediately so that people see the DNS change right away. In the days when we ran Bind on the resolving servers, this was easy; we configured the resolving Bind to be a secondary for our internal zones and set the master up with also-notify entries for it. When the master detected a zone change, it sent notifications out and the resolving Bind immediately loaded the new data. Done.

It's not clear how to achieve something like this with Unbound. Unbound doesn't listen to NOTIFY messages and do anything with them (although it's listed as a TODO item in the source code). While you can force an incredibly low TTL on DNS records so that the new DNS information will be seen within a minute or two, this setting is global; you can't apply it to just some zones, like say your own, and leave everything else cached as normal. In theory we could set absurdly low TTLs on everything in the internal views on the private master, which would propagate through to Unbound. In practice, how the internal views are build makes this infeasible; it would be a major change in what is a delicate tangle of a complex system.

(With low TTLs there's also the issue of cached negative entries, since we're often adding names that didn't exist before but may have been looked up to see that nope, there is no such hostname.)

Unbound can be told to flush specific zones via unbound-control and in theory this works remotely (if you configure it explicitly, among other things). In practice I have a number of qualms about this approach, even if it's scripted, and Unbound's documentation explicitly says that flushing zones is a slow operation.

Given that Unbound explicitly doesn't support NOTIFY yet, there's probably no real good solution to this. That's sometimes how it goes.

(We have what I'm going to call a workaround that we currently feel we can live with, but I'm not going to tell you what it is because it's not really an appealing one.)


Comments on this page:

By Jean Paul Galea at 2016-07-16 06:02:29:
I typically use the local-zone directive to solve your problem, although my networks are nowhere near as large as a university and you probably have lots of zones to migrate.

What if you try something like this? It's not very clean and not sure if it would work;

1. Run an Unbound instance to resolve/cache from root servers with bind address 127.0.1.1@53.

2. Run NSD/BIND to be authoritative for your internal zones with bind address 127.0.2.1@53.

3. Then, run another Unbound instance to accept queries from your network with:

# never cache on this instance
cache-max-ttl: 0

# always query your internal authoritative server for such zones
name: "internal.zone."
forward-addr: 127.0.2.1

# everything else gets forwarded to the resolving/caching unbound instance.
name: "."
forward-addr: 127.0.1.1

Similar situation here as well, we used to have slave zones on bind but now use unbound. So now we use unbound-control flush_zone to flush our internal zone on two fairly busy unbound resolvers and it takes 6-7 seconds, which is acceptable for us.

But please share your current workaround, even if it's not very appealing..

Written on 16 July 2016.
« Sudo and changes in security expectations (and user behaviors)
DNS resolution cannot be segmented (and what I mean by that) »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sat Jul 16 00:30:58 2016
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.