Unbound DNS Server
My local DNS resolver of choice was dnsmasq for a long time. It’s not the best, it’s not “enterprise-y”, but it’s easy to set up, and most importantly, it works. As part of my last network overhaul, I decided to give unbound a try.
This is a short article about my experience and configuration.
All you really need to know is in this excellent tutorial over at calomel.org. You should take a moment to read it.
A few months later, I am still happy with unbound. DNSSEC works, and it has some security benefits such as thwarting cache poisoning attempts. The caveat is that it does not have DHCP integration. That’s fine, OpenBSD has dhcpd. However, if you want DNS lookups to work with DHCP assignments, you have to look elsewhere.
My current solution is a hybrid. Unbound for DNS, dnsmasq for DHCP. Unbound forwards lookups for the local network to dnsmasq. There’s probably a better way to do this, but again, it works.
My abbreviated configuration looks like this. See the calomel.org article for more detail. Paths shown are for OpenBSD, your installation may vary.
/var/unbound/etc/unbound.conf:
:::Text only
remote-control:
control-enable: yes
server:
verbosity: 1
interface: 0.0.0.0
port: 53
do-ip4: yes
do-ip6: no
do-udp: yes
do-tcp: yes
access-control: 127.0.0.0/8 allow
access-control: 192.168.0.0/16 allow
root-hints: "/var/unbound/etc/root.hints"
hide-identity: yes
hide-version: yes
harden-glue: yes
harden-dnssec-stripped: yes
use-caps-for-id: yes
cache-min-ttl: 3600
cache-max-ttl: 86400
prefetch: yes
num-threads: 2
msg-cache-slabs: 8
rrset-cache-slabs: 8
infra-cache-slabs: 8
key-cache-slabs: 8
rrset-cache-size: 256m
msg-cache-size: 128m
private-address: 192.168.0.0/16
private-address: 172.16.0.0/12
private-address: 10.0.0.0/8
unwanted-reply-threshold: 10000
auto-trust-anchor-file: "/var/unbound/etc/root.key"
val-clean-additional: yes
include: "/var/unbound/etc/local_blocks"
do-not-query-localhost: no
# Your internal network name and addresses go here
private-domain: "my.internal.domain.name"
domain-insecure: "my.internal.domain.name"
private-domain: "1.168.192.in-addr.arpa."
domain-insecure: "1.168.192.in-addr.arpa."
local-zone: "1.168.192.in-addr.arpa." transparent
# Forward lookups for your internal domain name to dnsmasq
forward-zone:
name: "my.internal.domain.name."
forward-addr: 127.0.0.1@5353
# Reverse lookups for your internal domain name to dnsmasq
forward-zone:
name: "1.168.192.in-addr.arpa."
forward-addr: 127.0.0.1@5353
forward-zone:
name: "."
forward-addr: 8.8.4.4 # Google
forward-addr: 8.8.8.8 # Google
# forward-addr: 37.235.1.174 # FreeDNS
# forward-addr: 37.235.1.177 # FreeDNS
# forward-addr: 50.116.23.211 # OpenNIC
# forward-addr: 64.6.64.6 # Verisign
# forward-addr: 64.6.65.6 # Verisign
# forward-addr: 74.82.42.42 # Hurricane Electric
# forward-addr: 84.200.69.80 # DNS Watch
# forward-addr: 84.200.70.40 # DNS Watch
# forward-addr: 91.239.100.100 # censurfridns.dk
# forward-addr: 109.69.8.51 # puntCAT
# forward-addr: 208.67.222.220 # OpenDNS
# forward-addr: 208.67.222.222 # OpenDNS
# forward-addr: 216.146.35.35 # Dyn Public
# forward-addr: 216.146.36.36 # Dyn Public
You can block or override specific domains with this:
/var/unbound/etc/local_blocks: (from calomel.org)
:::Text only
# Blocking Ad Server domains. Google's AdSense, DoubleClick and Yahoo
# account for a 70 percent share of all advertising traffic. Block them.
local-zone: "doubleclick.net" redirect
local-data: "doubleclick.net A 127.0.0.1"
local-zone: "googlesyndication.com" redirect
local-data: "googlesyndication.com A 127.0.0.1"
local-zone: "googleadservices.com" redirect
local-data: "googleadservices.com A 127.0.0.1"
local-zone: "google-analytics.com" redirect
local-data: "google-analytics.com A 127.0.0.1"
local-zone: "ads.youtube.com" redirect
local-data: "ads.youtube.com A 127.0.0.1"
local-zone: "adserver.yahoo.com" redirect
local-data: "adserver.yahoo.com A 127.0.0.1"
local-zone: "ask.com" redirect
local-data: "ask.com A 127.0.0.1"
local-zone: "amazon-adsystem.com" redirect
local-data: "amazon-adsystem.com A 127.0.0.1"
local-zone: "scorecardresearch.com" redirect
local-data: "scorecardresearch.com A 127.0.0.1"
local-zone: "doubleclick.com" redirect
local-data: "doubleclick.com A 127.0.0.1"
local-zone: "quantserve.com" redirect
local-data: "quantserve.com A 127.0.0.1"
You can find dnsmasq configuration examples online, and the defaults are reasonable, so I won’t go into them here. You do need to make the following changes to dnsmasq.conf:
port=5353
Make sure dnsmasq’s DNS server is listening on an alternate port. This should match theforward-addr: 127.0.0.1@5353
lines in unbound.conf.domain=my.internal.domain.name
Again, make sure this matches up with unbound.conf.resolv-file=/etc/somefile
. Make sure dnsmasq uses specific resolvers (such as 8.8.8.8 and 8.8.4.4). This helps avoid a loop back issue when resolving hosts on the local network.
On OpenBSD, you may need to change the permissions on /var/unbound/etc
so that it can update the root key files. chown _unbound:wheel /var/unbound/etc && chmod 755 /var/unbound/etc
.
You can test DNSSEC with DNSSEC-Check.
Another quick test is to see if www.dnssec-failed.org
resolves:
:::Text only
# Example of working DNSSEC:
$ dig +short www.dnssec-failed.org
$
# Example of failed DNSSEC:
$ dig +short www.dnssec-failed.org @216.146.35.35
68.87.109.242
69.252.193.191
$