diff --git a/README.md b/README.md index f3d78ae4..f8a48c3b 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,11 @@ Please check [how the container starts](https://github.com/tomav/docker-mailserv Value in **bold** is the default value. +##### DMS_DEBUG + + - **empty** (0) => Debug disabled + - 1 => Enables debug on startup + ##### ENABLE_POP3 - **empty** => POP3 service disabled diff --git a/target/start-mailserver.sh b/target/start-mailserver.sh index 45aef988..082326da 100644 --- a/target/start-mailserver.sh +++ b/target/start-mailserver.sh @@ -8,6 +8,7 @@ ########################################################################## declare -A DEFAULT_VARS DEFAULT_VARS["VIRUSMAILS_DELETE_DELAY"]="${VIRUSMAILS_DELETE_DELAY:="7"}" +DEFAULT_VARS["DMS_DEBUG"]="${DMS_DEBUG:="0"}" ########################################################################## # << DEFAULT VARS ########################################################################## @@ -34,7 +35,8 @@ DEFAULT_VARS["VIRUSMAILS_DELETE_DELAY"]="${VIRUSMAILS_DELETE_DELAY:="7"}" # Implement them in the section-group: {check,setup,fix,start} ########################################################################## function register_functions() { - notify 'taskgrp' 'Registering check,setup,fix,misc and start-daemons functions' + notify 'taskgrp' 'Initializing setup' + notify 'task' 'Registering check,setup,fix,misc and start-daemons functions' ################### >> check funcs @@ -75,7 +77,10 @@ function register_functions() { _register_setup_function "_setup_security_stack" _register_setup_function "_setup_postfix_aliases" _register_setup_function "_setup_postfix_vhost" - _register_setup_function "_setup_postfix_relay_amazon_ses" + + if [ ! -z "$AWS_SES_HOST" -a ! -z "$AWS_SES_USERPASS" ]; then + _register_setup_function "_setup_postfix_relay_amazon_ses" + fi ################### << setup funcs @@ -191,31 +196,37 @@ function _register_misc_function() { function notify () { c_red="\e[0;31m" c_green="\e[0;32m" + c_brown="\e[0;33m" c_blue="\e[0;34m" c_bold="\033[1m" c_reset="\e[0m" notification_type=$1 notification_msg=$2 + msg="" case "${notification_type}" in 'inf') - msg="${c_green} * ${c_reset}${notification_msg}" + if [[ ${DEFAULT_VARS["DMS_DEBUG"]} == 1 ]]; then + msg="${c_green} * ${c_reset}${notification_msg}" + fi ;; 'err') msg="${c_red} * ${c_reset}${notification_msg}" ;; 'warn') - msg="${c_blue} * ${c_reset}${notification_msg}" + msg="${c_brown} * Warning => ${notification_msg}" ;; 'task') - msg=" >>>> ${notification_msg}" + if [[ ${DEFAULT_VARS["DMS_DEBUG"]} == 1 ]]; then + msg="${notification_msg}" + fi ;; 'taskgrp') msg="${c_bold}${notification_msg}${c_reset}" ;; 'fatal') - msg="${c_bold} >>>> ${notification_msg} <<<<${c_reset}" + msg="${c_red}Error: ${notification_msg}${c_red}" ;; *) msg="" @@ -243,21 +254,21 @@ function defunc() { # Description: Place functions for initial check of container sanity ########################################################################## function check() { - notify 'taskgrp' 'Checking configuration sanity:' + notify 'taskgrp' 'Checking configuration' for _func in "${FUNCS_CHECK[@]}";do $_func - [ $? != 0 ] && defunc + # [ $? != 0 ] && defunc done } function _check_hostname() { notify "task" "Check that hostname/domainname is provided (no default docker hostname) [$FUNCNAME]" - if ( ! echo $(hostname) | grep -E '^(\S+[.]\S+)$' ); then + if ( ! echo $(hostname) | grep -E '^(\S+[.]\S+)$' > /dev/null ); then notify 'err' "Setting hostname/domainname is required" return 1 else - notify 'inf' "Hostname has been set" + notify 'inf' "Hostname has been set to $(hostname)" return 0 fi } @@ -277,11 +288,9 @@ function _check_environment_variables() { # Description: Place functions for functional configurations here ########################################################################## function setup() { - notify 'taskgrp' 'Setting up the Container:' - + notify 'taskgrp' 'Configuring mail server' for _func in "${FUNCS_SETUP[@]}";do $_func - [ $? != 0 ] && defunc done } @@ -290,15 +299,15 @@ function _setup_default_vars() { for var in ${!DEFAULT_VARS[@]}; do echo "export $var=${DEFAULT_VARS[$var]}" >> /root/.bashrc - [ $? != 0 ] && notify 'err' "Unable to set $var=${DEFAULT_VARS[$var]}" && return 1 - notify 'inf' "$var=${DEFAULT_VARS[$var]} set" + # [ $? != 0 ] && notify 'err' "Unable to set $var=${DEFAULT_VARS[$var]}" && return 1 + notify 'inf' "Set $var=${DEFAULT_VARS[$var]}" done } function _setup_mailname() { notify 'task' 'Setting up Mailname' - echo "Creating /etc/mailname" + notify 'inf' "Creating /etc/mailname" echo $(hostname -d) > /etc/mailname } @@ -327,9 +336,9 @@ function _setup_dovecot_local_user() { echo -n > /etc/postfix/vmailbox echo -n > /etc/dovecot/userdb if [ -f /tmp/docker-mailserver/postfix-accounts.cf -a "$ENABLE_LDAP" != 1 ]; then - echo "Checking file line endings" + notify 'inf' "Checking file line endings" sed -i 's/\r//g' /tmp/docker-mailserver/postfix-accounts.cf - echo "Regenerating postfix 'vmailbox' and 'virtual' for given users" + notify 'inf' "Regenerating postfix user list" echo "# WARNING: this file is auto-generated. Modify config/postfix-accounts.cf to edit user list." > /etc/postfix/vmailbox # Checking that /tmp/docker-mailserver/postfix-accounts.cf ends with a newline @@ -384,7 +393,7 @@ function _setup_ldap() { /etc/postfix/ldap-${i}.cf done - echo "Configuring dovecot LDAP authentification" + notify 'inf' "Configuring dovecot LDAP authentification" sed -i -e 's|^hosts.*|hosts = '${LDAP_SERVER_HOST:="mail.domain.com"}'|g' \ -e 's|^base.*|base = '${LDAP_SEARCH_BASE:="ou=people,dc=domain,dc=com"}'|g' \ -e 's|^dn\s*=.*|dn = '${LDAP_BIND_DN:="cn=admin,dc=domain,dc=com"}'|g' \ @@ -394,18 +403,18 @@ function _setup_ldap() { # Add domainname to vhost. echo $(hostname -d) >> /tmp/vhost.tmp - echo "Enabling dovecot LDAP authentification" + notify 'inf' "Enabling dovecot LDAP authentification" sed -i -e '/\!include auth-ldap\.conf\.ext/s/^#//' /etc/dovecot/conf.d/10-auth.conf sed -i -e '/\!include auth-passwdfile\.inc/s/^/#/' /etc/dovecot/conf.d/10-auth.conf - echo "Configuring LDAP" + notify 'inf' "Configuring LDAP" [ -f /etc/postfix/ldap-users.cf ] && \ postconf -e "virtual_mailbox_maps = ldap:/etc/postfix/ldap-users.cf" || \ - echo '==> Warning: /etc/postfix/ldap-user.cf not found' + notify 'inf' "==> Warning: /etc/postfix/ldap-user.cf not found" [ -f /etc/postfix/ldap-aliases.cf -a -f /etc/postfix/ldap-groups.cf ] && \ postconf -e "virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf, ldap:/etc/postfix/ldap-groups.cf" || \ - echo '==> Warning: /etc/postfix/ldap-aliases.cf or /etc/postfix/ldap-groups.cf not found' + notify 'inf' "==> Warning: /etc/postfix/ldap-aliases.cf or /etc/postfix/ldap-groups.cf not found" [ ! -f /etc/postfix/sasl/smtpd.conf ] && cat > /etc/postfix/sasl/smtpd.conf << EOF pwcheck_method: saslauthd @@ -415,9 +424,9 @@ return 0 } function _setup_saslauthd() { - notify 'task' 'Setting up Saslauthd' + notify 'task' "Setting up Saslauthd" - echo "Configuring Cyrus SASL" + notify 'inf' "Configuring Cyrus SASL" # checking env vars and setting defaults [ -z $SASLAUTHD_MECHANISMS ] && SASLAUTHD_MECHANISMS=pam [ -z $SASLAUTHD_LDAP_SEARCH_BASE ] && SASLAUTHD_MECHANISMS=pam @@ -426,7 +435,7 @@ function _setup_saslauthd() { ([ -z $SASLAUTHD_LDAP_SSL ] || [ $SASLAUTHD_LDAP_SSL == 0 ]) && SASLAUTHD_LDAP_PROTO='ldap://' || SASLAUTHD_LDAP_PROTO='ldaps://' if [ ! -f /etc/saslauthd.conf ]; then - echo "Creating /etc/saslauthd.conf" + notify 'inf' "Creating /etc/saslauthd.conf" cat > /etc/saslauthd.conf << EOF ldap_servers: ${SASLAUTHD_LDAP_PROTO}${SASLAUTHD_LDAP_SERVER} @@ -477,11 +486,11 @@ function _setup_postfix_aliases() { test "$uname" != "$domain" && echo ${domain} >> /tmp/vhost.tmp done < /tmp/docker-mailserver/postfix-virtual.cf else - echo "==> Warning: 'config/postfix-virtual.cf' is not provided. No mail alias/forward created." + notify 'inf' "Warning 'config/postfix-virtual.cf' is not provided. No mail alias/forward created." fi if [ -f /tmp/docker-mailserver/postfix-regexp.cf ]; then # Copying regexp alias file - echo "Adding regexp alias file postfix-regexp.cf" + notify 'inf' "Adding regexp alias file postfix-regexp.cf" cp -f /tmp/docker-mailserver/postfix-regexp.cf /etc/postfix/regexp sed -i -e '/^virtual_alias_maps/{ s/ regexp:.*// @@ -493,18 +502,18 @@ function _setup_postfix_aliases() { function _setup_dkim() { notify 'task' 'Setting up DKIM' + mkdir -p /etc/opendkim && touch /etc/opendkim/SigningTable + # Check if keys are already available if [ -e "/tmp/docker-mailserver/opendkim/KeyTable" ]; then - mkdir -p /etc/opendkim cp -a /tmp/docker-mailserver/opendkim/* /etc/opendkim/ - echo "DKIM keys added for: `ls -C /etc/opendkim/keys/`" - echo "Changing permissions on /etc/opendkim" - # chown entire directory + notify 'inf' "DKIM keys added for: `ls -C /etc/opendkim/keys/`" + notify 'inf' "Changing permissions on /etc/opendkim" chown -R opendkim:opendkim /etc/opendkim/ # And make sure permissions are right chmod -R 0700 /etc/opendkim/keys/ else - echo "No DKIM key provided. Check the documentation to find how to get your keys." + notify 'warn' "No DKIM key provided. Check the documentation to find how to get your keys." fi } @@ -524,7 +533,7 @@ function _setup_ssl() { KEY="key" fi if [ -n "$KEY" ]; then - echo "Adding $(hostname) SSL certificate" + notify 'inf' "Adding $(hostname) SSL certificate" # Postfix configuration sed -i -r 's~smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem~smtpd_tls_cert_file=/etc/letsencrypt/live/'$(hostname)'/fullchain.pem~g' /etc/postfix/main.cf @@ -534,14 +543,14 @@ function _setup_ssl() { sed -i -e 's~ssl_cert = Warning: 'SASL_PASSWD' is not provided. /etc/postfix/sasl_passwd not created." + notify 'inf' "Warning: 'SASL_PASSWD' is not provided. /etc/postfix/sasl_passwd not created." fi } function _setup_postfix_relay_amazon_ses() { notify 'task' 'Setting up Postfix Relay Amazon SES' - - if [ ! -z "$AWS_SES_HOST" -a ! -z "$AWS_SES_USERPASS" ]; then - if [ -z "$AWS_SES_PORT" ];then - AWS_SES_PORT=25 - fi - echo "Setting up outgoing email via AWS SES host $AWS_SES_HOST:$AWS_SES_PORT" - echo "[$AWS_SES_HOST]:$AWS_SES_PORT $AWS_SES_USERPASS" >> /etc/postfix/sasl_passwd - postconf -e \ - "relayhost = [$AWS_SES_HOST]:$AWS_SES_PORT" \ - "smtp_sasl_auth_enable = yes" \ - "smtp_sasl_security_options = noanonymous" \ - "smtp_sasl_password_maps = texthash:/etc/postfix/sasl_passwd" \ - "smtp_use_tls = yes" \ - "smtp_tls_security_level = encrypt" \ - "smtp_tls_note_starttls_offer = yes" \ - "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt" + if [ -z "$AWS_SES_PORT" ];then + AWS_SES_PORT=25 fi + notify 'inf' "Setting up outgoing email via AWS SES host $AWS_SES_HOST:$AWS_SES_PORT" + echo "[$AWS_SES_HOST]:$AWS_SES_PORT $AWS_SES_USERPASS" >> /etc/postfix/sasl_passwd + postconf -e \ + "relayhost = [$AWS_SES_HOST]:$AWS_SES_PORT" \ + "smtp_sasl_auth_enable = yes" \ + "smtp_sasl_security_options = noanonymous" \ + "smtp_sasl_password_maps = texthash:/etc/postfix/sasl_passwd" \ + "smtp_use_tls = yes" \ + "smtp_tls_security_level = encrypt" \ + "smtp_tls_note_starttls_offer = yes" \ + "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt" } - function _setup_security_stack() { - notify 'task' 'Setting up Security Stack' + notify 'task' "Setting up Security Stack" - echo "Configuring Spamassassin" + notify 'inf' "Configuring Spamassassin" SA_TAG=${SA_TAG:="2.0"} && sed -i -r 's/^\$sa_tag_level_deflt (.*);/\$sa_tag_level_deflt = '$SA_TAG';/g' /etc/amavis/conf.d/20-debian_defaults SA_TAG2=${SA_TAG2:="6.31"} && sed -i -r 's/^\$sa_tag2_level_deflt (.*);/\$sa_tag2_level_deflt = '$SA_TAG2';/g' /etc/amavis/conf.d/20-debian_defaults SA_KILL=${SA_KILL:="6.31"} && sed -i -r 's/^\$sa_kill_level_deflt (.*);/\$sa_kill_level_deflt = '$SA_KILL';/g' /etc/amavis/conf.d/20-debian_defaults test -e /tmp/docker-mailserver/spamassassin-rules.cf && cp /tmp/docker-mailserver/spamassassin-rules.cf /etc/spamassassin/ if [ "$ENABLE_FAIL2BAN" = 1 ]; then - echo "Fail2ban enabled" + notify 'inf' "Fail2ban enabled" test -e /tmp/docker-mailserver/fail2ban-jail.cf && cp /tmp/docker-mailserver/fail2ban-jail.cf /etc/fail2ban/jail.local else # Disable logrotate config for fail2ban if not enabled @@ -737,7 +738,7 @@ function _setup_elk_forwarder() { ELK_PORT=${ELK_PORT:="5044"} ELK_HOST=${ELK_HOST:="elk"} - echo "Enabling log forwarding to ELK ($ELK_HOST:$ELK_PORT)" + notify 'inf' "Enabling log forwarding to ELK ($ELK_HOST:$ELK_PORT)" cat /etc/filebeat/filebeat.yml.tmpl \ | sed "s@\$ELK_HOST@$ELK_HOST@g" \ | sed "s@\$ELK_PORT@$ELK_PORT@g" \ @@ -754,10 +755,10 @@ function _setup_elk_forwarder() { # Description: Place functions for temporary workarounds and fixes here ########################################################################## function fix() { - notify 'taskgrg' "Starting to fix:" + notify 'taskgrg' "Post-configuration checks..." for _func in "${FUNCS_FIX[@]}";do $_func - [ $? != 0 ] && defunc + # [ $? != 0 ] && defunc done } @@ -767,9 +768,9 @@ function _fix_var_mail_permissions() { # Fix permissions, but skip this if 3 levels deep the user id is already set if [ `find /var/mail -maxdepth 3 -a \( \! -user 5000 -o \! -group 5000 \) | grep -c .` != 0 ]; then chown -R 5000:5000 /var/mail - echo "/var/mail permissions fixed" + notify 'inf' "/var/mail permissions fixed" else - echo "Permissions in /var/mail look OK" + notify 'inf' "Permissions in /var/mail look OK" fi } ########################################################################## @@ -783,11 +784,11 @@ function _fix_var_mail_permissions() { # Description: Place functions that do not fit in the sections above here ########################################################################## function misc() { - notify 'taskgrp' 'Starting Misc:' + notify 'taskgrp' 'Starting Misc' for _func in "${FUNCS_MISC[@]}";do $_func - [ $? != 0 ] && defunc + # [ $? != 0 ] && defunc done } @@ -796,19 +797,19 @@ function _misc_save_states() { # directory statedir=/var/mail-state if [ "$ONE_DIR" = 1 -a -d $statedir ]; then - echo "Consolidating all state onto $statedir" + notify 'inf' "Consolidating all state onto $statedir" for d in /var/spool/postfix /var/lib/postfix /var/lib/amavis /var/lib/clamav /var/lib/spamassasin /var/lib/fail2ban; do dest=$statedir/`echo $d | sed -e 's/.var.//; s/\//-/g'` if [ -d $dest ]; then - echo " Destination $dest exists, linking $d to it" + notify 'inf' " Destination $dest exists, linking $d to it" rm -rf $d ln -s $dest $d elif [ -d $d ]; then - echo " Moving contents of $d to $dest:" `ls $d` + notify 'inf' " Moving contents of $d to $dest:" `ls $d` mv $d $dest ln -s $dest $d else - echo " Linking $d to $dest" + notify 'inf' " Linking $d to $dest" mkdir -p $dest ln -s $dest $d fi @@ -821,11 +822,11 @@ function _misc_save_states() { # >> Start Daemons ########################################################################## function start_daemons() { - notify 'taskgrp' 'Starting Daemons' + notify 'taskgrp' 'Starting mail server' for _func in "${DAEMONS_START[@]}";do $_func - [ $? != 0 ] && defunc + # [ $? != 0 ] && defunc done } @@ -854,7 +855,10 @@ function _start_daemons_fail2ban() { function _start_daemons_opendkim() { notify 'task' 'Starting opendkim' - /etc/init.d/opendkim start + if [ -e "/tmp/docker-mailserver/opendkim/KeyTable" ]; then + /etc/init.d/opendkim start + [ $? != 0 ] && defunc + fi } function _start_daemons_opendmarc() { @@ -873,13 +877,13 @@ function _start_daemons_dovecot() { /usr/sbin/dovecot -c /etc/dovecot/dovecot.conf if [ "$ENABLE_POP3" = 1 ]; then - echo "Starting POP3 services" + notify 'inf' "Starting POP3 services" mv /etc/dovecot/protocols.d/pop3d.protocol.disab /etc/dovecot/protocols.d/pop3d.protocol /usr/sbin/dovecot reload fi if [ -f /tmp/docker-mailserver/dovecot.cf ]; then - echo 'Adding file "dovecot.cf" to the Dovecot configuration' + notify 'inf' "Adding file 'dovecot.cf' to the Dovecot configuration" cp /tmp/docker-mailserver/dovecot.cf /etc/dovecot/local.conf /usr/sbin/dovecot reload fi @@ -938,6 +942,13 @@ function _start_daemons_amavis() { # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # >> +notify 'taskgrp' "" +notify 'taskgrp' "#" +notify 'taskgrp' "#" +notify 'taskgrp' "# docker-mailserver" +notify 'taskgrp' "#" +notify 'taskgrp' "#" +notify 'taskgrp' "" register_functions @@ -947,7 +958,14 @@ fix misc start_daemons -tail -f /var/log/mail/mail.log +notify 'taskgrp' "" +notify 'taskgrp' "#" +notify 'taskgrp' "# $(hostname) is up and running" +notify 'taskgrp' "#" +notify 'taskgrp' "" + + +tail -fn 0 /var/log/mail/mail.log # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!