Unbound DNS Server Configuration & Static IPv6 Address on Proxmox
This article explains how to set up the Unbound DNS server as the resolver for your home network. It also shows how to generate and assign a static IPv6 address to your Proxmox server. This post is part of my series on home automation, networking & self-hosting that shows how to install, configure, and run a home server with (dockerized or virtualized) services such as Home Assistant and ownCloud.
What is Unbound?
Unbound is a fast, lean, and secure DNS server that has supplanted BIND as the default name server in FreeBSD and OpenBSD. Unbound supports DNSSEC and can use DNS over TLS (DoT) when forwarding queries to upstream DNS servers.
Unbound Installation & Configuration on Proxmox
Dockerized or Natively Installed?
DNS is an essential service that needs to be available even when Docker is not running (e.g., during backups). For that reason, I installed Unbound natively on my Proxmox home server.
Unbound Installation
The following commands install Unbound:
$ apt update
$ apt install unbound
Verify that the status of the Unbound service is active (running)
:
$ systemctl status unbound
● unbound.service - Unbound DNS server
Loaded: loaded (/lib/systemd/system/unbound.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2023-06-03 01:18:09 CEST; 1min 42s ago
Unbound Configuration
After the installation, Unbound uses its sensible built-in default configuration (see the config docs). We only need to change a subset of settings by replacing the contents of nano /etc/unbound/unbound.conf
with the following.
Note: please see this article if you want to bind Unbound to (Docker) interfaces that may not yet exist when Unbound starts.
server:
# Specify the IP addresses to listen on
# IMPORTANT:
# - Unbound won't start if these interfaces don't exist.
interface: 192.168.0.4
interface: lo
interface: ::0
# Root hints file
root-hints: "/usr/share/dns/root.hints"
# Location of the trust anchor file that enables DNSSEC
auto-trust-anchor-file: "/var/lib/unbound/root.key"
# Certificates used to authenticate connections made upstream
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
# Enable prefetching of almost expired message cache entries
prefetch: yes
# Refuse id.server and hostname.bind queries
hide-identity: yes
# Refuse version.server and version.bind queries
hide-version: yes
# Performance optimization
num-threads: 4
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 addresses are not allowed to be returned for public internet names.
# Any occurrence of such addresses is removed from DNS answers. This protects against DNS rebinding.
private-address: 192.168.0.0/16
private-address: 172.16.0.0/12
private-address: 10.0.0.0/8
private-address: 169.254.0.0/16
private-address: fd00::/8
private-address: fe80::/10
# Which clients may make queries to this server: everybody
access-control: 0.0.0.0/0 allow
access-control: ::/0 allow
# Local DNS domain
# REPLACE with your actual domain
local-zone: "home.yourdomain.com." transparent
# A records in the local DNS domain
# REPLACE with your actual domain and IP address
local-data: "auth.home.yourdomain.com. IN A 192.168.0.4"
local-data: "lldap.home.yourdomain.com. IN A 192.168.0.4"
local-data: "owncloud.home.yourdomain.com. IN A 192.168.0.4"
local-data: "portainer.home.yourdomain.com. IN A 192.168.0.4"
local-data: "px1.home.yourdomain.com. IN A 192.168.0.4"
local-data: "whoami.home.yourdomain.com. IN A 192.168.0.4"
# PTR records in the local DNS domain
# REPLACE with your actual domain and IP address
local-data-ptr: "192.168.0.4 px1.home.yourdomain.com"
# Act as DNS resolver by forwarding queries that cannot be answered locally via DNS-over-TLS (DoT)
forward-zone:
name: "."
forward-ssl-upstream: yes
# NextDNS (REPLACE ID with your actual ID)
forward-addr: 45.90.28.194@853#ID.dns.nextdns.io
forward-addr: 45.90.30.194@853#ID.dns.nextdns.io
forward-addr: 2a07:a8c0::ID@853#ID.dns.nextdns.io
forward-addr: 2a07:a8c1::ID@853#ID.dns.nextdns.io
# Quad9
# forward-addr: 9.9.9.9@853#dns.quad9.net
# forward-addr: 149.112.112.112@853#dns.quad9.net
# forward-addr: 2620:fe::fe@853#dns.quad9.net
# forward-addr: 2620:fe::9@853#dns.quad9.net
Check your new configuration by running the command unbound-checkconf
. The output should look similar to the following:
unbound-checkconf: no errors in /etc/unbound/unbound.conf
Restart Unbound:
$ systemctl restart unbound
Firewall Rule for DNS
See this earlier article for information on how to configure Proxmox’s firewall. Add a rule to allow DNS traffic:
- Direction:
in
- Action:
ACCEPT
- Macro:
DNS
- Enable: checked
Unbound Configuration Backup
Add Unbound’s configuration file as a backup source to resticprofile (more info on restic):
source:
- "/etc/unbound/unbound.conf"
Switch the Local Resolver
On the Proxmox server, switch the local resolver to Unbound by editing /etc/resolv.conf
and replacing the nameserver
line with the following:
nameserver 127.0.0.1
There’s no need to restart any services. The change becomes active immediately.
Test DNS Resolution
Test on the DNS Server
Test DNS resolution on the Proxmox server with the dig
command. The output should show the server as 127.0.0.1
, as in the following example:
$ dig helgeklein.com
; <<>> DiG 9.16.37-Debian <<>> helgeklein.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1893
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;helgeklein.com. IN A
;; ANSWER SECTION:
helgeklein.com. 181 IN A 104.26.10.91
helgeklein.com. 181 IN A 172.67.74.112
helgeklein.com. 181 IN A 104.26.11.91
;; Query time: 144 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Jun 03 02:44:33 CEST 2023
;; MSG SIZE rcvd: 91
Test on Another Machine on Your Network
Test name resolution on another machine on your network, e.g., on Windows, with the following command:
$ nslookup helgeklein.com 192.168.0.4
Assigning a Private IPv6 Address to Proxmox
The machine on which we installed the Unbound DNS server needs static IPv4 and IPv6 addresses. If you followed my Proxmox guide, your server already has a static IPv4 address. We’ll add a static IPv6 address now.
Generate Your IPv6 Unique Local Address (ULA) Prefix
IPv6 unique local addresses (ULAs) are used similarly to private IPv4 addresses, such as 192.168.0.0/16
. Create your own ULA prefix at unique-local-ipv6.com. You’ll get something like fd7b:a864:8b59::/48
.
Assign the IPv6 ULA Prefix to Your Router
Configure your router to always assign unique local addresses (ULAs) and use the ULA prefix you generated above.
If you have a Fritz!Box like me, navigate to Home Network > Network > Network Settings > IP Addresses > IPv6 Settings > Unique Local Addresses, and configure the following:
- Always assign unique local addresses (ULA): checked
- Set ULA prefix manually:
- Checked
- Enter the ULA prefix you generated above. e.g.,
fd7b:a864:8b59::/64
.
Enable IPv6 Router Advertisements on Proxmox
Apparently, Linux ignores router advertisements when forwarding is enabled. Check with the following command if you’re affected:
$ cat /proc/sys/net/ipv6/conf/vmbr0/accept_ra
If it prints 1
, you need to switch the accept_ra
setting to 2
by adding the following to the iface vmbr0 inet static
entry in /etc/network/interfaces
:
# Accept IPv6 router advertisements even when forwarding is enabled
accept_ra 2
Reboot and verify the changed setting has been applied.
Obtain Your Proxmox Server’s IPv6 Address
Reboot your Proxmox server. List all IPv6 addresses with the command ip -6 addr
. The output should look like the following:
3: vmbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 fd7b:a864:8b59:0:12:34:56:78/64 scope global dynamic mngtmpaddr
valid_lft 7195sec preferred_lft 3595sec
inet6 REDACTED scope global dynamic mngtmpaddr
valid_lft 7195sec preferred_lft 3595sec
inet6 fe80::REDACTED/64 scope link
valid_lft forever preferred_lft forever
In the output above, the Proxmox server’s unique local address (ULA) is fd7b:a864:8b59:0:12:34:56:78
.
Switch Your Network’s DNS Server
Now that your new DNS resolver is fully operational, it’s time to configure your home network’s devices to use it. How that is done depends on your setup.
Fritz!Box
If you have a Fritz!Box like me, navigate to Home Network > Network > Network Settings > IP Addresses.
IPv4 DNS Server
To change the IPv4 DNS server assigned via DHCP, navigate to IPv4 Settings > Home Network and configure the following:
- Local DNS Server:
192.168.0.4
IPv6 DNS Server
To change the IPv6 DNS server assigned via DHCPv6 and router assignments, navigate to IPv6 Settings > DNSv6 Server in the Home Network and configure the following:
- Local DNSv6 server: enter your Proxmox server’s ULA (in the example above:
fd7b:a864:8b59:0:12:34:56:78
) - Also announce DNSv6 server via router advertisement (RFC 5006): checked
Changelog
2024-05-31
- More specific interface bindings in
unbound.conf
to enable other DNS servers on individual IP addresses.
2023-10-21
- Fixed incorrect description of how to set
accept_ra
in Enable IPv6 Router Advertisements on Proxmox.
2023-06-12
Made the following changes to /etc/unbound/unbound.conf
:
- Replaced previous
access-control
entries with new ones that allow access from every IP address. The DNS server is in a private network; restrictions only cause problems. - Added
interface-automatic: yes
or Unbound would ignore/drop DNS requests from a WireGuard (Firezone) Docker container.
2023-06-08
Made the following changes to /etc/unbound/unbound.conf
:
- Added
access-control
entries for private IPv6 networks, or the server wouldn’t answer on the IPv6 ULA address (and returnrefused
instead). - Removed
PTR
records for the dockerized services because they all pointed to the same (host) IP address. - Switched the
local-zone
fromstatic
totransparent
to allow forwarding of queries for records not defined locally vialocal-data
.
1 Comment
Can you please explain why IPv6 is needed?
Unfortuenately my internet provider does not support IPv6 configuration on the router. If i only have IPv4 available, what areas of your server setup will I be missing out on?
My primary interest is getting proxmox, Docker and Portainer working, prefferably with https.