Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace bind9 with unbound #2193

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions conf/unbound.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
server:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How different is this from the stock configuration file when ubound is installed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A number of the options here are indeed the default for a stock configuration. The main differences are probably in the performance and hardening settings.
Some testing seems to confirm the unbound configuration will work out of the box.

# the working directory.
directory: "/etc/unbound"

# run as the unbound user
username: unbound

verbosity: 0 # uncomment and increase to get more logging.
# logfile: "/var/log/unbound.log" # won't work due to apparmor
# use-syslog: no
Comment on lines +9 to +10
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming back to this PR...

Is unbound logging to somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's logging to the systemd journal and to the syslog.


# By default listen only to localhost
#interface: ::1
#interface: 127.0.0.1
port: 53

# Only allow localhost to use this Unbound instance.
access-control: 127.0.0.1/8 allow
access-control: ::1/128 allow

# Private IP ranges, which shall never be returned or forwarded as public DNS response.
private-address: 10.0.0.0/8
private-address: 172.16.0.0/12
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: fd00::/8
private-address: fe80::/10

# Functionality
do-ip4: yes
do-ip6: yes
do-udp: yes
do-tcp: yes

# Performance
num-threads: 2
cache-min-ttl: 300
cache-max-ttl: 86400
serve-expired: yes
neg-cache-size: 4M
msg-cache-size: 50m
rrset-cache-size: 100m

so-reuseport: yes
so-rcvbuf: 4m
so-sndbuf: 4m

# Privacy / hardening
# hide server info from clients
hide-identity: yes
hide-version: yes
harden-glue: yes
harden-dnssec-stripped: yes
harden-algo-downgrade: yes
harden-large-queries: yes
harden-short-bufsize: yes

rrset-roundrobin: yes
minimal-responses: yes
identity: "Server"

