Unbound is a caching DNS resolver that comes as a part of OpenBSD base. You can use this to provide faster as well as more secure DNS lookup for the users on your network.
Please read through the unbound(8), unbound.conf(5), unbound-checkconf(8) and nsd(8) man pages.
Here's a sample /var/unbound/etc/unbound.conf:
server:
interface: 127.0.0.1 # listen on localhost
interface: ::1
#interface: 10.0.0.1 # provide DNS for users on the IPSec internal network
#do-ip6: no
access-control: 0.0.0.0/0 refuse # block all users by default
access-control: 10.0.0.0/8 allow # allow users on the internal network to use unbound
access-control: 127.0.0.0/8 allow # allow localhost to use unbound
access-control: ::0/0 refuse # block all IPv6 users by default
access-control: ::1 allow # allow IPv6 localhost to use unbound
hide-identity: yes
hide-version: yes
remote-control:
control-enable: yes
control-interface: /var/run/unbound.sock
forward-zone:
name: "."
forward-addr: 185.117.154.144
forward-addr: 165.227.40.43
forward-addr: 217.144.132.169
forward-addr: 212.237.22.141
forward-addr: 165.227.108.86
The forward-addr lines indicate which nameserver unbound will query. You can find a list of public servers on OpenNIC.
Tip: To quickly get the IPs from OpenNIC, click on the OK button at the top, then open up your web browser's javascript console window and run this command:
document.clear();data=document.querySelectorAll("html body div#frame div#view div#srvlist div p");document.body.innerText="forward-addr: 9.9.9.9";data.forEach(line=>{
if (line.childNodes[0].childNodes[1].title == "No logs kept"){
document.body.innerHTML+=`<br>forward-addr: ${line.childNodes[2].childNodes[0].data}`;
}
});
You can also run these command:
Attach:unbound.txt
(:if false:)
if you are using another server as a master, set forwarding from this server as a priority:
forward-zone:
name: "example.com."
forward-addr: 10.10.10.10@53
forward-first: no
forward-no-cache: no
(:ifend:)
If you need to store local zones, add a block to the "server" section about it:
local-zone: "localhost." static
local-data: "localhost. 10800 IN NS localhost."
local-data: "localhost. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
local-data: "localhost. 10800 IN A 127.0.0.1"
local-data: "localhost. 10800 IN AAAA ::1"
To start unbound:
$ doas rcctl enable unbound
$ doas rcctl start unbound
For the computer that runs unbound, you'll want to make sure /etc/resolv.conf uses 127.0.0.1 as the nameserver (that is, you query unbound running on port 53). In /etc/resolv.conf:
nameserver 127.0.0.1
lookup file bind
Check to make sure /etc/resolv.conf.tail does not contain any other name servers except 127.0.0.1. All your nameservers should instead be specified in /var/unbound/etc/unbound.conf.
If the computer running unbound uses DHCP for network configuration, you will want to include this line in /etc/dhclient.conf:
ignore domain-name-servers;
This tells OpenBSD's dhclient to ignore the name server provided by the dhcp server.
If the computer running unbound is also providing a dhcp server for your local network, you will want to add this line inside your /etc/dhcpd.conf blocks:
option domain-name-servers 192.168.1.1;
Here's how to use unbound as a local caching resolver:
Edit /etc/resolv.conf so it queries localhost on port 53:
# Generated by age0 dhclient
nameserver 127.0.0.1
lookup file bind
Inside /var/unbound/etc/unbound.conf, you will see this at the top:
server:
interface: 127.0.0.1
interface: ::1
# override the default "any" address to send queries; if multiple
# addresses are available, they are used randomly to counter spoofing
#outgoing-interface: 192.0.2.1
#outgoing-interface: 2001:db8::53
access-control: 0.0.0.0/0 refuse
access-control: 127.0.0.0/8 allow
access-control: ::0/0 refuse
access-control: ::1 allow
Make sure you are listening on 127.0.0.1 (for localhost) so that your VPS can query localhost on port 53, and also ::1 on port 53 (for IPv6).
For access control, you want to refuse 0.0.0.0/0 (all IPv4s) but allow 127.0.0.0/8 (everything that originates locally). Again, refuse ::0/0 (all IPv6s) but allow ::1 (localhost).
Put this at the bottom of the file:
forward-zone:
name: "." # use for ALL queries
forward-addr: 163.53.248.170
forward-addr: 103.236.162.119
forward-addr: 192.99.85.244
forward-addr: 31.171.251.118
forward-addr: 51.254.25.115
forward-addr: 46.101.70.183
forward-addr: 45.71.112.70
forward-addr: 87.98.175.85
forward-addr: 185.208.208.141
forward-addr: 89.35.39.64
forward-addr: 87.98.175.85
forward-addr: 172.98.193.42
forward-addr: 111.67.20.8
These are IP addresses for DNS servers which I got from https://servers.opennic.org/. However, the servers change regularly so make sure you update the list.
To start unbound:
$ doas rcctl enable unbound
$ doas rcctl start unbound
To test if unbound is working:
$ dig @127.0.0.1 google.com
You should see something like this:
;; ANSWER SECTION:
google.com. 29 IN A 172.217.27.142
DNSSec
In /var/unbound/etc/unbound.conf, there are these two lines:
auto-trust-anchor-file: "/var/unbound/db/root.key"
aggressive-nsec: no
Both should be commented to turn off DNSSEC.
I have not yet found out how to turn on DNSSEC safely. The problem is that if you turn on DNSSEC it will refuse to serve DNS records that don't have DNSSEC enabled.
Stale hostname
If you ever change your host's IP address, /etc/hosts may be intercepting the name lookup and giving you the old IP address.
Make sure there is no entry in the /etc/hosts files that is causing your machine to use the old IP.
Troubleshooting
Mar 8 01:34:41 hostname unbound: [45846:0] info: validation failure <hostname.com. A IN>: key for validation . is marked as invalid because of a previous validation failure <previoushostname.com. A IN>: no DNSKEY rrset for trust anchor . while building chain of trust
Flush all negative cache.
# unbound-control flush_negative