1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2024-11-22 02:17:26 +00:00
mailinabox/scripts/dns_update.sh

136 lines
4.1 KiB
Bash
Executable File

#!/bin/bash
# DNS: Creates DNS zone files
#############################
# Create nsd.conf and zone files, and updates the OpenDKIM signing tables.
# We set the administrative email address for every domain to domain_contact@[domain.com].
# You should probably create an alias to your email address.
# This script is safe to run on its own.
source /etc/mailinabox.conf # load global vars
# Ensure a zone file exists for every domain name in use by a mail user.
for mail_user in `tools/mail.py user`; do
domain=`echo $mail_user | sed s/.*@//`
if [ ! -f $STORAGE_ROOT/dns/$domain.txt ]; then
echo "" > $STORAGE_ROOT/dns/$domain.txt;
fi
done
# Create the top of nsd.conf.
cat > /etc/nsd/nsd.conf << EOF;
server:
hide-version: yes
# identify the server (CH TXT ID.SERVER entry).
identity: ""
# The directory for zonefile: files.
zonesdir: "/etc/nsd/zones"
# ZONES
EOF
# For every zone file in our dns directory, build a proper zone
# file and mention it in nsd.conf. And add information to the
# OpenDKIM signing tables.
mkdir -p /etc/nsd/zones;
truncate --size 0 /etc/opendkim/KeyTable
truncate --size 0 /etc/opendkim/SigningTable
for fn in $STORAGE_ROOT/dns/*.txt; do
# $fn is the zone configuration file, which is just a placeholder now.
# For every file like mydomain.com.txt we'll create zone information
# for that domain. We don't actually read the file.
# $fn2 is the file without the directory.
# $zone is the domain name (just mydomain.com).
fn2=`basename $fn`
zone=`echo $fn2 | sed "s/.txt\$//"`
# If the zone file exists, get the existing zone serial number so we can increment it.
# TODO: This needs to be done better so that the existing serial number is persisted in the storage area.
serial=`date +"%Y%m%d00"`
if [ -f /etc/nsd/zones/$fn2 ]; then
existing_serial=`grep "serial number" /etc/nsd/zones/$fn2 | sed "s/; serial number//"`
if [ ! -z "$existing_serial" ]; then
serial=`echo $existing_serial + 1 | bc`
fi
fi
# Create the zone file.
cat > /etc/nsd/zones/$fn2 << EOF;
\$ORIGIN $zone. ; default zone domain
\$TTL 86400 ; default time to live
@ IN SOA ns1.$PUBLIC_HOSTNAME. hostmaster.$PUBLIC_HOSTNAME. (
$serial ; serial number
28800 ; Refresh
7200 ; Retry
864000 ; Expire
86400 ; Min TTL
)
NS ns1.$PUBLIC_HOSTNAME.
NS ns2.$PUBLIC_HOSTNAME.
IN A $PUBLIC_IP
MX 10 $PUBLIC_HOSTNAME.
300 TXT "v=spf1 mx -all"
www IN A $PUBLIC_IP
EOF
# In PUBLIC_HOSTNAME, also define ns1 and ns2.
if [ "$zone" = $PUBLIC_HOSTNAME ]; then
cat >> /etc/nsd/zones/$fn2 << EOF;
ns1 IN A $PUBLIC_IP
ns2 IN A $PUBLIC_IP
EOF
fi
# If OpenDKIM is set up..
if [ -f "$STORAGE_ROOT/mail/dkim/mail.txt" ]; then
# Append the DKIM TXT record to the zone as generated by OpenDKIM.
cat "$STORAGE_ROOT/mail/dkim/mail.txt" >> /etc/nsd/zones/$fn2;
# Append ADSP (RFC 5617) and DMARC records.
cat >> /etc/nsd/zones/$fn2 << EOF;
_adsp._domainkey IN TXT "dkim=all"
_dmarc IN TXT "v=DMARC1; p=quarantine"
EOF
fi
# Add this zone file to the main nsd configuration file.
cat >> /etc/nsd/nsd.conf << EOF;
zone:
name: $zone
zonefile: $fn2
EOF
# Append a record to OpenDKIM's KeyTable and SigningTable. The SigningTable maps
# email addresses to signing information. The KeyTable maps specify the hostname,
# the selector, and the path to the private key.
#
# DKIM ADSP and DMARC both only support policies where the signing domain matches
# the From address, so the KeyTable must specify that the signing domain for a
# sender matches the sender's domain.
#
# In SigningTable, we map every email address to a key record called $zone.
# Then we specify for the key record named $zone its domain, selector, and key.
echo "$zone $zone:mail:$STORAGE_ROOT/mail/dkim/mail.private" >> /etc/opendkim/KeyTable
echo "*@$zone $zone" >> /etc/opendkim/SigningTable
done
# Kick nsd.
service nsd restart
# Kick opendkim.
service opendkim restart