Restructure start-mailserver.sh #338

This commit is contained in:
alinmear 2016-12-01 15:45:40 +01:00
parent 9e862b8405
commit 1f31475e11
1 changed files with 877 additions and 454 deletions

View File

@ -1,27 +1,310 @@
#!/bin/bash #!/bin/bash
die () { ##########################################################################
echo "## Configuration error:" # >> DEFAULT VARS
echo >&2 "> $@" #
# add them here.
# Example: DEFAULT_VARS["KEY"]="VALUE"
##########################################################################
declare -A DEFAULT_VARS
DEFAULT_VARS["VIRUSMAILS_DELETE_DELAY"]="${VIRUSMAILS_DELETE_DELAY:="7"}"
##########################################################################
# << DEFAULT VARS
##########################################################################
##########################################################################
# >> REGISTER FUNCTIONS
#
# add your new functions/methods here.
#
# NOTE: position matters when registering a function in stacks. First in First out
# Execution Logic:
# > check functions
# > setup functions
# > fix functions
# > misc functions
# > start-daemons
#
# Example:
# if [ CONDITION IS MET ]; then
# _register_{setup,fix,check,start}_{functions,daemons} "$FUNCNAME"
# fi
#
# Implement them in the section-group: {check,setup,fix,start}
##########################################################################
function register_functions() {
notify 'taskgrp' 'Registering check,setup,fix,misc and start-daemons functions'
################### >> check funcs
_register_check_function "_check_environment_variables"
_register_check_function "_check_hostname"
################### << check funcs
################### >> setup funcs
_register_setup_function "_setup_default_vars"
if [ "$ENABLE_ELK_FORWARDER" = 1 ]; then
_register_setup_function "_setup_elk_forwarder"
fi
if [ "$SMTP_ONLY" != 1 ]; then
_register_setup_function "_setup_dovecot"
_register_setup_function "_setup_dovecot_local_user"
fi
if [ "$ENABLE_LDAP" = 1 ];then
_register_setup_function "_setup_ldap"
fi
if [ "$ENABLE_SASLAUTHD" = 1 ];then
_register_setup_function "_setup_saslauthd"
fi
_register_setup_function "_setup_dkim"
_register_setup_function "_setup_ssl"
_register_setup_function "_setup_docker_permit"
_register_setup_function "_setup_mailname"
_register_setup_function "_setup_postfix_override_configuration"
_register_setup_function "_setup_postfix_sasl_password"
_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"
################### << setup funcs
################### >> fix funcs
_register_fix_function "_fix_var_mail_permissions"
################### << fix funcs
################### >> misc funcs
_register_misc_function "_misc_save_states"
################### << misc funcs
################### >> daemon funcs
_register_start_daemon "_start_daemons_sys"
if [ "$ENABLE_ELK_FORWARDER" = 1 ]; then
_register_start_daemon "_start_daemons_filebeat"
fi
if [ "$SMTP_ONLY" != 1 ]; then
_register_start_daemon "_start_daemons_dovecot"
fi
# needs to be started before saslauthd
_register_start_daemon "_start_daemons_opendkim"
_register_start_daemon "_start_daemons_opendmarc"
_register_start_daemon "_start_daemons_postfix"
if [ "$ENABLE_SASLAUTHD" = 1 ];then
_register_start_daemon "_start_daemons_saslauthd"
fi
# care needs to run after postfix
if [ "$ENABLE_FAIL2BAN" = 1 ]; then
_register_start_daemon "_start_daemons_fail2ban"
fi
if [ "$ENABLE_FETCHMAIL" = 1 ]; then
_register_start_daemon "_start_daemons_fetchmail"
fi
if ! [ "$DISABLE_CLAMAV" = 1 ]; then
_register_start_daemon "_start_daemons_clamav"
fi
if ! [ "$DISABLE_AMAVIS" = 1 ]; then
_register_start_daemon "_start_daemons_amavis"
fi
################### << daemon funcs
}
##########################################################################
# << REGISTER FUNCTIONS
##########################################################################
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, unless you exactly know what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# >>
##########################################################################
# >> CONSTANTS
##########################################################################
declare -a FUNCS_SETUP
declare -a FUNCS_FIX
declare -a FUNCS_CHECK
declare -a FUNCS_MISC
declare -a DAEMONS_START
declare -A HELPERS_EXEC_STATE
##########################################################################
# << CONSTANTS
##########################################################################
##########################################################################
# >> protected register_functions
##########################################################################
function _register_start_daemon() {
DAEMONS_START+=($1)
notify 'inf' "$1() registered"
}
function _register_setup_function() {
FUNCS_SETUP+=($1)
notify 'inf' "$1() registered"
}
function _register_fix_function() {
FUNCS_FIX+=($1)
notify 'inf' "$1() registered"
}
function _register_check_function() {
FUNCS_CHECK+=($1)
notify 'inf' "$1() registered"
}
function _register_misc_function() {
FUNCS_MISC+=($1)
notify 'inf' "$1() registered"
}
##########################################################################
# << protected register_functions
##########################################################################
function notify () {
c_red="\e[0;31m"
c_green="\e[0;32m"
c_blue="\e[0;34m"
c_bold="\033[1m"
c_reset="\e[0m"
notification_type=$1
notification_msg=$2
case "${notification_type}" in
'inf')
msg="${c_green} * ${c_reset}${notification_msg}"
;;
'err')
msg="${c_red} * ${c_reset}${notification_msg}"
;;
'warn')
msg="${c_blue} * ${c_reset}${notification_msg}"
;;
'task')
msg=" >>>> ${notification_msg}"
;;
'taskgrp')
msg="${c_bold}${notification_msg}${c_reset}"
;;
'fatal')
msg="${c_bold} >>>> ${notification_msg} <<<<${c_reset}"
;;
*)
msg=""
;;
esac
[[ ! -z "${msg}" ]] && echo -e "${msg}"
}
function defunc() {
notify 'fatal' "Please fix the failures. Exiting ..."
exit 1 exit 1
} }
# # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Check that hostname/domainname is provided (no default docker hostname) # ! CARE --> DON'T CHANGE, except you know exactly what you are doing
# # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if ( ! echo $(hostname) | grep -E '^(\S+[.]\S+)$' ); then # <<
die "Setting hostname/domainname is required."
fi
#
# Default variables
#
echo "export VIRUSMAILS_DELETE_DELAY=${VIRUSMAILS_DELETE_DELAY:="7"}" >> /root/.bashrc
##########################################################################
# >> Check Stack
# #
# Configuring Dovecot # Description: Place functions for initial check of container sanity
##########################################################################
function check() {
notify 'taskgrp' 'Checking configuration sanity:'
for _func in "${FUNCS_CHECK[@]}";do
$_func
[ $? != 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
notify 'err' "Setting hostname/domainname is required"
return 1
else
notify 'inf' "Hostname has been set"
return 0
fi
}
function _check_environment_variables() {
notify "task" "Check that there are no conflicts with env variables [$FUNCNAME]"
return 0
}
##########################################################################
# << Check Stack
##########################################################################
##########################################################################
# >> Setup Stack
# #
if [ "$SMTP_ONLY" != 1 ]; then # Description: Place functions for functional configurations here
##########################################################################
function setup() {
notify 'taskgrp' 'Setting up the Container:'
for _func in "${FUNCS_SETUP[@]}";do
$_func
[ $? != 0 ] && defunc
done
}
function _setup_default_vars() {
notify 'task' "Setting up default variables [$FUNCNAME]"
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"
done
}
function _setup_mailname() {
notify 'task' 'Setting up Mailname'
echo "Creating /etc/mailname"
echo $(hostname -d) > /etc/mailname
}
function _setup_dovecot() {
notify 'task' 'Setting up Dovecot'
cp -a /usr/share/dovecot/protocols.d /etc/dovecot/ cp -a /usr/share/dovecot/protocols.d /etc/dovecot/
# Disable pop3 (it will be eventually enabled later in the script, if requested) # Disable pop3 (it will be eventually enabled later in the script, if requested)
mv /etc/dovecot/protocols.d/pop3d.protocol /etc/dovecot/protocols.d/pop3d.protocol.disab mv /etc/dovecot/protocols.d/pop3d.protocol /etc/dovecot/protocols.d/pop3d.protocol.disab
@ -30,14 +313,20 @@ if [ "$SMTP_ONLY" != 1 ]; then
sed -i -e 's/#port = 993/port = 993/g' /etc/dovecot/conf.d/10-master.conf sed -i -e 's/#port = 993/port = 993/g' /etc/dovecot/conf.d/10-master.conf
sed -i -e 's/#port = 995/port = 995/g' /etc/dovecot/conf.d/10-master.conf sed -i -e 's/#port = 995/port = 995/g' /etc/dovecot/conf.d/10-master.conf
sed -i -e 's/#ssl = yes/ssl = required/g' /etc/dovecot/conf.d/10-ssl.conf sed -i -e 's/#ssl = yes/ssl = required/g' /etc/dovecot/conf.d/10-ssl.conf
fi
# # Enable Managesieve service by setting the symlink
# Users # to the configuration file Dovecot will actually find
# if [ "$ENABLE_MANAGESIEVE" = 1 ]; then
echo -n > /etc/postfix/vmailbox echo "Sieve management enabled"
echo -n > /etc/dovecot/userdb mv /etc/dovecot/protocols.d/managesieved.protocol.disab /etc/dovecot/protocols.d/managesieved.protocol
if [ -f /tmp/docker-mailserver/postfix-accounts.cf -a "$ENABLE_LDAP" != 1 ]; then fi
}
function _setup_dovecot_local_user() {
notify 'task' 'Setting up 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" echo "Checking file line endings"
sed -i 's/\r//g' /tmp/docker-mailserver/postfix-accounts.cf sed -i 's/\r//g' /tmp/docker-mailserver/postfix-accounts.cf
echo "Regenerating postfix 'vmailbox' and 'virtual' for given users" echo "Regenerating postfix 'vmailbox' and 'virtual' for given users"
@ -80,14 +369,13 @@ if [ -f /tmp/docker-mailserver/postfix-accounts.cf -a "$ENABLE_LDAP" != 1 ]; the
test -e /tmp/docker-mailserver/${login}.dovecot.sieve && cp /tmp/docker-mailserver/${login}.dovecot.sieve /var/mail/${domain}/${user}/.dovecot.sieve test -e /tmp/docker-mailserver/${login}.dovecot.sieve && cp /tmp/docker-mailserver/${login}.dovecot.sieve /var/mail/${domain}/${user}/.dovecot.sieve
echo ${domain} >> /tmp/vhost.tmp echo ${domain} >> /tmp/vhost.tmp
done < /tmp/docker-mailserver/postfix-accounts.cf done < /tmp/docker-mailserver/postfix-accounts.cf
else else
echo "==> Warning: 'config/docker-mailserver/postfix-accounts.cf' is not provided. No mail account created." echo "==> Warning: 'config/docker-mailserver/postfix-accounts.cf' is not provided. No mail account created."
fi fi
}
# function _setup_ldap() {
# LDAP notify 'task' 'Setting up Ldap'
#
if [ "$ENABLE_LDAP" = 1 ]; then
for i in 'users' 'groups' 'aliases'; do for i in 'users' 'groups' 'aliases'; do
sed -i -e 's|^server_host.*|server_host = '${LDAP_SERVER_HOST:="mail.domain.com"}'|g' \ sed -i -e 's|^server_host.*|server_host = '${LDAP_SERVER_HOST:="mail.domain.com"}'|g' \
-e 's|^search_base.*|search_base = '${LDAP_SEARCH_BASE:="ou=people,dc=domain,dc=com"}'|g' \ -e 's|^search_base.*|search_base = '${LDAP_SEARCH_BASE:="ou=people,dc=domain,dc=com"}'|g' \
@ -123,12 +411,12 @@ if [ "$ENABLE_LDAP" = 1 ]; then
pwcheck_method: saslauthd pwcheck_method: saslauthd
mech_list: plain login mech_list: plain login
EOF EOF
fi return 0
}
function _setup_saslauthd() {
notify 'task' 'Setting up Saslauthd'
#
# SASLAUTHD
#
if [ "$ENABLE_SASLAUTHD" = 1 ]; then
echo "Configuring Cyrus SASL" echo "Configuring Cyrus SASL"
# checking env vars and setting defaults # checking env vars and setting defaults
[ -z $SASLAUTHD_MECHANISMS ] && SASLAUTHD_MECHANISMS=pam [ -z $SASLAUTHD_MECHANISMS ] && SASLAUTHD_MECHANISMS=pam
@ -154,23 +442,25 @@ log_level: 10
EOF EOF
fi fi
sed -i -e "s|^START=.*|START=yes|g" \ sed -i \
-e "s|^START=.*|START=yes|g" \
-e "s|^MECHANISMS=.*|MECHANISMS="\"$SASLAUTHD_MECHANISMS\""|g" \ -e "s|^MECHANISMS=.*|MECHANISMS="\"$SASLAUTHD_MECHANISMS\""|g" \
-e "s|^MECH_OPTIONS=.*|MECH_OPTIONS="\"$SASLAUTHD_MECH_OPTIONS\""|g" \ -e "s|^MECH_OPTIONS=.*|MECH_OPTIONS="\"$SASLAUTHD_MECH_OPTIONS\""|g" \
/etc/default/saslauthd /etc/default/saslauthd
sed -i -e "/smtpd_sasl_path =.*/d" \ sed -i \
-e "/smtpd_sasl_path =.*/d" \
-e "/smtpd_sasl_type =.*/d" \ -e "/smtpd_sasl_type =.*/d" \
-e "/dovecot_destination_recipient_limit =.*/d" \ -e "/dovecot_destination_recipient_limit =.*/d" \
/etc/postfix/main.cf /etc/postfix/main.cf
gpasswd -a postfix sasl gpasswd -a postfix sasl
fi }
# function _setup_postfix_aliases() {
# Aliases notify 'task' 'Setting up Postfix Aliases'
#
echo -n > /etc/postfix/virtual echo -n > /etc/postfix/virtual
echo -n > /etc/postfix/regexp echo -n > /etc/postfix/regexp
if [ -f /tmp/docker-mailserver/postfix-virtual.cf ]; then if [ -f /tmp/docker-mailserver/postfix-virtual.cf ]; then
# Copying virtual file # Copying virtual file
cp -f /tmp/docker-mailserver/postfix-virtual.cf /etc/postfix/virtual cp -f /tmp/docker-mailserver/postfix-virtual.cf /etc/postfix/virtual
while read from to while read from to
@ -181,10 +471,10 @@ if [ -f /tmp/docker-mailserver/postfix-virtual.cf ]; then
# if they are equal it means the line looks like: "user1 other@domain.tld" # if they are equal it means the line looks like: "user1 other@domain.tld"
test "$uname" != "$domain" && echo ${domain} >> /tmp/vhost.tmp test "$uname" != "$domain" && echo ${domain} >> /tmp/vhost.tmp
done < /tmp/docker-mailserver/postfix-virtual.cf done < /tmp/docker-mailserver/postfix-virtual.cf
else else
echo "==> Warning: 'config/postfix-virtual.cf' is not provided. No mail alias/forward created." echo "==> Warning: 'config/postfix-virtual.cf' is not provided. No mail alias/forward created."
fi fi
if [ -f /tmp/docker-mailserver/postfix-regexp.cf ]; then if [ -f /tmp/docker-mailserver/postfix-regexp.cf ]; then
# Copying regexp alias file # Copying regexp alias file
echo "Adding regexp alias file postfix-regexp.cf" echo "Adding regexp alias file postfix-regexp.cf"
cp -f /tmp/docker-mailserver/postfix-regexp.cf /etc/postfix/regexp cp -f /tmp/docker-mailserver/postfix-regexp.cf /etc/postfix/regexp
@ -192,11 +482,14 @@ if [ -f /tmp/docker-mailserver/postfix-regexp.cf ]; then
s/ regexp:.*// s/ regexp:.*//
s/$/ regexp:\/etc\/postfix\/regexp/ s/$/ regexp:\/etc\/postfix\/regexp/
}' /etc/postfix/main.cf }' /etc/postfix/main.cf
fi fi
}
# DKIM function _setup_dkim() {
# Check if keys are already available notify 'task' 'Setting up DKIM'
if [ -e "/tmp/docker-mailserver/opendkim/KeyTable" ]; then
# Check if keys are already available
if [ -e "/tmp/docker-mailserver/opendkim/KeyTable" ]; then
mkdir -p /etc/opendkim mkdir -p /etc/opendkim
cp -a /tmp/docker-mailserver/opendkim/* /etc/opendkim/ cp -a /tmp/docker-mailserver/opendkim/* /etc/opendkim/
echo "DKIM keys added for: `ls -C /etc/opendkim/keys/`" echo "DKIM keys added for: `ls -C /etc/opendkim/keys/`"
@ -205,12 +498,16 @@ if [ -e "/tmp/docker-mailserver/opendkim/KeyTable" ]; then
chown -R opendkim:opendkim /etc/opendkim/ chown -R opendkim:opendkim /etc/opendkim/
# And make sure permissions are right # And make sure permissions are right
chmod -R 0700 /etc/opendkim/keys/ chmod -R 0700 /etc/opendkim/keys/
else else
echo "No DKIM key provided. Check the documentation to find how to get your keys." echo "No DKIM key provided. Check the documentation to find how to get your keys."
fi fi
}
# SSL Configuration function _setup_ssl() {
case $SSL_TYPE in notify 'task' 'Setting up SSL'
# SSL Configuration
case $SSL_TYPE in
"letsencrypt" ) "letsencrypt" )
# letsencrypt folders and files mounted in /etc/letsencrypt # letsencrypt folders and files mounted in /etc/letsencrypt
if [ -e "/etc/letsencrypt/live/$(hostname)/cert.pem" ] \ if [ -e "/etc/letsencrypt/live/$(hostname)/cert.pem" ] \
@ -233,11 +530,9 @@ case $SSL_TYPE in
sed -i -e 's~ssl_key = </etc/dovecot/private/dovecot\.pem~ssl_key = </etc/letsencrypt/live/'$(hostname)'/'"$KEY"'\.pem~g' /etc/dovecot/conf.d/10-ssl.conf sed -i -e 's~ssl_key = </etc/dovecot/private/dovecot\.pem~ssl_key = </etc/letsencrypt/live/'$(hostname)'/'"$KEY"'\.pem~g' /etc/dovecot/conf.d/10-ssl.conf
echo "SSL configured with 'letsencrypt' certificates" echo "SSL configured with 'letsencrypt' certificates"
fi fi
fi fi
;; ;;
"custom" ) "custom" )
# Adding CA signed SSL certificate if provided in 'postfix/ssl' folder # Adding CA signed SSL certificate if provided in 'postfix/ssl' folder
if [ -e "/tmp/docker-mailserver/ssl/$(hostname)-full.pem" ]; then if [ -e "/tmp/docker-mailserver/ssl/$(hostname)-full.pem" ]; then
@ -254,10 +549,8 @@ case $SSL_TYPE in
sed -i -e 's~ssl_key = </etc/dovecot/private/dovecot\.pem~ssl_key = </etc/postfix/ssl/'$(hostname)'-full\.pem~g' /etc/dovecot/conf.d/10-ssl.conf sed -i -e 's~ssl_key = </etc/dovecot/private/dovecot\.pem~ssl_key = </etc/postfix/ssl/'$(hostname)'-full\.pem~g' /etc/dovecot/conf.d/10-ssl.conf
echo "SSL configured with 'CA signed/custom' certificates" echo "SSL configured with 'CA signed/custom' certificates"
fi fi
;; ;;
"manual" ) "manual" )
# Lets you manually specify the location of the SSL Certs to use. This gives you some more control over this whole processes (like using kube-lego to generate certs) # Lets you manually specify the location of the SSL Certs to use. This gives you some more control over this whole processes (like using kube-lego to generate certs)
if [ -n "$SSL_CERT_PATH" ] \ if [ -n "$SSL_CERT_PATH" ] \
@ -278,11 +571,9 @@ case $SSL_TYPE in
sed -i -e 's~ssl_key = </etc/dovecot/private/dovecot\.pem~ssl_key = </etc/postfix/ssl/key~g' /etc/dovecot/conf.d/10-ssl.conf sed -i -e 's~ssl_key = </etc/dovecot/private/dovecot\.pem~ssl_key = </etc/postfix/ssl/key~g' /etc/dovecot/conf.d/10-ssl.conf
echo "SSL configured with 'Manual' certificates" echo "SSL configured with 'Manual' certificates"
fi fi
;; ;;
"self-signed" )
"self-signed" )
# Adding self-signed SSL certificate if provided in 'postfix/ssl' folder # Adding self-signed SSL certificate if provided in 'postfix/ssl' folder
if [ -e "/tmp/docker-mailserver/ssl/$(hostname)-cert.pem" ] \ if [ -e "/tmp/docker-mailserver/ssl/$(hostname)-cert.pem" ] \
&& [ -e "/tmp/docker-mailserver/ssl/$(hostname)-key.pem" ] \ && [ -e "/tmp/docker-mailserver/ssl/$(hostname)-key.pem" ] \
@ -309,20 +600,26 @@ case $SSL_TYPE in
sed -i -e 's~ssl_key = </etc/dovecot/private/dovecot\.pem~ssl_key = </etc/postfix/ssl/'$(hostname)'-key\.pem~g' /etc/dovecot/conf.d/10-ssl.conf sed -i -e 's~ssl_key = </etc/dovecot/private/dovecot\.pem~ssl_key = </etc/postfix/ssl/'$(hostname)'-key\.pem~g' /etc/dovecot/conf.d/10-ssl.conf
echo "SSL configured with 'self-signed' certificates" echo "SSL configured with 'self-signed' certificates"
fi fi
;; ;;
esac
}
esac function _setup_postfix_vhost() {
notify 'task' "Setting up Postfix vhost"
if [ -f /tmp/vhost.tmp ]; then if [ -f /tmp/vhost.tmp ]; then
cat /tmp/vhost.tmp | sort | uniq > /etc/postfix/vhost && rm /tmp/vhost.tmp cat /tmp/vhost.tmp | sort | uniq > /etc/postfix/vhost && rm /tmp/vhost.tmp
fi fi
}
# PERMIT_DOCKER Option function _setup_docker_permit() {
container_ip=$(ip addr show eth0 | grep 'inet ' | sed 's/[^0-9\.\/]*//g' | cut -d '/' -f 1) notify 'task' 'Setting up PERMIT_DOCKER Option'
container_network="$(echo $container_ip | cut -d '.' -f1-2).0.0"
case $PERMIT_DOCKER in container_ip=$(ip addr show eth0 | grep 'inet ' | sed 's/[^0-9\.\/]*//g' | cut -d '/' -f 1)
container_network="$(echo $container_ip | cut -d '.' -f1-2).0.0"
case $PERMIT_DOCKER in
"host" ) "host" )
echo "Adding $container_network/16 to my networks" echo "Adding $container_network/16 to my networks"
postconf -e "$(postconf | grep '^mynetworks =') $container_network/16" postconf -e "$(postconf | grep '^mynetworks =') $container_network/16"
@ -343,29 +640,49 @@ case $PERMIT_DOCKER in
bash -c "echo $container_ip/32 >> /etc/opendmarc/ignore.hosts" bash -c "echo $container_ip/32 >> /etc/opendmarc/ignore.hosts"
bash -c "echo $container_ip/32 >> /etc/opendkim/TrustedHosts" bash -c "echo $container_ip/32 >> /etc/opendkim/TrustedHosts"
;; ;;
esac
esac # @TODO fix: bash: /etc/opendkim/TrustedHosts: No such file or directory
# temporary workarround return success
return 0
}
# function _setup_postfix_override_configuration() {
# Override Postfix configuration notify 'task' 'Setting up Postfix Override configuration'
#
if [ -f /tmp/docker-mailserver/postfix-main.cf ]; then if [ -f /tmp/docker-mailserver/postfix-main.cf ]; then
while read line; do while read line; do
postconf -e "$line" postconf -e "$line"
done < /tmp/docker-mailserver/postfix-main.cf done < /tmp/docker-mailserver/postfix-main.cf
echo "Loaded 'config/postfix-main.cf'" echo "Loaded 'config/postfix-main.cf'"
else else
echo "No extra postfix settings loaded because optional '/tmp/docker-mailserver/postfix-main.cf' not provided." echo "No extra postfix settings loaded because optional '/tmp/docker-mailserver/postfix-main.cf' not provided."
fi fi
}
# Support general SASL password function _setup_postfix_sasl_password() {
rm -f /etc/postfix/sasl_passwd notify 'task' 'Setting up Postfix SASL Password'
if [ ! -z "$SASL_PASSWD" ]; then
# Support general SASL password
rm -f /etc/postfix/sasl_passwd
if [ ! -z "$SASL_PASSWD" ]; then
echo "$SASL_PASSWD" >> /etc/postfix/sasl_passwd echo "$SASL_PASSWD" >> /etc/postfix/sasl_passwd
fi fi
# Support outgoing email relay via Amazon SES # Install SASL passwords
if [ ! -z "$AWS_SES_HOST" -a ! -z "$AWS_SES_USERPASS" ]; then if [ -f /etc/postfix/sasl_passwd ]; then
chown root:root /etc/postfix/sasl_passwd
chmod 0600 /etc/postfix/sasl_passwd
echo "Loaded SASL_PASSWD"
else
echo "==> 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 if [ -z "$AWS_SES_PORT" ];then
AWS_SES_PORT=25 AWS_SES_PORT=25
fi fi
@ -380,49 +697,100 @@ if [ ! -z "$AWS_SES_HOST" -a ! -z "$AWS_SES_USERPASS" ]; then
"smtp_tls_security_level = encrypt" \ "smtp_tls_security_level = encrypt" \
"smtp_tls_note_starttls_offer = yes" \ "smtp_tls_note_starttls_offer = yes" \
"smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt" "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt"
fi fi
}
# Install SASL passwords
if [ -f /etc/postfix/sasl_passwd ]; then
chown root:root /etc/postfix/sasl_passwd
chmod 0600 /etc/postfix/sasl_passwd
echo "Loaded SASL_PASSWD"
else
echo "==> Warning: 'SASL_PASSWD' is not provided. /etc/postfix/sasl_passwd not created."
fi
# Fix permissions, but skip this if 3 levels deep the user id is already set function _setup_security_stack() {
if [ `find /var/mail -maxdepth 3 -a \( \! -user 5000 -o \! -group 5000 \) | grep -c .` != 0 ]; then notify 'task' 'Setting up Security Stack'
echo "Fixing /var/mail permissions"
chown -R 5000:5000 /var/mail
else
echo "Permissions in /var/mail look OK"
fi
echo "Creating /etc/mailname" echo "Configuring Spamassassin"
echo $(hostname -d) > /etc/mailname 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/
echo "Configuring Spamassassin" if [ "$ENABLE_FAIL2BAN" = 1 ]; then
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" echo "Fail2ban enabled"
test -e /tmp/docker-mailserver/fail2ban-jail.cf && cp /tmp/docker-mailserver/fail2ban-jail.cf /etc/fail2ban/jail.local test -e /tmp/docker-mailserver/fail2ban-jail.cf && cp /tmp/docker-mailserver/fail2ban-jail.cf /etc/fail2ban/jail.local
else else
# Disable logrotate config for fail2ban if not enabled # Disable logrotate config for fail2ban if not enabled
rm -f /etc/logrotate.d/fail2ban rm -f /etc/logrotate.d/fail2ban
fi fi
# Fix cron.daily for spamassassin # Fix cron.daily for spamassassin
sed -i -e 's~invoke-rc.d spamassassin reload~/etc/init\.d/spamassassin reload~g' /etc/cron.daily/spamassassin sed -i -e 's~invoke-rc.d spamassassin reload~/etc/init\.d/spamassassin reload~g' /etc/cron.daily/spamassassin
# Consolidate all state that should be persisted across container restarts into one mounted # Copy user provided configuration files if provided
# directory if [ -f /tmp/docker-mailserver/amavis.cf ]; then
statedir=/var/mail-state cp /tmp/docker-mailserver/amavis.cf /etc/amavis/conf.d/50-user
if [ "$ONE_DIR" = 1 -a -d $statedir ]; then fi
}
function _setup_elk_forwarder() {
notify 'task' 'Setting up Elk forwarder'
ELK_PORT=${ELK_PORT:="5044"}
ELK_HOST=${ELK_HOST:="elk"}
echo "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" \
> /etc/filebeat/filebeat.yml
}
##########################################################################
# << Setup Stack
##########################################################################
##########################################################################
# >> Fix Stack
#
# Description: Place functions for temporary workarounds and fixes here
##########################################################################
function fix() {
notify 'taskgrg' "Starting to fix:"
for _func in "${FUNCS_FIX[@]}";do
$_func
[ $? != 0 ] && defunc
done
}
function _fix_var_mail_permissions() {
notify 'task' 'Fixing /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"
else
echo "Permissions in /var/mail look OK"
fi
}
##########################################################################
# << Fix Stack
##########################################################################
##########################################################################
# >> Misc Stack
#
# Description: Place functions that do not fit in the sections above here
##########################################################################
function misc() {
notify 'taskgrp' 'Starting Misc:'
for _func in "${FUNCS_MISC[@]}";do
$_func
[ $? != 0 ] && defunc
done
}
function _misc_save_states() {
# Consolidate all state that should be persisted across container restarts into one mounted
# directory
statedir=/var/mail-state
if [ "$ONE_DIR" = 1 -a -d $statedir ]; then
echo "Consolidating all state onto $statedir" echo "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 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'` dest=$statedir/`echo $d | sed -e 's/.var.//; s/\//-/g'`
@ -440,87 +808,142 @@ if [ "$ONE_DIR" = 1 -a -d $statedir ]; then
ln -s $dest $d ln -s $dest $d
fi fi
done done
fi fi
if [ "$ENABLE_ELK_FORWARDER" = 1 ]; then }
ELK_PORT=${ELK_PORT:="5044"}
ELK_HOST=${ELK_HOST:="elk"}
echo "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" \
> /etc/filebeat/filebeat.yml
fi
echo "Starting daemons"
cron
/etc/init.d/rsyslog start
if [ "$ENABLE_ELK_FORWARDER" = 1 ]; then
/etc/init.d/filebeat start
fi
# Enable Managesieve service by setting the symlink ##########################################################################
# to the configuration file Dovecot will actually find # >> Start Daemons
if [ "$ENABLE_MANAGESIEVE" = 1 ]; then ##########################################################################
echo "Sieve management enabled" function start_daemons() {
mv /etc/dovecot/protocols.d/managesieved.protocol.disab /etc/dovecot/protocols.d/managesieved.protocol notify 'taskgrp' 'Starting Daemons'
fi
if [ "$SMTP_ONLY" != 1 ]; then for _func in "${DAEMONS_START[@]}";do
$_func
[ $? != 0 ] && defunc
done
}
function _start_daemons_sys() {
notify 'task' 'Starting Cron'
cron
notify 'task' 'Starting rsyslog'
/etc/init.d/rsyslog start
}
function _start_daemons_saslauthd() {
notify "task" "Starting saslauthd"
/etc/init.d/saslauthd start
}
function _start_daemons_fail2ban() {
notify 'task' 'Starting fail2ban'
touch /var/log/auth.log
/etc/init.d/fail2ban start
}
function _start_daemons_opendkim() {
notify 'task' 'Starting opendkim'
/etc/init.d/opendkim start
}
function _start_daemons_opendmarc() {
notify 'task' 'Starting opendmarc'
/etc/init.d/opendmarc start
}
function _start_daemons_postfix() {
notify 'task' 'Starting postfix'
/etc/init.d/postfix start
}
function _start_daemons_dovecot() {
# Here we are starting sasl and imap, not pop3 because it's disabled by default # Here we are starting sasl and imap, not pop3 because it's disabled by default
echo " * Starting dovecot services" notify 'task' "Starting dovecot services"
/usr/sbin/dovecot -c /etc/dovecot/dovecot.conf /usr/sbin/dovecot -c /etc/dovecot/dovecot.conf
fi
if [ "$ENABLE_POP3" = 1 -a "$SMTP_ONLY" != 1 ]; then if [ "$ENABLE_POP3" = 1 ]; then
echo "Starting POP3 services" echo "Starting POP3 services"
mv /etc/dovecot/protocols.d/pop3d.protocol.disab /etc/dovecot/protocols.d/pop3d.protocol mv /etc/dovecot/protocols.d/pop3d.protocol.disab /etc/dovecot/protocols.d/pop3d.protocol
/usr/sbin/dovecot reload /usr/sbin/dovecot reload
fi fi
if [ -f /tmp/docker-mailserver/dovecot.cf ]; then if [ -f /tmp/docker-mailserver/dovecot.cf ]; then
echo 'Adding file "dovecot.cf" to the Dovecot configuration' echo 'Adding file "dovecot.cf" to the Dovecot configuration'
cp /tmp/docker-mailserver/dovecot.cf /etc/dovecot/local.conf cp /tmp/docker-mailserver/dovecot.cf /etc/dovecot/local.conf
/usr/sbin/dovecot reload /usr/sbin/dovecot reload
fi fi
# Enable fetchmail daemon # @TODO fix: on integration test
if [ "$ENABLE_FETCHMAIL" = 1 ]; then # doveadm: Error: userdb lookup: connect(/var/run/dovecot/auth-userdb) failed: No such file or directory
# doveadm: Fatal: user listing failed
#if [ "$ENABLE_LDAP" != 1 ]; then
#echo "Listing users"
#/usr/sbin/dovecot user '*'
#fi
}
function _start_daemons_filebeat() {
notify 'task' 'Starting FileBeat'
/etc/init.d/filebeat start
}
function _start_daemons_fetchmail() {
notify 'task' 'Starting fetchmail'
/usr/local/bin/setup-fetchmail /usr/local/bin/setup-fetchmail
echo "Fetchmail enabled" echo "Fetchmail enabled"
/etc/init.d/fetchmail start /etc/init.d/fetchmail start
fi }
# Start services related to SMTP function _start_daemons_clamav() {
if ! [ "$DISABLE_CLAMAV" = 1 ]; then notify 'task' "Starting clamav"
/etc/init.d/clamav-daemon start /etc/init.d/clamav-daemon start
fi }
# Copy user provided configuration files if provided function _start_daemons_amavis() {
if [ -f /tmp/docker-mailserver/amavis.cf ]; then notify 'task' 'Starting Daemon Amavis'
cp /tmp/docker-mailserver/amavis.cf /etc/amavis/conf.d/50-user
fi
if ! [ "$DISABLE_AMAVIS" = 1 ]; then
/etc/init.d/amavis start /etc/init.d/amavis start
fi
/etc/init.d/opendkim start
/etc/init.d/opendmarc start
/etc/init.d/postfix start
if [ "$ENABLE_FAIL2BAN" = 1 ]; then # @TODO fix: on integration test of mail_with_ldap amavis fails because of:
echo "Starting fail2ban service" # Starting amavisd: The value of variable $myhostname is "ldap", but should have been
touch /var/log/auth.log # a fully qualified domain name; perhaps uname(3) did not provide such.
/etc/init.d/fail2ban start # You must explicitly assign a FQDN of this host to variable $myhostname
fi # in /etc/amavis/conf.d/05-node_id, or fix what uname(3) provides as a host's
# network name!
if [ "$ENABLE_SASLAUTHD" = 1 ]; then # > temporary workaround to passe integration test
/etc/init.d/saslauthd start return 0
fi }
##########################################################################
# << Start Daemons
##########################################################################
if [ "$SMTP_ONLY" != 1 -a "$ENABLE_LDAP" != 1 ]; then
echo "Listing users"
/usr/sbin/dovecot user '*'
fi
echo "Starting..."
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, unless you exactly know what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# >>
register_functions
check
setup
fix
misc
start_daemons
tail -f /var/log/mail/mail.log tail -f /var/log/mail/mail.log
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, unless you exactly know what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# <<
exit 0