How I use Unbound on Fedora 20 to deal with the VPN DNS issue

May 7, 2014

A while back Pete Zaitcev asked about the issue of VPNs versus DNS (and wound up with a good answer). This is the problem where you have a VPN connection off to some internal networks somewhere and you want to look up VPN hosts using one DNS server (the VPN's DNS server) but look up everything else with another DNS server.

I have a similar situation with my home machine, as I have an IPSec tunnel to work that basically puts one side of my machine on the work network, complete with a bunch of internal DNS and internal networks. Since I leave the IPSec tunnel up all the time, in theory I could rely on work's internal DNS server for everything. In practice the tunnel can get interrupted and anyways I wanted to avoid the latency hit for sending DNS over it when possible. My solution is to run Unbound as a local caching DNS server, configured to mostly go to the Internet but to divert lookups for some zones off to our internal DNS servers.

(Well, I do tricks with some other lookups but they're not as interesting.)

Fedora 20 has split the Unbound configuration up into multiple files so you don't need to modify the package-supplied files very much (or at all), although where to put things is a bit arcane. To simplify, configuring what DNS lookups for what zones should go where goes in /etc/unbound/conf.d while access control and result filtering goes in /etc/unbound/local.d. You're going to need both.

My conf.d file has things like:

     name: "sandbox"
     name: ""

(.sandbox is our internal top-level domain for purely internal hosts.)

Here the IP address I'm pointing the forward-zone stanzas at is the internal caching DNS server that ordinary client machines use. Unbound will make normal recursive DNS queries to it just as if it was a regular client instead of a real DNS server.

(If you're pointing at authoritative, non-recursive DNS servers you want to use stub-zone, but this is usually going to be rare.)

My local.d file has a bunch of stuff about listening interfaces and access control, but the important bit is a collection of statements about result filtering. These cover things like:

# Remove these IPs from public DNS results
# Allow these domains to use private IPs
private-domain: sandbox
# Don't try to do DNSSEC for these
domain-insecure: sandbox

local-zone: "" nodefault

(On a non Fedora 20 machine, the local.d bits go in the server: section of unbound.conf while conf.d bits go at the top level.)

The local-zone statement here is really important. If you leave it out, Unbound defaults to returning NXDOMAIN for PTR queries in 10/8 (along with all the other RFC1918 private IP ranges) despite the fact that I configured forwarding for these DNS queries.

(Yes, this caused a certain amount of heartburn when I set Unbound up for the first time on my work machine. It's documented in the unbound.conf manpage if you read the whole thing carefully.)

My setup implicitly assumes that the IPSec tunnel is up and the work internal DNS server listed in eg the forward-zone declarations is reachable. If I brought the tunnel down regularly I'd need to do something more clever (or more brute force, eg restarting Unbound with a 'no tunnel' configuration that didn't have all the forwarding and so on). It also doesn't have any interaction with NetworkManager because I don't use NetworkManager on this machine (it's a bad fit for NM).

(I understand that NetworkManager either has or is in the process of gaining its own mechanisms to handle this problem, assuming that you manage all your networking and VPNs and so on through NetworkManager. See Pete Zaitcev's entry.)

Written on 07 May 2014.
« Another problem with building your own packages: dependency issues
The modern world of spliced together multi-layer DNS resolution »

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

Last modified: Wed May 7 02:15:18 2014
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.