DNS, SPF, and DKIM

This commit is contained in:
Joshua Tauberer 2013-08-21 16:53:22 -04:00
parent e06b4f5ccf
commit 5cef1bb63d
8 changed files with 179 additions and 4 deletions

View File

@ -41,6 +41,8 @@ Then launch a new instance. We're creating a m1.small instance --- it's the smal
source ec2/start_instance.sh source ec2/start_instance.sh
It will wait until the instance is available. It will wait until the instance is available.
You'll probably want to associate it with an Elastic IP. If you do, you'll need to update the INSTANCE_IP variable.
Configure the server: Configure the server:

View File

@ -7,7 +7,8 @@ UBUNTU_CONFIG="us-east-1 13.04 amd64 instance-store"
export AMI=`curl -s http://cloud-images.ubuntu.com/locator/ec2/releasesTable | python3 tools/get_ubuntu_ami.py $UBUNTU_CONFIG` export AMI=`curl -s http://cloud-images.ubuntu.com/locator/ec2/releasesTable | python3 tools/get_ubuntu_ami.py $UBUNTU_CONFIG`
ec2-create-group -d "mailinabox" "mailinabox" ec2-create-group -d "mailinabox" "mailinabox"
for PORT in 25 587 993; do ec2-authorize mailinabox -P tcp -p $PORT -s 0.0.0.0/0; done for PORT in 25 53 587 993; do ec2-authorize mailinabox -P tcp -p $PORT -s 0.0.0.0/0; done
for PORT in 53; do ec2-authorize mailinabox -P udp -p $PORT -s 0.0.0.0/0; done
ec2run $AMI -k $EC2_KEYPAIR_NAME -t m1.small -z $AWS_AZ -g mailinabox > instance.info ec2run $AMI -k $EC2_KEYPAIR_NAME -t m1.small -z $AWS_AZ -g mailinabox > instance.info
export INSTANCE=`cat instance.info | grep INSTANCE | awk {'print $2'}` export INSTANCE=`cat instance.info | grep INSTANCE | awk {'print $2'}`

45
scripts/dkim.sh Normal file
View File

@ -0,0 +1,45 @@
# Install OpenDKIM.
#
# After this, you'll still need to run dns_update to get the DKIM
# signature in the DNS zones.
apt-get install -q -y opendkim opendkim-tools
mkdir -p /etc/opendkim;
mkdir -p $STORAGE_ROOT/mail/dkim
echo "127.0.0.1" > /etc/opendkim/TrustedHosts
if grep -q "ExternalIgnoreList" /etc/opendkim.conf; then
true; # already done
else
cat >> /etc/opendkim.conf << EOF;
MinimumKeyBits 1024
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
Socket inet:8891@localhost
RequireSafeKeys false
EOF
fi
# Create a new DKIM key if we don't have one already.
if [ ! -z "$STORAGE_ROOT/mail/dkim/mail.private" ]; then
# Should we specify -h rsa-sha256?
opendkim-genkey -r -s mail -D $STORAGE_ROOT/mail/dkim
fi
chown -R opendkim:opendkim $STORAGE_ROOT/mail/dkim
chmod go-rwx $STORAGE_ROOT/mail/dkim
# add OpenDKIM as a milter to postfix. Be careful. If we add other milters
# later, it needs to be concatenated on the smtpd_milters line.
tools/editconf.py /etc/postfix/main.cf \
smtpd_milters=inet:127.0.0.1:8891 \
non_smtpd_milters=\$smtpd_milters \
milter_default_action=accept
service opendkim restart
service postfix restart

36
scripts/dns.sh Normal file
View File

@ -0,0 +1,36 @@
# Configures a DNS server using nsd.
#
# After running this script, you also must run scripts/dns_update.sh,
# and any time a zone file is added/changed/removed. It should be
# run after DKIM is configured, however.
apt-get -qq -y install nsd3
if [ -z "$PUBLIC_HOSTNAME" ]; then
PUBLIC_HOSTNAME=example.org
fi
if [ -z "$PUBLIC_IP" ]; then
# works on EC2 only...
PUBLIC_IP=`wget -q -O- http://instance-data/latest/meta-data/public-ipv4`
fi
sudo mkdir -p /var/run/nsd3
mkdir -p "$STORAGE_ROOT/dns";
# Store our desired IP address (to put in the zone files) for later.
echo $PUBLIC_IP > $STORAGE_ROOT/dns/our_ip
# Create the default zone if it doesn't exist.
if [ ! -f "$STORAGE_ROOT/dns/$PUBLIC_HOSTNAME.txt" ]; then
# can be an empty file, defaults are applied elsewhere
cat > "$STORAGE_ROOT/dns/$PUBLIC_HOSTNAME.txt" << EOF;
EOF
fi
chown -R ubuntu.ubuntu $STORAGE_ROOT/dns
ufw allow domain

