Settting up Dovecot IMAP server and TLS encryption

#!/bin/bash

# Setting up Dovecot IMAP server

domain_name=tuxmail.io

user1_email_address=user1

# Open ports

ufw allow 80,443,587,465,143,993/tcp

# POP3

ufw allow 110,995/tcp

# Install certbot for ssl certificate

apt update
apt dist-upgrade

DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata

apt install -y certbot python3-certbot-apache

# Create Apache virtual host

cat << EOF >> "/etc/apache2/sites-available/mail.$domain_name.conf"

ServerName mail.$domain_name

DocumentRoot /var/www/html/

EOF

# Enable the virtual host

a2ensite "mail.$domain_name.conf"

# Disable the default virtual host

a2dissite 000-default

# Reload apache2

systemctl reload apache2

# Run the following command to obtain a Let’s Encrypt TLS certificate

certbot certonly -a apache --agree-tos --no-eff-email --staple-ocsp --email "$user1_email_address@$domain_name" -d "mail.$domain_name"

# Enable submission service of Postfix so that an email client can submit emails to Postfix SMTP server

# Make a backup of the postfix configuration if it doesn't already exist

if ! [ -f "/etc/postfix/master1.cf-backup" ]; then cp /etc/postfix/master.cf /etc/postfix/master.cf-backup; fi

# Delete submission section

sed /'#submission'/,/milter_macro_daemon_name=ORIGINATING/d /etc/postfix/master.cf > /tmp/master1.cf

# Enable the submission daemon of Postfix by re-inserting unccomented

sed '/# Choose one: enable smtps/i\
submission inet n - y - - smtpd\
-o syslog_name=postfix/submission\
-o smtpd_tls_security_level=encrypt\
-o smtpd_tls_wrappermode=no\
-o smtpd_sasl_auth_enable=yes\
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject\
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject\
-o smtpd_sasl_type=dovecot\
-o smtpd_sasl_path=private/auth' /tmp/master1.cf > /etc/postfix/master2.cf

# Move and delete unnessary temporary files

rm /etc/postfix/master.cf
mv /etc/postfix/master2.cf /etc/postfix/master.cf
rm /tmp/master1.cf

# Delete smtps section

sed /'#smtps'/,/milter_macro_daemon_name=ORIGINATING/d /etc/postfix/master.cf > /tmp/master1.cf

# Re-insert smtps section uncommented for outlook users

sed '/#628/i\
smtps inet n - y - - smtpd\
-o syslog_name=postfix/smtps\
-o smtpd_tls_wrappermode=yes\
-o smtpd_sasl_auth_enable=yes\
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject\
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject\
-o smtpd_sasl_type=dovecot\
-o smtpd_sasl_path=private/auth' /tmp/master1.cf > /etc/postfix/master2.cf

# Move and delete unnessary temporary files

rm /etc/postfix/master.cf
mv /etc/postfix/master2.cf /etc/postfix/master.cf
rm /tmp/master1.cf

# Make a backup of the main.cf configuration if it doesn't already exist

if ! [ -f "/etc/postfix/main.cf-backup" ]; then cp /etc/postfix/main.cf /etc/postfix/main.cf-backup; fi

# Delete the TLS parameters section

cp /etc/postfix/main.cf-backup /etc/postfix/main.cf
sed /'# TLS parameters'/,/smtp_scache/d /etc/postfix/main.cf > /tmp/main1.cf

# Re-insert TLS parameters section with the following options

sed '/smtpd_relay_restrictions/i\
#Enable TLS Encryption when Postfix receives incoming emails\
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.domain_name/fullchain.pem\
smtpd_tls_key_file=/etc/letsencrypt/live/mail.domain_name/privkey.pem\
smtpd_tls_security_level=may \
smtpd_tls_loglevel = 1\
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache\
\
#Enable TLS Encryption when Postfix sends outgoing emails\
smtp_tls_security_level = may\
smtp_tls_loglevel = 1\
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache\
\
#Enforce TLSv1.3 or TLSv1.2\
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1\
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1\
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1\
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1' /tmp/main1.cf > /etc/postfix/main.cf

rm /tmp/main1.cf

# Replace domain_name with domain name

sed -i "s/domain_name/$(echo "$domain_name")/g" /etc/postfix/main.cf

systemctl restart postfix

# Install Dovecot core package and the IMAP/pop3 daemon packages

apt install -y dovecot-core dovecot-imapd dovecot-pop3d

# Enable installed protocols

sed -i "s/Enable installed protocols/Enable installed protocols\nprotocols = imap pop3/g" /etc/dovecot/dovecot.conf

# Have Dovecot use the Maildir format

sed -i 's/mail_location = mbox:~\/mail:INBOX=\/var\/mail\/%u/mail_location = maildir:~\/Maildir/g' /etc/dovecot/conf.d/10-mail.conf

# Add Dovecot to the mail group

adduser dovecot mail

