diff --git a/conf/NetworkManager.conf b/conf/NetworkManager.conf new file mode 100644 index 00000000..72c85bcf --- /dev/null +++ b/conf/NetworkManager.conf @@ -0,0 +1,2 @@ +[main] +dns=unbound diff --git a/conf/unbound.conf b/conf/unbound.conf new file mode 100644 index 00000000..ae6d53bb --- /dev/null +++ b/conf/unbound.conf @@ -0,0 +1,56 @@ +server: + # 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 + + # 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 + + # 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" # + +remote-control: + control-enable: yes + control-port: 953 diff --git a/management/dns_update.py b/management/dns_update.py index 62a053f5..79b9ad8a 100755 --- a/management/dns_update.py +++ b/management/dns_update.py @@ -115,9 +115,9 @@ def do_dns_update(env, force=False): # If this is the only thing that changed? updated_domains.append("DKIM 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", "reload"], trap=True) if len(updated_domains) == 0: # if nothing was updated (except maybe DKIM's files), don't show any output diff --git a/management/status_checks.py b/management/status_checks.py index 5554cf0f..040695d8 100755 --- a/management/status_checks.py +++ b/management/status_checks.py @@ -22,9 +22,8 @@ from utils import shell, sort_domains, load_env_vars_from_file, load_settings 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, }, @@ -49,15 +48,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", "reload"], trap=True) run_system_checks(rounded_values, env, output) @@ -793,7 +792,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() if at: diff --git a/setup/dns.sh b/setup/dns.sh index fd0dec90..f24eb56b 100755 --- a/setup/dns.sh +++ b/setup/dns.sh @@ -14,7 +14,7 @@ echo "Installing nsd (DNS server)..." # 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 @@ -40,7 +40,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. diff --git a/setup/system.sh b/setup/system.sh index 4d5ae33b..0d433463 100755 --- a/setup/system.sh +++ b/setup/system.sh @@ -310,50 +310,33 @@ 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: -# -# * 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 -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 "listen-on-v6 " /etc/bind/named.conf.options; then - # Add a listen-on-v6 directive if it doesn't exist inside the options block. - sed -i "s/^}/\n\tlisten-on-v6 { ::1; };\n}/" /etc/bind/named.conf.options -else - # Modify the listen-on-v6 directive if it does exist - sed -i "s/listen-on-v6 { any; }/listen-on-v6 { ::1; }/" /etc/bind/named.conf.options -fi +# remove bind9 in case it is still there +apt-get purge -qq -y bind9 -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 -fi +# Install unbound and dns utils (e.g. dig) +apt_install unbound python3-unbound bind9-dnsutils -# 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. -rm -f /etc/resolv.conf -tools/editconf.py /etc/systemd/resolved.conf DNSStubListener=no -echo "nameserver 127.0.0.1" > /etc/resolv.conf +# Configure unbound +cp -f conf/unbound.conf /etc/unbound/unbound.conf.d/miabunbound.conf + +# Configure network manager +mkdir /etc/NetworkManager/conf.d +cp -f conf/NetworkManager.conf /etc/NetworkManager/conf.d/unbound.conf + +# Modify systemd settings +tools/editconf.py /etc/systemd/resolv.conf \ + DNS=127.0.0.1 \ + DNSSEC=yes \ + DNSStubListener=no # Restart the DNS services. -restart_service bind9 systemctl restart systemd-resolved +systemctl restart unbound # ### Fail2Ban Service