Commit e713af5f authored by Joshua Tauberer's avatar Joshua Tauberer

refactor the mail setup scripts

As the scripts keep growing, it's time to split them up to
keep them understandable.

This splits mail.sh into mail-postfix.sh, mail-dovecot.sh,
and mail-users.sh, which has all of the user database-related
configurations shared by Dovecot and Postfix. Also from
spamassassin.sh the core sieve configuration is moved into
mail-dovecot.sh and the virtual transport setting is moved
into mail-postfix.sh.

Also revising one of the sed scripts in mail-dovecot to
not insert a new additional # at the start of a line each
time the script is run.
parent 6f51b496
#!/bin/bash
#
# Dovecot (IMAP and LDA)
#
# Dovecot is *both* the IMAP server (the protocol that email applications
# use to query a mailbox) as well as the local delivery agent (LDA),
# meaning it is responsible for writing emails to mailbox storage on disk.
# You could imagine why these things would be bundled together.
#
# As part of local mail delivery, Dovecot executes actions on incoming
# mail as defined in a "sieve" script.
#
# Dovecot's LDA role comes after spam filtering. Postfix hands mail off
# to Spamassassin which in turn hands it off to Dovecot. This all happens
# using the LMTP protocol.
source setup/functions.sh # load our functions
source /etc/mailinabox.conf # load global vars
# Install packages.
apt_install \
dovecot-core dovecot-imapd dovecot-lmtpd dovecot-sqlite sqlite3 dovecot-sieve
# The dovecot-imapd dovecot-lmtpd packages automatically enable IMAP and LMTP protocols.
# Set the location where we'll store user mailboxes.
tools/editconf.py /etc/dovecot/conf.d/10-mail.conf \
mail_location=maildir:$STORAGE_ROOT/mail/mailboxes/%d/%n \
mail_privileged_group=mail \
first_valid_uid=0
# IMAP
# Require that passwords are sent over SSL only, and allow the usual IMAP authentication mechanisms.
# The LOGIN mechanism is supposedly for Microsoft products like Outlook to do SMTP login (I guess
# since we're using Dovecot to handle SMTP authentication?).
tools/editconf.py /etc/dovecot/conf.d/10-auth.conf \
disable_plaintext_auth=yes \
"auth_mechanisms=plain login"
# Enable SSL, specify the location of the SSL certificate and private key files,
# and allow only good ciphers per http://baldric.net/2013/12/07/tls-ciphers-in-postfix-and-dovecot/.
tools/editconf.py /etc/dovecot/conf.d/10-ssl.conf \
ssl=required \
"ssl_cert=<$STORAGE_ROOT/ssl/ssl_certificate.pem" \
"ssl_key=<$STORAGE_ROOT/ssl/ssl_private_key.pem" \
"ssl_cipher_list=TLSv1+HIGH !SSLv2 !RC4 !aNULL !eNULL !3DES @STRENGTH"
# Disable in-the-clear IMAP and POP because we're paranoid (we haven't even
# enabled POP).
sed -i "s/#port = 143/port = 0/" /etc/dovecot/conf.d/10-master.conf
sed -i "s/#port = 110/port = 0/" /etc/dovecot/conf.d/10-master.conf
# LDA (LMTP)
# Enable Dovecot's LDA service with the LMTP protocol. It will listen
# in port 10026, and Spamassassin will be configured to pass mail there.
#
# The disabled unix socket listener is normally how Postfix and Dovecot
# would communicate (see the Postfix setup script for the corresponding
# setting also commented out).
#
# Also increase the number of allowed IMAP connections per mailbox because
# we all have so many devices lately.
cat > /etc/dovecot/conf.d/99-local.conf << EOF;
service lmtp {
#unix_listener /var/spool/postfix/private/dovecot-lmtp {
# user = postfix
# group = postfix
#}
inet_listener lmtp {
address = 127.0.0.1
port = 10026
}
}
protocol imap {
mail_max_userip_connections = 20
}
EOF
# Setting a postmaster_address seems to be required or LMTP won't start.
tools/editconf.py /etc/dovecot/conf.d/15-lda.conf \
postmaster_address=postmaster@$PRIMARY_HOSTNAME
# SIEVE
# Enable the Dovecot sieve plugin which let's us set a script that automatically moves
# spam into the user's Spam mail filter. (Note: Be careful if we want to use multiple
# plugins later.)
#
# The actual sieve script is copied into user mailboxes at the time the user account
# is created. Our script moves spam into the user's Spam folder.
sudo sed -i "s/#mail_plugins = .*/mail_plugins = \$mail_plugins sieve/" /etc/dovecot/conf.d/20-lmtp.conf
# PERMISSIONS
# Make the place for mailboxes.
mkdir -p $STORAGE_ROOT/mail
# Ensure configuration files are owned by dovecot and not world readable.
chown -R mail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot
# Ensure mailbox files have a directory that exists and are owned by the mail user.
mkdir -p $STORAGE_ROOT/mail/mailboxes
chown -R mail.mail $STORAGE_ROOT/mail/mailboxes
# Allow the IMAP port in the firewall.
ufw_allow imaps
# Restart services.
service dovecot restart
This diff is collapsed.
#!/bin/bash
#
# User Authentication and Destination Validation
#
# This script configures user authentication for Dovecot
# and Postfix (which relies on Dovecot) and destination
# validation by quering an Sqlite3 database of mail users.
source setup/functions.sh # load our functions
source /etc/mailinabox.conf # load global vars
# The database of mail users (i.e. authenticated users, who have mailboxes)
# and aliases (forwarders).
db_path=$STORAGE_ROOT/mail/users.sqlite
# Create an empty database if it doesn't yet exist.
if [ ! -f $db_path ]; then
echo Creating new user database: $db_path;
echo "CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT NOT NULL UNIQUE, password TEXT NOT NULL, extra);" | sqlite3 $db_path;
echo "CREATE TABLE aliases (id INTEGER PRIMARY KEY AUTOINCREMENT, source TEXT NOT NULL UNIQUE, destination TEXT NOT NULL);" | sqlite3 $db_path;
fi
# User Authentication
#####################
# Have Dovecot query our database, and not system users, for authentication.
sed -i "s/#*\(\!include auth-system.conf.ext\)/#\1/" /etc/dovecot/conf.d/10-auth.conf
sed -i "s/#\(\!include auth-sql.conf.ext\)/\1/" /etc/dovecot/conf.d/10-auth.conf
# Specify how the database is to be queried for user authentication (passdb)
# and where user mailboxes are stored (userdb).
cat > /etc/dovecot/conf.d/auth-sql.conf.ext << EOF;
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=mail gid=mail home=$STORAGE_ROOT/mail/mailboxes/%d/%n
}
EOF
# Configure the SQL to query for a user's password.
cat > /etc/dovecot/dovecot-sql.conf.ext << EOF;
driver = sqlite
connect = $db_path
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM users WHERE email='%u';
EOF
chmod 0600 /etc/dovecot/dovecot-sql.conf.ext # per Dovecot instructions
# Have Dovecot provide an authorization service that Postfix can access & use.
# Drew Crawford sets the auth-worker process to run as the mail user, but we don't care if it runs as root.
cat > /etc/dovecot/conf.d/99-local-auth.conf << EOF;
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
}
EOF
# And have Postfix use that service.
tools/editconf.py /etc/postfix/main.cf \
smtpd_sasl_type=dovecot \
smtpd_sasl_path=private/auth \
smtpd_sasl_auth_enable=yes
# Destination Validation
########################
# Use a Sqlite3 database to check whether a destination email address exists,
# and to perform any email alias rewrites in Postfix.
tools/editconf.py /etc/postfix/main.cf \
virtual_mailbox_domains=sqlite:/etc/postfix/virtual-mailbox-domains.cf \
virtual_mailbox_maps=sqlite:/etc/postfix/virtual-mailbox-maps.cf \
virtual_alias_maps=sqlite:/etc/postfix/virtual-alias-maps.cf \
local_recipient_maps=\$virtual_mailbox_maps
# SQL statement to check if we handle mail for a domain, either for users or aliases.
cat > /etc/postfix/virtual-mailbox-domains.cf << EOF;
dbpath=$db_path
query = SELECT 1 FROM users WHERE email LIKE '%%@%s' UNION SELECT 1 FROM aliases WHERE source LIKE '%%@%s'
EOF
# SQL statement to check if we handle mail for a user.
cat > /etc/postfix/virtual-mailbox-maps.cf << EOF;
dbpath=$db_path
query = SELECT 1 FROM users WHERE email='%s'
EOF
# SQL statement to rewrite an email address if an alias is present.
cat > /etc/postfix/virtual-alias-maps.cf << EOF;
dbpath=$db_path
query = SELECT destination FROM aliases WHERE source='%s'
EOF
# Restart Services
##################
service postfix restart
service dovecot restart
......@@ -12,7 +12,7 @@
source setup/functions.sh # load our functions
# Install packages.
apt_install spampd razor pyzor dovecot-sieve dovecot-antispam
apt_install spampd razor pyzor dovecot-antispam
# Allow spamassassin to download new rules.
tools/editconf.py /etc/default/spamassassin \
......@@ -21,19 +21,11 @@ tools/editconf.py /etc/default/spamassassin \
# Configure pyzor.
pyzor discover
# Hook into postfix. Replace dovecot with spampd as the mail delivery agent.
tools/editconf.py /etc/postfix/main.cf virtual_transport=lmtp:[127.0.0.1]:10025
# Pass messages on to docevot on port 10026.
# This is actually the default setting but we don't want to lose track of it.
# We've already configured Dovecot to listen on this port.
tools/editconf.py /etc/default/spampd DESTPORT=10026
# Enable the Dovecot sieve plugin which let's us set a script that automatically moves
# spam into the user's Spam mail filter.
# (Note: Be careful if we want to use multiple plugins later.)
sudo sed -i "s/#mail_plugins = .*/mail_plugins = \$mail_plugins sieve/" /etc/dovecot/conf.d/20-lmtp.conf
# Enable the Dovecot antispam plugin to detect when a message moves between folders so we can
# pass it to sa-learn for training. (Be careful if we use multiple plugins later.)
sudo sed -i "s/#mail_plugins = .*/mail_plugins = \$mail_plugins antispam/" /etc/dovecot/conf.d/20-imap.conf
......
......@@ -182,7 +182,9 @@ EOF
. setup/system.sh
. setup/ssl.sh
. setup/dns.sh
. setup/mail.sh
. setup/mail-postfix.sh
. setup/mail-dovecot.sh
. setup/mail-users.sh
. setup/dkim.sh
. setup/spamassassin.sh
. setup/web.sh
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment