#!/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) readonly toolName=mailserver readonly mtaName=postfix readonly mtaUser=postfix readonly mtaDeps="$mtaName $mtaName-mysql" readonly mtaConfLoc="/etc/$mtaName" readonly mtaMysqlConfLoc="$mtaConfLoc/sql" readonly mdaName=dovecot readonly mdaConfLoc="/etc/$mdaName" readonly mdaConfDir="$mdaConfLoc/conf.d" readonly mdaDeps="dovecot-imapd dovecot-lmtpd dovecot-mysql dovecot-managesieved dovecot-sieve" sq_aptOpt= sq_config=0 seq_config() { root || endReturn -o 1 "No root" #initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE" if initSeqConfig "${seq_configName:?}" "${seq_configTemplate:?}" ; then sq_config=1 info " Domain: ${MAS_DOMAIN:-}" else dry || return 1 fi ## Apt cmdline option to suppress user interaction interactive || sq_aptOpt="-y" return 0 } step_1_info() { echo "Update apt repositories"; } step_1_alias() { echo "install"; } step_1() { exe apt update } step_2_info() { echo "Install $mtaName"; } step_2() { confirm -n -y "In the following dialog chose \"Internet site\" and enter $MAS_DOMAIN as your domain. Enter to continue..." exe apt install $mtaDeps ${sq_aptOpt:-} } step_3_info() { echo "Enable $mtaName"; } step_3() { exe systemctl enable $mtaName info "Printing $mtaName status" exe service $mtaName status info "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() { local mtaConfSubmission="${seq_origin:?}/$toolName/submissionService" local mtaConfSmtps="${seq_origin:?}/$toolName/smtpsService" info "Copy following lines..." exe cat "$mtaConfSubmission" confirm -n -y "Press Enter to open the $mtaConfLoc/master.cf" editor $mtaConfLoc/master.cf info exe cat "$mtaConfSmtps" confirm -n -y "Press Enter to open the $mtaConfLoc/master.cf" editor $mtaConfLoc/master.cf } 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" info "Restarting $mtaName" exe service $mtaName restart } step_7_info() { echo "Restrict client access" echoinfo "Mainly PTR record check" } step_7() { exe postconf -e "smtpd_client_restrictions = permit_mynetworks, reject_unknown_client_hostname" } step_8_info() { echo "Install $mdaName"; } step_8() { exe apt install $mdaDeps ${sq_aptOpt} info "Installed version: $(dovecot --version)" } step_9_info() { echo "Configure $mdaName" } step_9() { color green cat < "$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" info "Restarting $mtaName" exe service $mtaName restart } step_24_info() { echo "$mdaName virtualisation configuration instructions"; } step_24() { color green cat < "$mtaClientAccessLoc" info "Don't forget to add the following" info -a "[$mtaConfLoc/main.cf]" info -a " smtpd_relay_restrictions =" info -a " check_client_access hash:$mtaClientAccessLoc" fi info "Updating $mtaClientAccessLoc" exe postmap "$mtaClientAccessLoc" } mtaClientAccessLoc="$mtaConfLoc/client_access" step_54_info() { echo "Deny recipient access for listed mail addresses" } step_54_alias() { echo "recipient_access"; } step_54() { if [ ! -f "$mtaRecipientAccessLoc" ] ; then info "Generating $mtaRecipientAccessLoc" exep "echo \"# unwanted@${MAS_DOMAIN} 550 No mailbox. Nothing to see here.\" > \"$mtaRecipientAccessLoc\"" info "Don't forget to add the following" info -a "[$mtaConfLoc/main.cf]" info -a " smtpd_recipient_restrictions =" info -a " check_recipient_access hash:$mtaRecipientAccessLoc" fi info "Updating $mtaRecipientAccessLoc" exe postmap "$mtaRecipientAccessLoc" } mtaRecipientAccessLoc="$mtaConfLoc/recipient_access" step_56_info() { echo "Add sender dependant relay with authentication"; } step_56_alias() { echo "sender_relay"; } step_56() { if [ ! -f "$mtaSenderRelayLoc" ] ; then info "Generating $mtaSenderRelayLoc" exep "echo \"# user@extern.com smtp:[mail.extern.com]:587\" > \"$mtaSenderRelayLoc\"" exe postconf -e "smtp_sender_dependent_authentication = yes" exe postconf -e "sender_dependent_relayhost_maps = hash:$mtaSenderRelayLoc" exe postconf -e "smtp_sasl_security_options = noanonymous" exe postconf -e "smtp_sasl_mechanism_filter = plain" exe postconf -e "smtp_tls_security_level = encrypt" exe postconf -e "smtp_tls_mandatory_ciphers = high" info "Don't forget to add credentials for the new relay" info -a "[$saslPassFile]" info -a " user@extern.com username:passwort" info -a "postmap $saslPassFile" fi info "Updating $mtaSenderRelayLoc" exe postmap "$mtaSenderRelayLoc" exe postmap "$saslPassFile" } mtaSenderRelayLoc="$mtaConfLoc/sender_relay" step_100_info() { echo "Send testmail [-u SYSTEMUSER | -f FROM] [TO]" echoinfo "Send as current user to postmaster@\$MAS_DOMAIN by default" } step_100_alias() { echo "test"; } step_100() { shift local fromAdr local toAdr="postmaster@$MAS_DOMAIN" local asUser= for _ in "$@" ; do case "$1" in -f) shift fromAdr="-f ${1:-} " shift ;; -u) shift asUser="sudo -u ${1:-} " shift ;; *) break ;; esac done [ -n "${1:-}" ] && toAdr="$1" exe ${asUser}sh -c "echo \"Subject: Test from Postfix\nIt is \$(date)\n\nGreetings \$(whoami)\" | sendmail ${fromAdr}$toAdr" } step_102_info() { echo "Show mail queue"; } step_102_alias() { echo "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() { echo "delqueue"; } step_104() { shift local msgId="ALL" [ -n "${1:-}" ] && msgId="$1" exe postsuper -d "$msgId" } # shellcheck disable=SC2034 # Appears unused readonly sqr_minVersion=16 # shellcheck disable=SC1091 # Don't follow this source . /usr/local/bin/sequencer.sh