How I use Unbound on Fedora 20 to deal with the VPN DNS issue
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.
conf.d file has things like:
forward-zone: name: "sandbox" forward-addr: 188.8.131.52 forward-zone: name: "10.in-addr.arpa" forward-addr: 184.108.40.206
(.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.)
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 private-address: 10.0.0.0/8 # Allow these domains to use private IPs private-domain: sandbox # Don't try to do DNSSEC for these domain-insecure: sandbox # MUST INCLUDE THIS local-zone: "10.in-addr.arpa" nodefault
(On a non Fedora 20 machine, the
local.d bits go in the
conf.d bits go at the top level.)
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.)