# Configure Postfix to pass incoming emails to Dovecot, via the LMTP protocol, which is a simplified version of SMTP, so incoming emails will saved in Maildir format by Dovecot

# Install the Dovecot LMTP Server

apt install -y dovecot-lmtpd libsasl2-modules

# Add lmtp to the supported protocols

sed -i 's/protocols = imap pop3/protocols = imap pop3 lmtp/g' /etc/dovecot/dovecot.conf

# Change the lmtp service definition to the following

sed -i 's/unix_listener lmtp {/unix_listener \/var\/spool\/postfix\/private\/dovecot-lmtp {\n mode = 0600\n user = postfix\n group = postfix\n/g' /etc/dovecot/conf.d/10-master.conf

# Tell Postfix to deliver incoming emails to local message store via the Dovecot LMTP server and disable SMTPUTF8 in Postfix, because Dovecot-LMTP doesn’t support this email extension.

cat << EOF >> "/etc/postfix/main.cf"

mailbox_transport = lmtp:unix:private/dovecot-lmtp
smtputf8_enable = no
EOF

# Disable plaintext authentication

sed -i 's/#disable_plaintext_auth = yes/disable_plaintext_auth = yes/g' /etc/dovecot/conf.d/10-auth.conf

# Change auth_username_format to = %n to drop the domain part, then Dovecot should be able to find the mailbox user

sed -i 's/#auth_username_format = %Lu/auth_username_format = %n/g' /etc/dovecot/conf.d/10-auth.conf

# Add support for older clients

sed -i 's/auth_mechanisms = plain/auth_mechanisms = plain login/g' /etc/dovecot/conf.d/10-auth.conf

# Require SSL

sed -i 's/ssl = yes/ssl = required/g' /etc/dovecot/conf.d/10-ssl.conf

# Specify the location of your Let’s Encrypt TLS certificate and private key.

sed -i "s/ssl_cert = <\/etc\/dovecot\/private\/dovecot.pem/ssl_cert = <\/etc\/letsencrypt\/live\/mail.$(echo "$domain_name")\/fullchain.pem/g" /etc/dovecot/conf.d/10-ssl.conf

sed -i "s/ssl_key = <\/etc\/dovecot\/private\/dovecot.key/ssl_key = <\/etc\/letsencrypt\/live\/mail.$(echo "$domain_name")\/privkey.pem/g" /etc/dovecot/conf.d/10-ssl.conf

# Prefer the server’s order of ciphers over client’s.

sed -i "s/#ssl_prefer_server_ciphers = no/ssl_prefer_server_ciphers = yes/g" /etc/dovecot/conf.d/10-ssl.conf

# Disable insecure SSLv3, TLSv1 and TLSv1.1 by adding the following line

sed -i "s/#ssl_min_protocol = TLSv1.2/ssl_min_protocol = TLSv1.2/g" /etc/dovecot/conf.d/10-ssl.conf

# Trisquel 11 ships with OpenSSL 3.0, which features a FIPS provider. However, it won’t work with Dovecot. We need to diable the FIPS provider

sed -i "s/providers = provider_sect/#providers = provider_sect/g" /etc/ssl/openssl.cnf

# This is so that Postfix can find the Dovecot authentication server

sed -i "s/unix_listener auth-userdb {/unix_listener \/var\/spool\/postfix\/private\/auth {\n mode = 0660\n user = postfix\n group = postfix/g" /etc/dovecot/conf.d/10-master.conf

# Have certain folders auto-created

# Trash

sed -i "s/mailbox Trash {/mailbox Trash {\n auto = create/g" /etc/dovecot/conf.d/15-mailboxes.conf

# Junk

sed -i "s/mailbox Junk {/mailbox Junk {\n auto = create/g" /etc/dovecot/conf.d/15-mailboxes.conf

# Drafts

sed -i "s/mailbox Drafts {/mailbox Drafts {\n auto = create/g" /etc/dovecot/conf.d/15-mailboxes.conf

# Sent

sed -i "s/mailbox Sent {/mailbox Sent {\n auto = create/g" /etc/dovecot/conf.d/15-mailboxes.conf

# Resstart Postfix and Dovecot

systemctl restart postfix dovecot

# Set time zone

timedatectl set-timezone America/New_York

# Install NTP

apt install -y ntp
systemctl restart ntp

# Add main domain name to the mydestination list

sed -i "s/mydestination = /mydestination = $domain_name, /g" /etc/postfix/main.cf

systemctl restart postfix

# Automatically renew ssl certificate

apt install -y cron
crontab -l | { cat; echo "@daily certbot renew --quiet && systemctl reload postfix dovecot apache2"; } | crontab -

# If dovecot ever crashes we should have it automatically restart

mkdir -p /etc/systemd/system/dovecot.service.d/

cat << EOF >> "/etc/systemd/system/dovecot.service.d/restart.conf"
[Service]
Restart=always
RestartSec=5s
EOF

systemctl daemon-reload