# Include possible white/blacklists
include: /etc/unbound/lists.d/*.conf

remote-control:
control-enable: yes
control-port: 953

4 changes: 2 additions & 2 deletions management/dns_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ def do_dns_update(env, force=False):
# If this is the only thing that changed?
updated_domains.append("OpenDKIM configuration")

# Clear bind9's DNS cache so our own DNS resolver is up to date.
# Clear unbound's DNS cache so our own DNS resolver is up to date.
# (ignore errors with trap=True)
shell('check_call', ["/usr/sbin/rndc", "flush"], trap=True)
shell('check_call', ["/usr/sbin/unbound-control", "flush_zone", ".", "-q"], trap=True)

if len(updated_domains) == 0:
# if nothing was updated (except maybe OpenDKIM's files), don't show any output
Expand Down
15 changes: 7 additions & 8 deletions management/status_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@

def get_services():
return [
{ "name": "Local DNS (bind9)", "port": 53, "public": False, },
#{ "name": "NSD Control", "port": 8952, "public": False, },
{ "name": "Local DNS Control (bind9/rndc)", "port": 953, "public": False, },
{ "name": "Local DNS (unbound)", "port": 53, "public": False, },
{ "name": "Local DNS Control (unbound)", "port": 953, "public": False, },
{ "name": "Dovecot LMTP LDA", "port": 10026, "public": False, },
{ "name": "Postgrey", "port": 10023, "public": False, },
{ "name": "Spamassassin", "port": 10025, "public": False, },
Expand All @@ -48,15 +47,15 @@ def run_checks(rounded_values, env, output, pool, domains_to_check=None):

# check that services are running
if not run_services_checks(env, output, pool):
# If critical services are not running, stop. If bind9 isn't running,
# If critical services are not running, stop. If unbound isn't running,
# all later DNS checks will timeout and that will take forever to
# go through, and if running over the web will cause a fastcgi timeout.
return

# clear bind9's DNS cache so our DNS checks are up to date
# (ignore errors; if bind9/rndc isn't running we'd already report
# clear unbound's DNS cache so our DNS checks are up to date
# (ignore errors; if unbound isn't running we'd already report
# that in run_services checks.)
shell('check_call', ["/usr/sbin/rndc", "flush"], trap=True)
shell('check_call', ["/usr/sbin/unbound-control", "flush_zone", ".", "-q"], trap=True)

run_system_checks(rounded_values, env, output)

Expand Down Expand Up @@ -778,7 +777,7 @@ def query_dns(qname, rtype, nxdomain='[Not Set]', at=None, as_list=False):
qname += "."

# Use the default nameservers (as defined by the system, which is our locally
# running bind server), or if the 'at' argument is specified, use that host
# running unbound server), or if the 'at' argument is specified, use that host
# as the nameserver.
resolver = dns.resolver.get_default_resolver()

Expand Down
4 changes: 2 additions & 2 deletions setup/dns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ source /etc/mailinabox.conf # load global vars

# Prepare nsd's configuration.
# We configure nsd before installation as we only want it to bind to some addresses
# and it otherwise will have port / bind conflicts with bind9 used as the local resolver
# and it otherwise will have port / bind conflicts with unbound used as the local resolver
mkdir -p /var/run/nsd
mkdir -p /etc/nsd
mkdir -p /etc/nsd/zones
Expand All @@ -38,7 +38,7 @@ server:

EOF

# Since we have bind9 listening on localhost for locally-generated
# Since we have unbound listening on localhost for locally-generated
# DNS queries that require a recursive nameserver, and the system
# might have other network interfaces for e.g. tunnelling, we have
# to be specific about the network interfaces that nsd binds to.
Expand Down
57 changes: 27 additions & 30 deletions setup/system.sh
Original file line number Diff line number Diff line change
Expand Up @@ -315,45 +315,42 @@ fi #NODOC
# DNS server, which won't work for RBLs. So we really need a local recursive
# nameserver.
#
# We'll install `bind9`, which as packaged for Ubuntu, has DNSSEC enabled by default via "dnssec-validation auto".
# We'll install unbound, which as packaged for Ubuntu, has DNSSEC enabled by default.
# We'll have it be bound to 127.0.0.1 so that it does not interfere with
# the public, recursive nameserver `nsd` bound to the public ethernet interfaces.
#
# About the settings:
#
# * Adding -4 to OPTIONS will have `bind9` not listen on IPv6 addresses
# so that we're sure there's no conflict with nsd, our public domain
# name server, on IPV6.
# * The listen-on directive in named.conf.options restricts `bind9` to
# binding to the loopback interface instead of all interfaces.
# * The max-recursion-queries directive increases the maximum number of iterative queries.
# If more queries than specified are sent, bind9 returns SERVFAIL. After flushing the cache during system checks,
# we ran into the limit thus we are increasing it from 75 (default value) to 100.
apt_install bind9
tools/editconf.py /etc/default/named \
"OPTIONS=\"-u bind -4\""
if ! grep -q "listen-on " /etc/bind/named.conf.options; then
# Add a listen-on directive if it doesn't exist inside the options block.
sed -i "s/^}/\n\tlisten-on { 127.0.0.1; };\n}/" /etc/bind/named.conf.options
fi
if ! grep -q "max-recursion-queries " /etc/bind/named.conf.options; then
# Add a max-recursion-queries directive if it doesn't exist inside the options block.
sed -i "s/^}/\n\tmax-recursion-queries 100;\n}/" /etc/bind/named.conf.options

# remove bind9 in case it is still there
apt-get purge -qq -y bind9 bind9-utils

# Install unbound and dns utils (e.g. dig)
apt_install unbound bind9-dnsutils

# Configure unbound
cp -f conf/unbound.conf /etc/unbound/unbound.conf.d/miabunbound.conf

mkdir -p /etc/unbound/lists.d

systemctl restart unbound

unbound-control -q status

# Only reset the local dns settings if unbound server is running, otherwise we'll
# up with a system with an unusable internet connection
if [ $? -ne 0 ]; then
echo "Recursive DNS server not active"
exit 1
fi

# First we'll disable systemd-resolved's management of resolv.conf and its stub server.
# Breaking the symlink to /run/systemd/resolve/stub-resolv.conf means
# systemd-resolved will read it for DNS servers to use. Put in 127.0.0.1,
# which is where bind9 will be running. Obviously don't do this before
# installing bind9 or else apt won't be able to resolve a server to
# download bind9 from.
# Modify systemd settings
rm -f /etc/resolv.conf
tools/editconf.py /etc/systemd/resolved.conf DNSStubListener=no
tools/editconf.py /etc/systemd/resolved.conf \
DNS=127.0.0.1 \
DNSSEC=yes \
DNSStubListener=no
echo "nameserver 127.0.0.1" > /etc/resolv.conf

# Restart the DNS services.

restart_service bind9
systemctl restart systemd-resolved

# ### Fail2Ban Service
Expand Down