#!/bin/bash # Installing a mailserver including postfix postfixadmin and dovecot # # MTA = Mail Transport Agent (postfix) # MDA = Mail Delivery Agent (dovecot) # MUA = Mail User Agent (Mail program used by the user) toolName=mailserver mtaName=postfix mtaUser=postfix mtaDeps="$mtaName $mtaName-mysql" mtaConfLoc="/etc/$mtaName" mtaMysqlConfLoc="$mtaConfLoc/sql" mdaName=dovecot mdaConfLoc="/etc/$mdaName" mdaConfDir="$mdaConfLoc/conf.d" mdaDeps="dovecot-imapd dovecot-lmtpd dovecot-mysql dovecot-managesieved dovecot-sieve" # Get script working directory # (when called from a different directory) WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )" CONFIG=0 CONFIG_FILE_NAME="${toolName}.cfg" CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example" step_config() { if [ $(id -u) -ne 0 ] ; then endReturn -o 1 "No root" fi initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE" if [ $? -eq 0 ] ; then CONFIG=1 echo " Domain: $MAS_DOMAIN" elif [ $? -eq 1 ] ; then # Config $CONFIG_FILE_NAME created. Needs modification first exit 1 fi } step_1_info() { echo "Update apt repositories"; } step_1_alias() { ALIAS="install"; } step_1() { exe apt update } step_2_info() { echo "Install $mtaName"; } step_2() { local aptOpt= if [ $QUIET -ne 0 ];then aptOpt="-y" else read -p "In the following dialog chose \"Internet site\" and enter $MAS_DOMAIN as your domain. Enter to continue..." fi exe apt install $mtaDeps $aptOpt } step_3_info() { echo "Enable $mtaName"; } step_3() { exe systemctl enable $mtaName echo -e " [I] Printing $mtaName status\n" exe service $mtaName status echo -e "\n [I] Installed postfix version: $(postconf mail_version)" } step_4_info() { echo "$mtaName basic domain configuration"; } step_4() { exe postconf -e "myhostname = mail.$MAS_DOMAIN" exe postconf -e "mydomain = $MAS_DOMAIN" exe postconf -e "myorigin = $MAS_DOMAIN" exe postconf -e "mydestination = $MAS_DOMAIN, \$myhostname, mail.\$mydomain, localhost.\$mydomain, localhost" } step_5_info() { echo "$mtaName enable submission service"; } step_5() { echo -e " [I] Copy following lines...\n" exe cat "$mtaConfSubmission" exe read -rep $'\nPress Enter to open the '$mtaConfLoc'/master.cf' exe vi $mtaConfLoc/master.cf exe echo exe cat "$mtaConfSmtps" exe read -rep $'\nPress Enter to open the '$mtaConfLoc'/master.cf' exe vi $mtaConfLoc/master.cf } mtaConfSubmission="$WDIR/$toolName/submissionService" mtaConfSmtps="$WDIR/$toolName/smtpsService" step_6_info() { echo "Configure TLS"; } step_6() { exe postconf "smtpd_tls_cert_file = /etc/letsencrypt/live/$MAS_DOMAIN/fullchain.pem" exe postconf "smtpd_tls_key_file = /etc/letsencrypt/live/$MAS_DOMAIN/privkey.pem" #Force TLSv1.3 or TLSv1.2 exe postconf "smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1" exe postconf "smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1" exe postconf "smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1" exe postconf "smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1" echo " [I] Restarting $mtaName" exe service $mtaName restart } step_7_info() { echo "Install $mdaName"; } step_7() { exe apt install $mdaDeps echo -e "\n [I] Installed version: $(dovecot --version)" } step_8_info() { echo "Configure $mdaName" if [ $CONTEXT_HELP -ne 0 ] ; then echo fi } step_8() { echo "# Configuring Mailbox Location" echo " [/etc/dovecot/conf.d/10-mail.conf]" echo " mail_location = maildir:~/Maildir" echo " mail_privileged_group = mail" echo echo " usermod -aG mail dovecot" echo echo "# Configuring Authentication Mechanism" echo " [/etc/dovecot/conf.d/10-auth.conf]" echo " disable_plaintext_auth = yes" echo " # Login with full mail address" echo " auth_username_format = %n" echo " # "login" to support older mail clients" echo " auth_mechanisms = plain login" echo echo "# Configure SSL/TLS Encryption" echo " [/etc/dovecot/conf.d/10-ssl.conf]" echo " ssl = required" echo " ssl_cert = "$mtaMysqlConfLoc/${mtaFile}.cf" done exe chown -R root:${mtaUser} "$mtaMysqlConfLoc" exe chmod 640 "${mtaMysqlConfLoc}"/* } step_22_info() { echo "Modify $mtaName configuration for virtual mailboxes"; } step_22() { exe postconf -e "virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf" exe postconf -e "virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf" exe postconf -e "virtual_alias_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf" exe postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp" # Apex domain removed, it is handled as virtual domain now exe postconf -e "mydestination = \$myhostname, localhost.\$mydomain, localhost" # Base location for the virtual maildirs exe postconf -e "virtual_mailbox_base = $MAS_VIRTUAL_FOLDER_BASE" exe postconf -e "virtual_minimum_uid = $MAS_VIRTUAL_USER_ID" exe postconf -e "virtual_uid_maps = static:$MAS_VIRTUAL_USER_ID" exe postconf -e "virtual_gid_maps = static:$MAS_VIRTUAL_USER_ID" } step_23_info() { echo "Create virtual user $MAS_VIRTUAL_USER and folder $MAS_VIRTUAL_FOLDER_BASE"; } step_23() { exe mkdir -p "$MAS_VIRTUAL_FOLDER_BASE" exe groupadd --gid $MAS_VIRTUAL_USER_ID $MAS_VIRTUAL_USER exe adduser --disabled-login --disabled-password --home "$MAS_VIRTUAL_FOLDER_BASE" --uid $MAS_VIRTUAL_USER_ID --gid $MAS_VIRTUAL_USER_ID $MAS_VIRTUAL_USER exe chown -R ${MAS_VIRTUAL_USER}: "$MAS_VIRTUAL_FOLDER_BASE" exe chmod -R 770 "$MAS_VIRTUAL_FOLDER_BASE" echo " [I] Restarting $mtaName" exe service $mtaName restart } step_24_info() { echo "$mdaName virtualisation configuration instructions"; } step_24() { echo "# Configuring Mailbox Location" echo " [/etc/dovecot/conf.d/10-mail.conf]" echo " mail_location = maildir:~/Maildir" echo " mail_home = ${MAS_VIRTUAL_FOLDER_BASE}/%d/%n" echo echo "# Configure authentication" echo " [/etc/dovecot/conf.d/10-auth.conf]" echo " # Username with domain" echo " auth_username_format = %u" echo " # Find and uncomment following line" echo " !include auth-sql.conf.ext" echo " # Comment following line to prevent local users from sending mail" echo " # without having registered an email address" echo " #!include auth-system.conf.ext" echo " # Debug login issues in /var/log/maillog by adding:" echo " auth_debug = yes" echo " auth_debug_passwords = yes" echo echo "# Adding mysql login information" echo " [/etc/dovecot/dovecot-sql.conf.ext]" echo " driver = mysql" echo " connect = host=$MAS_DBHOST dbname=$MAS_DBNAME user=$MAS_DBUSER password='${MAS_DBPASS}'" echo " default_pass_scheme = MD5" echo " password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'" echo " user_query = SELECT maildir, $MAS_VIRTUAL_USER_ID AS uid, $MAS_VIRTUAL_USER_ID AS gid FROM mailbox WHERE username = '%u' AND active='1'" echo " iterate_query = SELECT username AS user FROM mailbox" } step_25_info() { echo "Configure sieve for virtual users" if [ $CONTEXT_HELP -ne 0 ] ; then echo fi } step_25() { echo "# Sieve script configuration" echo " [$mdaConfDir/90-sieve.conf]" echo " sieve = file:/var/vmail/%d/%n/sieve;active=/var/vmail/%d/%n/.dovecot.sieve" echo " sieve_extensions = +notify +imapflags +vnd.dovecot.execute" echo " sieve_plugins = sieve_extprograms" echo " sieve_user_log = file:/var/vmail/%d/%n/sieve/sieve.log" echo echo "# Enable excution of external programs (e.g. to send xmpp messages on certain keywords)" echo " [$mdaConfDir/90-sieve-extprograms.conf]" echo " sieve_execute_bin_dir = /usr/lib/dovecot/sieve-extprograms" echo echo "# Enable sieve for lmtp" echo " [$mdaConfDir/20-lmtp.conf]" echo " postmaster_address = postmaster@$MAS_DOMAIN" echo " mail_plugins = $mail_plugins sieve" } step_50_info() { echo "Adding relay host for sending mails"; } step_50() { exe postconf -e "relayhost = $MAS_RELAYHOST" exe postconf -e "smtp_sasl_auth_enable = yes" exe postconf -e "smtp_sasl_password_maps = hash:$saslPassFile" addConf -s "$MAS_RELAYHOST $MAS_RELAYUSER:$MAS_RELAYPASS" "$saslPassFile" exe postmap "$saslPassFile" } saslPassFile="$mtaConfLoc/sasl_password" step_52_info() { echo "Grant access for specific (local) hostnames" echoinfo "Workaround when local clients connect to 25 with different ips (v6)" } step_52_alias() { ALIAS="client_access"; } step_52() { if [ ! -f "$mtaClientAccessLoc" ] ; then echo " [I] Generating $mtaClientAccessLoc" exep "echo \"# myhost.lan OK\" > \"$mtaClientAccessLoc\"" echo " [I] Don't forget to add the following" echo " [$mtaConfLoc/main.cf]" echo " smtpd_relay_restrictions =" echo " check_client_access hash:$mtaClientAccessLoc" fi echo " [I] Updating $mtaClientAccessLoc" exe postmap "$mtaClientAccessLoc" } mtaClientAccessLoc="$mtaConfLoc/client_access" step_54_info() { echo "Deny recipient access for listed mail addresses" } step_54_alias() { ALIAS="recipient_access"; } step_54() { if [ ! -f "$mtaRecipientAccessLoc" ] ; then echo " [I] Generating $mtaRecipientAccessLoc" exep "echo \"# unwanted@${MAS_DOMAIN} 550 No mailbox. Nothing to see here.\" > \"$mtaRecipientAccessLoc\"" echo " [I] Don't forget to add the following" echo " [$mtaConfLoc/main.cf]" echo " smtpd_recipient_restrictions =" echo " check_recipient_access hash:$mtaRecipientAccessLoc" fi echo " [I] Updating $mtaRecipientAccessLoc" exe postmap "$mtaRecipientAccessLoc" } mtaRecipientAccessLoc="$mtaConfLoc/recipient_access" step_100_info() { echo "Send testmail"; } step_100() { echo -e "Subject: TestPostfix\nIt goes on" | sendmail martin@winklerfamilie.de } step_102_info() { echo "Show mail queue"; } step_102_alias() { ALIAS="showqueue"; } step_102() { exe sendmail -bp } step_104_info() { echo "Delete mail queue [ID]" echoinfo "Delete all queued mails if [ID] is empty" } step_104_alias() { ALIAS="delqueue"; } step_104() { shift local msgId="ALL" if [ ! -z $1 ] ; then msgId="$1" fi exe postsuper -d "$msgId" } VERSION_SEQREV=11 . /usr/local/bin/sequencer.sh