2014-07-19 16:31:05 +00:00
#!/bin/bash
2014-10-04 21:57:26 +00:00
# DNS
2014-09-21 17:43:21 +00:00
# -----------------------------------------------
2013-09-01 14:13:51 +00:00
2014-06-13 00:18:53 +00:00
# This script installs packages, but the DNS zone files are only
# created by the /dns/update API in the management server because
# the set of zones (domains) hosted by the server depends on the
# mail users & aliases created by the user later.
2013-09-01 14:13:51 +00:00
2014-06-03 11:12:38 +00:00
source setup/functions.sh # load our functions
2014-10-08 12:48:43 +00:00
source /etc/mailinabox.conf # load global vars
2014-05-01 19:13:00 +00:00
2014-04-18 00:17:24 +00:00
# Prepare nsd's configuration.
2020-04-24 10:37:59 +00:00
# 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
2014-10-04 18:06:08 +00:00
mkdir -p /var/run/nsd
2020-04-11 23:44:19 +00:00
mkdir -p /etc/nsd
mkdir -p /etc/nsd/zones
2020-04-22 15:25:12 +00:00
touch /etc/nsd/zones.conf
2020-04-11 23:44:19 +00:00
touch /etc/nsd/nsd.conf
2013-09-01 14:13:51 +00:00
2015-05-04 11:19:48 +00:00
cat > /etc/nsd/nsd.conf << EOF;
2017-04-10 16:37:09 +00:00
# Do not edit. Overwritten by Mail-in-a-Box setup.
2015-05-04 11:19:48 +00:00
server:
hide-version: yes
2018-12-02 23:00:16 +00:00
logfile: "/var/log/nsd.log"
2015-05-04 11:19:48 +00:00
# identify the server (CH TXT ID.SERVER entry).
identity: ""
# The directory for zonefile: files.
zonesdir: "/etc/nsd/zones"
2015-05-04 11:22:57 +00:00
# Allows NSD to bind to IP addresses that are not (yet) added to the
# network interface. This allows nsd to start even if the network stack
# isn't fully ready, which apparently happens in some cases.
# See https://www.nlnetlabs.nl/projects/nsd/nsd.conf.5.html.
ip-transparent: yes
2015-05-04 11:19:48 +00:00
EOF
# Since we have bind9 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.
for ip in $PRIVATE_IP $PRIVATE_IPV6 ; do
echo " ip-address: $ip " >> /etc/nsd/nsd.conf;
done
2021-09-24 12:07:40 +00:00
# Create a directory for additional configuration directives, including
# the zones.conf file written out by our management daemon.
echo "include: /etc/nsd/nsd.conf.d/*.conf" >> /etc/nsd/nsd.conf;
# Remove the old location of zones.conf that we generate. It will
# now be stored in /etc/nsd/nsd.conf.d.
rm -f /etc/nsd/zones.conf
2015-05-04 11:19:48 +00:00
2020-04-24 10:37:59 +00:00
# Add log rotation
cat > /etc/logrotate.d/nsd <<EOF;
/var/log/nsd.log {
weekly
missingok
rotate 12
compress
delaycompress
notifempty
}
EOF
# Install the packages.
#
# * nsd: The non-recursive nameserver that publishes our DNS records.
# * ldnsutils: Helper utilities for signing DNSSEC zones.
# * openssh-client: Provides ssh-keyscan which we use to create SSHFP records.
echo "Installing nsd (DNS server)..."
apt_install nsd ldnsutils openssh-client
2020-04-11 23:44:19 +00:00
2014-06-17 22:21:12 +00:00
# Create DNSSEC signing keys.
mkdir -p " $STORAGE_ROOT /dns/dnssec " ;
2014-10-04 17:29:42 +00:00
2021-06-27 21:24:26 +00:00
# TLDs, registrars, and validating nameservers don't all support the same algorithms,
# so we'll generate keys using a few different algorithms so that dns_update.py can
# choose which algorithm to use when generating the zonefiles. See #1953 for recent
# discussion. File for previously used algorithms (i.e. RSASHA1-NSEC3-SHA1) may still
# be in the output directory, and we'll continue to support signing zones with them
# so that trust isn't broken with deployed DS records, but we won't generate those
# keys on new systems.
2014-10-04 21:57:26 +00:00
FIRST = 1 #NODOC
2021-06-27 21:24:26 +00:00
for algo in RSASHA256 ECDSAP256SHA256; do
2014-10-04 17:29:42 +00:00
if [ ! -f " $STORAGE_ROOT /dns/dnssec/ $algo .conf " ] ; then
if [ $FIRST = = 1 ] ; then
2015-11-17 22:11:35 +00:00
echo "Generating DNSSEC signing keys..."
2014-10-04 21:57:26 +00:00
FIRST = 0 #NODOC
2014-10-04 17:29:42 +00:00
fi
2014-06-17 22:21:12 +00:00
2014-10-13 14:00:26 +00:00
# Create the Key-Signing Key (KSK) (with `-k`) which is the so-called
# Secure Entry Point. The domain name we provide ("_domain_") doesn't
2021-06-27 21:24:26 +00:00
# matter -- we'll use the same keys for all our domains.
2014-10-04 21:57:26 +00:00
#
# `ldns-keygen` outputs the new key's filename to stdout, which
# we're capturing into the `KSK` variable.
2015-11-17 20:41:13 +00:00
#
2015-11-17 22:11:35 +00:00
# ldns-keygen uses /dev/random for generating random numbers by default.
# This is slow and unecessary if we ensure /dev/urandom is seeded properly,
# so we use /dev/urandom. See system.sh for an explanation. See #596, #115.
2021-06-27 21:24:26 +00:00
# (This previously used -b 2048 but it's unclear if this setting makes sense
# for non-RSA keys, so it's removed. The RSA-based keys are not recommended
# anymore anyway.)
KSK = $( umask 077; cd $STORAGE_ROOT /dns/dnssec; ldns-keygen -r /dev/urandom -a $algo -k _domain_) ;
2014-06-17 22:21:12 +00:00
# Now create a Zone-Signing Key (ZSK) which is expected to be
# rotated more often than a KSK, although we have no plans to
# rotate it (and doing so would be difficult to do without
2021-06-27 21:24:26 +00:00
# disturbing DNS availability.) Omit `-k`.
# (This previously used -b 1024 but it's unclear if this setting makes sense
# for non-RSA keys, so it's removed.)
ZSK = $( umask 077; cd $STORAGE_ROOT /dns/dnssec; ldns-keygen -r /dev/urandom -a $algo _domain_) ;
2014-06-17 22:21:12 +00:00
# These generate two sets of files like:
2014-09-21 17:43:21 +00:00
#
2021-06-27 21:24:26 +00:00
# * `K_domain_.+007+08882.ds`: DS record normally provided to domain name registrar (but it's actually invalid with `_domain_` so we don't use this file)
2014-10-13 14:00:26 +00:00
# * `K_domain_.+007+08882.key`: public key
2014-09-21 17:43:21 +00:00
# * `K_domain_.+007+08882.private`: private key (secret!)
2014-06-17 22:21:12 +00:00
# The filenames are unpredictable and encode the key generation
# options. So we'll store the names of the files we just generated.
# We might have multiple keys down the road. This will identify
# what keys are the current keys.
2014-10-04 17:29:42 +00:00
cat > $STORAGE_ROOT /dns/dnssec/$algo .conf << EOF;
2014-06-17 22:21:12 +00:00
KSK = $KSK
ZSK = $ZSK
EOF
fi
2014-10-04 21:57:26 +00:00
# And loop to do the next algorithm...
2014-10-04 17:29:42 +00:00
done
2014-06-17 22:21:12 +00:00
2014-10-04 21:57:26 +00:00
# Force the dns_update script to be run every day to re-sign zones for DNSSEC
# before they expire. When we sign zones (in `dns_update.py`) we specify a
# 30-day validation window, so we had better re-sign before then.
2014-06-17 22:21:12 +00:00
cat > /etc/cron.daily/mailinabox-dnssec << EOF;
2014-07-25 12:15:30 +00:00
#!/bin/bash
2014-06-17 22:21:12 +00:00
# Mail-in-a-Box
# Re-sign any DNS zones with DNSSEC because the signatures expire periodically.
2021-06-27 21:24:26 +00:00
$( pwd ) /tools/dns_update
2014-06-17 22:21:12 +00:00
EOF
chmod +x /etc/cron.daily/mailinabox-dnssec
2013-09-01 14:13:51 +00:00
# Permit DNS queries on TCP/UDP in the firewall.
2013-08-21 20:53:22 +00:00
2014-05-01 19:35:18 +00:00
ufw_allow domain
2013-08-21 20:53:22 +00:00