89
scripts/dns_update.sh Normal file
View File

@ -0,0 +1,89 @@
# Create nsd.conf and zone files, and updates the OpenDKIM signing tables.
PUBLIC_IP=`cat $STORAGE_ROOT/dns/our_ip`
# Create the top of nsd.conf.
cat > /etc/nsd3/nsd.conf << EOF;
server:
hide-version: yes
# identify the server (CH TXT ID.SERVER entry).
identity: ""
# The directory for zonefile: files.
zonesdir: "/etc/nsd3/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/nsd3/zones;
truncate --size 0 /etc/opendkim/KeyTable
truncate --size 0 /etc/opendkim/SigningTable
for fn in $STORAGE_ROOT/dns/*.txt; do
fn2=`basename $fn`
zone=`echo $fn2 | sed "s/.txt\$//"`
# If the zone file exists, increment the serial number.
# 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/nsd3/zones/$fn2 ]; then
existing_serial=`grep "serial number" /etc/nsd3/zones/$fn2 | sed "s/; serial number//"`
if [ ! -z "$existing_serial" ]; then
serial=`echo $existing_serial + 1 | bc`
fi
fi
cat > /etc/nsd3/zones/$fn2 << EOF;
\$ORIGIN $zone. ; default zone domain
\$TTL 86400 ; default time to live
@ IN SOA ns1.$zone. domain_contact.$zone. (
$serial ; serial number
28800 ; Refresh
7200 ; Retry
864000 ; Expire
86400 ; Min TTL
)
NS ns1.$zone.
IN A $PUBLIC_IP
MX 10 mail.$zone.
300 TXT "v=spf1 mx -all"
mail IN A $PUBLIC_IP
EOF
# If OpenDKIM is set up, append that information to the zone.
if [ -f "$STORAGE_ROOT/mail/dkim/mail.txt" ]; then
cat "$STORAGE_ROOT/mail/dkim/mail.txt" >> /etc/nsd3/zones/$fn2;
fi
cat >> /etc/nsd3/nsd.conf << EOF;
zone:
name: $zone
zonefile: $fn2
EOF
# OpenDKIM
echo "$zone $zone:mail:$STORAGE_ROOT/mail/dkim/mail.private" >> /etc/opendkim/KeyTable
echo "*@$zone $zone" >> /etc/opendkim/SigningTable
done
# Kick nsd.
service nsd3 rebuild
service nsd3 restart # ensure it is running
# Kick opendkim.
service opendkim restart

View File

@ -1,3 +1,6 @@
. scripts/system.sh . scripts/system.sh
. scripts/dns.sh
. scripts/mail.sh . scripts/mail.sh
. scripts/dkim.sh
. scripts/dns_update.sh

View File

@ -20,7 +20,6 @@ apt-get install -q -y ntp fail2ban
# Turn on the firewall. First allow incoming SSH, then turn on the firewall. Additional open # Turn on the firewall. First allow incoming SSH, then turn on the firewall. Additional open
# ports will be set up in the scripts that set up those services. # ports will be set up in the scripts that set up those services.
ufw allow ssh ufw allow ssh
#ufw allow domain
#ufw allow http #ufw allow http
#ufw allow https #ufw allow https
ufw --force enable ufw --force enable

View File

@ -1,6 +1,6 @@
import smtplib, sys, os import smtplib, sys, os
fromaddr = "testuser@testdomain.com" fromaddr = "testuser@" + os.environ.get("DOMAIN", "testdomain.com")
msg = """From: %s msg = """From: %s
To: %s To: %s
@ -10,7 +10,7 @@ This is a test message.""" % (fromaddr, sys.argv[1])
server = smtplib.SMTP(os.environ["INSTANCE_IP"], 587) server = smtplib.SMTP(os.environ["INSTANCE_IP"], 587)
server.set_debuglevel(1) server.set_debuglevel(1)
server.starttls() server.starttls()
server.login("testuser@testdomain.com", "testpw") server.login(fromaddr, "testpw")
server.sendmail(fromaddr, [sys.argv[1]], msg) server.sendmail(fromaddr, [sys.argv[1]], msg)
server.quit() server.quit()