2016-01-20 15:41:34 +00:00
#!/bin/bash
2015-03-28 14:59:15 +00:00
2016-12-01 14:45:40 +00:00
##########################################################################
# >> DEFAULT VARS
2016-10-30 11:42:29 +00:00
#
2017-02-07 19:53:34 +00:00
# add them here.
2016-12-01 14:45:40 +00:00
# Example: DEFAULT_VARS["KEY"]="VALUE"
##########################################################################
declare -A DEFAULT_VARS
2016-12-25 21:54:37 +00:00
DEFAULT_VARS[ "ENABLE_CLAMAV" ] = " ${ ENABLE_CLAMAV : = "0" } "
DEFAULT_VARS[ "ENABLE_SPAMASSASSIN" ] = " ${ ENABLE_SPAMASSASSIN : = "0" } "
2016-12-27 14:55:41 +00:00
DEFAULT_VARS[ "ENABLE_POP3" ] = " ${ ENABLE_POP3 : = "0" } "
2016-12-25 21:54:37 +00:00
DEFAULT_VARS[ "ENABLE_FAIL2BAN" ] = " ${ ENABLE_FAIL2BAN : = "0" } "
DEFAULT_VARS[ "ENABLE_MANAGESIEVE" ] = " ${ ENABLE_MANAGESIEVE : = "0" } "
DEFAULT_VARS[ "ENABLE_FETCHMAIL" ] = " ${ ENABLE_FETCHMAIL : = "0" } "
DEFAULT_VARS[ "ENABLE_LDAP" ] = " ${ ENABLE_LDAP : = "0" } "
2017-02-06 09:21:18 +00:00
DEFAULT_VARS[ "ENABLE_POSTGREY" ] = " ${ ENABLE_POSTGREY : = "0" } "
DEFAULT_VARS[ "POSTGREY_DELAY" ] = " ${ POSTGREY_DELAY : = "300" } "
DEFAULT_VARS[ "POSTGREY_MAX_AGE" ] = " ${ POSTGREY_MAX_AGE : = "35" } "
DEFAULT_VARS[ "POSTGREY_TEXT" ] = " ${ POSTGREY_TEXT : = "Delayed by postgrey" } "
2016-12-25 21:54:37 +00:00
DEFAULT_VARS[ "ENABLE_SASLAUTHD" ] = " ${ ENABLE_SASLAUTHD : = "0" } "
2016-12-27 15:09:16 +00:00
DEFAULT_VARS[ "SMTP_ONLY" ] = " ${ SMTP_ONLY : = "0" } "
2016-12-23 22:56:39 +00:00
DEFAULT_VARS[ "DMS_DEBUG" ] = " ${ DMS_DEBUG : = "0" } "
2017-01-20 22:30:29 +00:00
DEFAULT_VARS[ "OVERRIDE_HOSTNAME" ] = " ${ OVERRIDE_HOSTNAME } "
2016-12-01 14:45:40 +00:00
##########################################################################
# << DEFAULT VARS
##########################################################################
2017-01-09 22:49:46 +00:00
##########################################################################
# >> GLOBAL VARS
#
# add your global script variables here.
#
# Example: KEY="VALUE"
##########################################################################
HOSTNAME = " $( hostname -f) "
DOMAINNAME = " $( hostname -d) "
##########################################################################
# << GLOBAL VARS
##########################################################################
2016-12-01 14:45:40 +00:00
##########################################################################
# >> REGISTER FUNCTIONS
2016-10-30 11:42:29 +00:00
#
2017-02-07 19:53:34 +00:00
# add your new functions/methods here.
2016-10-08 17:02:47 +00:00
#
2016-12-01 14:45:40 +00:00
# NOTE: position matters when registering a function in stacks. First in First out
2017-02-07 19:53:34 +00:00
# Execution Logic:
2016-12-01 14:45:40 +00:00
# > check functions
# > setup functions
# > fix functions
# > misc functions
# > start-daemons
2016-10-30 13:11:36 +00:00
#
2017-02-07 19:53:34 +00:00
# Example:
2016-12-01 14:45:40 +00:00
# if [ CONDITION IS MET ]; then
# _register_{setup,fix,check,start}_{functions,daemons} "$FUNCNAME"
# fi
2016-10-30 13:11:36 +00:00
#
2016-12-01 14:45:40 +00:00
# Implement them in the section-group: {check,setup,fix,start}
##########################################################################
function register_functions( ) {
2016-12-23 22:56:39 +00:00
notify 'taskgrp' 'Initializing setup'
notify 'task' 'Registering check,setup,fix,misc and start-daemons functions'
2016-12-01 14:45:40 +00:00
################### >> 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"
2017-01-03 09:55:03 +00:00
_register_setup_function "_setup_postfix_sasl"
2016-12-01 14:45:40 +00:00
fi
2017-02-06 09:21:18 +00:00
if [ " $ENABLE_POSTGREY " = 1 ] ; then
_register_setup_function "_setup_postgrey"
fi
2016-12-01 14:45:40 +00:00
_register_setup_function "_setup_dkim"
_register_setup_function "_setup_ssl"
_register_setup_function "_setup_docker_permit"
_register_setup_function "_setup_mailname"
2017-01-20 22:30:29 +00:00
_register_setup_function "_setup_amavis"
2017-02-13 10:07:30 +00:00
_register_setup_function "_setup_dmarc_hostname"
_register_setup_function "_setup_postfix_hostname"
_register_setup_function "_setup_dovecot_hostname"
2016-12-01 14:45:40 +00:00
_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"
2016-12-23 22:56:39 +00:00
if [ ! -z " $AWS_SES_HOST " -a ! -z " $AWS_SES_USERPASS " ] ; then
_register_setup_function "_setup_postfix_relay_amazon_ses"
fi
2016-12-01 14:45:40 +00:00
2017-01-09 22:52:36 +00:00
if [ " $ENABLE_POSTFIX_VIRTUAL_TRANSPORT " = 1 ] ; then
_register_setup_function "_setup_postfix_virtual_transport"
fi
2017-03-14 14:22:19 +00:00
_register_setup_function "_setup_environment"
2016-12-01 14:45:40 +00:00
################### << setup funcs
################### >> fix funcs
_register_fix_function "_fix_var_mail_permissions"
2017-02-07 19:53:34 +00:00
_register_fix_function "_fix_var_amavis_permissions"
2016-12-01 14:45:40 +00:00
################### << fix funcs
################### >> misc funcs
_register_misc_function "_misc_save_states"
2017-02-07 19:53:34 +00:00
2016-12-01 14:45:40 +00:00
################### << misc funcs
################### >> daemon funcs
2016-12-23 22:56:39 +00:00
_register_start_daemon "_start_daemons_cron"
_register_start_daemon "_start_daemons_rsyslog"
2016-12-01 14:45:40 +00:00
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"
2017-02-06 09:21:18 +00:00
#postfix uses postgrey, needs to be started before postfix
if [ " $ENABLE_POSTGREY " = 1 ] ; then
_register_start_daemon "_start_daemons_postgrey"
fi
2017-02-07 19:53:34 +00:00
2016-12-01 14:45:40 +00:00
_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
2016-12-25 21:54:37 +00:00
if [ " $ENABLE_CLAMAV " = 1 ] ; then
2016-12-01 14:45:40 +00:00
_register_start_daemon "_start_daemons_clamav"
fi
2017-02-06 09:21:18 +00:00
2017-01-20 22:30:29 +00:00
_register_start_daemon "_start_daemons_amavis"
2016-12-01 14:45:40 +00:00
################### << 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"
2016-12-23 22:56:39 +00:00
c_brown = "\e[0;33m"
2016-12-01 14:45:40 +00:00
c_blue = "\e[0;34m"
c_bold = "\033[1m"
c_reset = "\e[0m"
notification_type = $1
notification_msg = $2
2016-12-23 22:56:39 +00:00
notification_format = $3
msg = ""
2016-12-01 14:45:40 +00:00
case " ${ notification_type } " in
2016-12-23 22:56:39 +00:00
'taskgrp' )
msg = " ${ c_bold } ${ notification_msg } ${ c_reset } "
; ;
'task' )
if [ [ ${ DEFAULT_VARS [ "DMS_DEBUG" ] } = = 1 ] ] ; then
msg = " ${ notification_msg } ${ c_reset } "
fi
; ;
2016-12-01 14:45:40 +00:00
'inf' )
2016-12-23 22:56:39 +00:00
if [ [ ${ DEFAULT_VARS [ "DMS_DEBUG" ] } = = 1 ] ] ; then
msg = " ${ c_green } * ${ notification_msg } ${ c_reset } "
fi
2016-12-01 14:45:40 +00:00
; ;
2016-12-23 22:56:39 +00:00
'started' )
msg = " ${ c_green } ${ notification_msg } ${ c_reset } "
2016-12-01 14:45:40 +00:00
; ;
'warn' )
2016-12-23 22:56:39 +00:00
msg = " ${ c_brown } * ${ notification_msg } ${ c_reset } "
2016-12-01 14:45:40 +00:00
; ;
2016-12-23 22:56:39 +00:00
'err' )
msg = " ${ c_red } * ${ notification_msg } ${ c_reset } "
2016-12-01 14:45:40 +00:00
; ;
'fatal' )
2016-12-23 22:56:39 +00:00
msg = " ${ c_red } Error: ${ notification_msg } ${ c_reset } "
2016-12-01 14:45:40 +00:00
; ;
*)
msg = ""
; ;
esac
2016-12-23 22:56:39 +00:00
case " ${ notification_format } " in
'n' )
options = "-ne"
; ;
*)
options = "-e"
; ;
esac
[ [ ! -z " ${ msg } " ] ] && echo $options " ${ msg } "
2016-12-01 14:45:40 +00:00
}
function defunc( ) {
2017-02-07 19:53:34 +00:00
notify 'fatal' "Please fix your configuration. Exiting..."
2016-12-01 14:45:40 +00:00
exit 1
}
2016-12-23 22:56:39 +00:00
function display_startup_daemon( ) {
$1 & >/dev/null
res = $?
if [ [ ${ DEFAULT_VARS [ "DMS_DEBUG" ] } = = 1 ] ] ; then
if [ $res = 0 ] ; then
notify 'started' " [ OK ]"
else
echo "false"
notify 'err' " [ FAILED ]"
fi
fi
return $res
}
2016-12-01 14:45:40 +00:00
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, except you know exactly what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# <<
2016-10-30 13:11:36 +00:00
2015-08-26 08:04:07 +00:00
2016-12-01 14:45:40 +00:00
##########################################################################
# >> Check Stack
2016-10-30 13:11:36 +00:00
#
2016-12-01 14:45:40 +00:00
# Description: Place functions for initial check of container sanity
##########################################################################
function check( ) {
2016-12-23 22:56:39 +00:00
notify 'taskgrp' 'Checking configuration'
2016-12-01 14:45:40 +00:00
for _func in " ${ FUNCS_CHECK [@] } " ; do
$_func
[ $? != 0 ] && defunc
done
}
function _check_hostname( ) {
2017-01-20 22:30:29 +00:00
notify "task" " Check that hostname/domainname is provided or overidden (no default docker hostname/kubernetes) [ $FUNCNAME ] "
if [ [ ! -z ${ DEFAULT_VARS [ "OVERRIDE_HOSTNAME" ] } ] ] ; then
export HOSTNAME = ${ DEFAULT_VARS [ "OVERRIDE_HOSTNAME" ] }
export DOMAINNAME = $( echo $HOSTNAME | sed s/[ ^.] *.//)
fi
2016-12-01 14:45:40 +00:00
2017-01-09 22:49:46 +00:00
if ( ! echo $HOSTNAME | grep -E '^(\S+[.]\S+)$' > /dev/null ) ; then
2016-12-01 14:45:40 +00:00
notify 'err' "Setting hostname/domainname is required"
return 1
2017-02-07 19:53:34 +00:00
else
2017-01-20 22:30:29 +00:00
notify 'inf' " Domain has been set to $DOMAINNAME "
2017-01-09 22:49:46 +00:00
notify 'inf' " Hostname has been set to $HOSTNAME "
2016-12-01 14:45:40 +00:00
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
2016-10-30 13:11:36 +00:00
#
2016-12-01 14:45:40 +00:00
# Description: Place functions for functional configurations here
##########################################################################
function setup( ) {
2016-12-23 22:56:39 +00:00
notify 'taskgrp' 'Configuring mail server'
2016-12-01 14:45:40 +00:00
for _func in " ${ FUNCS_SETUP [@] } " ; do
$_func
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
2016-12-23 22:56:39 +00:00
notify 'inf' " Set $var = ${ DEFAULT_VARS [ $var ] } "
2016-12-01 14:45:40 +00:00
done
}
function _setup_mailname( ) {
notify 'task' 'Setting up Mailname'
2016-12-23 22:56:39 +00:00
notify 'inf' "Creating /etc/mailname"
2017-01-09 22:49:46 +00:00
echo $DOMAINNAME > /etc/mailname
2016-12-01 14:45:40 +00:00
}
2017-01-20 22:30:29 +00:00
function _setup_amavis( ) {
notify 'task' 'Setting up Amavis'
notify 'inf' "Applying hostname to /etc/amavis/conf.d/05-node_id"
sed -i 's/^#\$myhostname = "mail.example.com";/\$myhostname = "' $HOSTNAME '";/' /etc/amavis/conf.d/05-node_id
}
2017-02-13 10:07:30 +00:00
function _setup_dmarc_hostname( ) {
notify 'task' 'Setting up dmarc'
notify 'inf' "Applying hostname to /etc/opendmarc.conf"
sed -i -e 's/^AuthservID.*$/AuthservID ' $HOSTNAME '/g' \
-e 's/^TrustedAuthservIDs.*$/TrustedAuthservIDs ' $HOSTNAME '/g' /etc/opendmarc.conf
}
function _setup_postfix_hostname( ) {
notify 'task' 'Applying hostname and domainname to Postfix'
notify 'inf' "Applying hostname to /etc/postfix/main.cf"
postconf -e " myhostname = $HOSTNAME "
postconf -e " mydomain = $DOMAINNAME "
}
function _setup_dovecot_hostname( ) {
notify 'task' 'Applying hostname to Dovecot'
notify 'inf' "Applying hostname to /etc/dovecot/conf.d/15-lda.conf"
sed -i 's/^#hostname =.*$/hostname = ' $HOSTNAME '/g' /etc/dovecot/conf.d/15-lda.conf
}
2016-12-01 14:45:40 +00:00
function _setup_dovecot( ) {
notify 'task' 'Setting up Dovecot'
cp -a /usr/share/dovecot/protocols.d /etc/dovecot/
# 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/managesieved.protocol /etc/dovecot/protocols.d/managesieved.protocol.disab
sed -i -e 's/#ssl = yes/ssl = yes/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/#ssl = yes/ssl = required/g' /etc/dovecot/conf.d/10-ssl.conf
# Enable Managesieve service by setting the symlink
# to the configuration file Dovecot will actually find
if [ " $ENABLE_MANAGESIEVE " = 1 ] ; then
2016-12-23 22:56:39 +00:00
notify 'inf' "Sieve management enabled"
2016-12-01 14:45:40 +00:00
mv /etc/dovecot/protocols.d/managesieved.protocol.disab /etc/dovecot/protocols.d/managesieved.protocol
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
2016-12-23 22:56:39 +00:00
notify 'inf' "Checking file line endings"
2016-12-01 14:45:40 +00:00
sed -i 's/\r//g' /tmp/docker-mailserver/postfix-accounts.cf
2016-12-23 22:56:39 +00:00
notify 'inf' "Regenerating postfix user list"
2016-12-01 14:45:40 +00:00
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
sed -i -e '$a\' /tmp/docker-mailserver/postfix-accounts.cf
chown dovecot:dovecot /etc/dovecot/userdb
chmod 640 /etc/dovecot/userdb
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
# Creating users
# 'pass' is encrypted
2017-04-07 20:28:19 +00:00
# comments and empty lines are ignored
grep -v " ^\s* $\|^\s*\# " /tmp/docker-mailserver/postfix-accounts.cf | while IFS = $'|' read login pass
2016-12-01 14:45:40 +00:00
do
# Setting variables for better readability
user = $( echo ${ login } | cut -d @ -f1)
domain = $( echo ${ login } | cut -d @ -f2)
# Let's go!
2016-12-23 22:56:39 +00:00
notify 'inf' " user ' ${ user } ' for domain ' ${ domain } ' with password '********' "
2016-12-01 14:45:40 +00:00
echo " ${ login } ${ domain } / ${ user } / " >> /etc/postfix/vmailbox
# User database for dovecot has the following format:
# user:password:uid:gid:(gecos):home:(shell):extra_fields
# Example :
# ${login}:${pass}:5000:5000::/var/mail/${domain}/${user}::userdb_mail=maildir:/var/mail/${domain}/${user}
echo " ${ login } : ${ pass } :5000:5000::/var/mail/ ${ domain } / ${ user } :: " >> /etc/dovecot/userdb
mkdir -p /var/mail/${ domain }
if [ ! -d " /var/mail/ ${ domain } / ${ user } " ] ; then
maildirmake.dovecot " /var/mail/ ${ domain } / ${ user } "
maildirmake.dovecot " /var/mail/ ${ domain } / ${ user } /.Sent "
maildirmake.dovecot " /var/mail/ ${ domain } / ${ user } /.Trash "
maildirmake.dovecot " /var/mail/ ${ domain } / ${ user } /.Drafts "
echo -e "INBOX\nSent\nTrash\nDrafts" >> " /var/mail/ ${ domain } / ${ user } /subscriptions "
touch " /var/mail/ ${ domain } / ${ user } /.Sent/maildirfolder "
fi
# Copy user provided sieve file, if present
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
2017-03-28 08:59:02 +00:00
done
2016-12-01 14:45:40 +00:00
else
2016-12-23 22:56:39 +00:00
notify 'warn' "'config/docker-mailserver/postfix-accounts.cf' is not provided. No mail account created."
2016-12-01 14:45:40 +00:00
fi
}
function _setup_ldap( ) {
notify 'task' 'Setting up Ldap'
for i in 'users' 'groups' 'aliases' ; do
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|^bind_dn.*|bind_dn = ' ${ LDAP_BIND_DN : = "cn=admin,dc=domain,dc=com" } '|g' \
-e 's|^bind_pw.*|bind_pw = ' ${ LDAP_BIND_PW : = "admin" } '|g' \
/etc/postfix/ldap-${ i } .cf
done
2017-01-09 22:49:46 +00:00
notify 'inf' "Configuring dovecot LDAP authentification"
2016-12-01 14:45:40 +00:00
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' \
-e 's|^dnpass\s*=.*|dnpass = ' ${ LDAP_BIND_PW : = "admin" } '|g' \
/etc/dovecot/dovecot-ldap.conf.ext
# Add domainname to vhost.
2017-01-09 22:49:46 +00:00
echo $DOMAINNAME >> /tmp/vhost.tmp
2016-12-01 14:45:40 +00:00
2016-12-23 22:56:39 +00:00
notify 'inf' "Enabling dovecot LDAP authentification"
2016-12-01 14:45:40 +00:00
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
2016-12-23 22:56:39 +00:00
notify 'inf' "Configuring LDAP"
2016-12-01 14:45:40 +00:00
[ -f /etc/postfix/ldap-users.cf ] && \
postconf -e "virtual_mailbox_maps = ldap:/etc/postfix/ldap-users.cf" || \
2016-12-23 22:56:39 +00:00
notify 'inf' "==> Warning: /etc/postfix/ldap-user.cf not found"
2016-12-01 14:45:40 +00:00
[ -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" || \
2016-12-23 22:56:39 +00:00
notify 'inf' "==> Warning: /etc/postfix/ldap-aliases.cf or /etc/postfix/ldap-groups.cf not found"
2016-12-01 14:45:40 +00:00
2017-01-03 09:55:03 +00:00
return 0
}
2017-02-06 09:21:18 +00:00
function _setup_postgrey( ) {
notify 'inf' "Configuring postgrey"
sed -i -e 's/bl.spamcop.net$/bl.spamcop.net, check_policy_service inet:127.0.0.1:10023/' /etc/postfix/main.cf
sed -i -e " s/\"--inet=10023\"/\"--inet=10023 --delay= $POSTGREY_DELAY --max-age= $POSTGREY_MAX_AGE \"/ " /etc/default/postgrey
TEXT_FOUND = ` grep -i "POSTGREY_TEXT" /etc/default/postgrey | wc -l`
2017-02-07 19:53:34 +00:00
2017-02-06 09:21:18 +00:00
if [ $TEXT_FOUND -eq 0 ] ; then
printf " POSTGREY_TEXT=\" $POSTGREY_TEXT \"\n\n " >> /etc/default/postgrey
fi
2017-04-12 15:59:04 +00:00
cp -f /tmp/docker-mailserver/whitelist_clients.local /etc/postgrey/whitelist_clients.local
2017-02-06 09:21:18 +00:00
}
2017-01-03 09:55:03 +00:00
function _setup_postfix_sasl( ) {
2016-12-01 14:45:40 +00:00
[ ! -f /etc/postfix/sasl/smtpd.conf ] && cat > /etc/postfix/sasl/smtpd.conf << EOF
2016-10-30 13:11:36 +00:00
pwcheck_method: saslauthd
mech_list: plain login
EOF
2017-01-03 09:55:03 +00:00
return 0
2016-12-01 14:45:40 +00:00
}
2016-10-30 13:11:36 +00:00
2016-12-01 14:45:40 +00:00
function _setup_saslauthd( ) {
2016-12-23 22:56:39 +00:00
notify 'task' "Setting up Saslauthd"
2016-12-01 14:45:40 +00:00
2016-12-23 22:56:39 +00:00
notify 'inf' "Configuring Cyrus SASL"
2016-12-01 14:45:40 +00:00
# checking env vars and setting defaults
2017-02-06 11:11:15 +00:00
[ -z " $SASLAUTHD_MECHANISMS " ] && SASLAUTHD_MECHANISMS = pam
[ " $SASLAUTHD_MECHANISMS " = ldap -a -z " $SASLAUTHD_LDAP_SEARCH_BASE " ] && SASLAUTHD_MECHANISMS = pam
[ -z " $SASLAUTHD_LDAP_SERVER " ] && SASLAUTHD_LDAP_SERVER = localhost
[ -z " $SASLAUTHD_LDAP_FILTER " ] && SASLAUTHD_LDAP_FILTER = '(&(uniqueIdentifier=%u)(mailEnabled=TRUE))'
( [ -z " $SASLAUTHD_LDAP_SSL " ] || [ $SASLAUTHD_LDAP_SSL = = 0 ] ) && SASLAUTHD_LDAP_PROTO = 'ldap://' || SASLAUTHD_LDAP_PROTO = 'ldaps://'
2016-12-01 14:45:40 +00:00
if [ ! -f /etc/saslauthd.conf ] ; then
2016-12-23 22:56:39 +00:00
notify 'inf' "Creating /etc/saslauthd.conf"
2016-12-01 14:45:40 +00:00
cat > /etc/saslauthd.conf << EOF
2016-10-30 13:11:36 +00:00
ldap_servers: ${ SASLAUTHD_LDAP_PROTO } ${ SASLAUTHD_LDAP_SERVER }
ldap_auth_method: bind
ldap_bind_dn: ${ SASLAUTHD_LDAP_BIND_DN }
ldap_bind_pw: ${ SASLAUTHD_LDAP_PASSWORD }
ldap_search_base: ${ SASLAUTHD_LDAP_SEARCH_BASE }
ldap_filter: ${ SASLAUTHD_LDAP_FILTER }
ldap_referrals: yes
log_level: 10
EOF
2016-12-01 14:45:40 +00:00
fi
2016-12-19 12:39:30 +00:00
sed -i \
-e "/^[^#].*smtpd_sasl_type.*/s/^/#/g" \
-e "/^[^#].*smtpd_sasl_path.*/s/^/#/g" \
etc/postfix/master.cf
2016-12-01 14:45:40 +00:00
sed -i \
-e "s|^START=.*|START=yes|g" \
-e "s|^MECHANISMS=.*|MECHANISMS=" \" $SASLAUTHD_MECHANISMS \" "|g" \
-e "s|^MECH_OPTIONS=.*|MECH_OPTIONS=" \" $SASLAUTHD_MECH_OPTIONS \" "|g" \
/etc/default/saslauthd
2017-01-03 09:55:03 +00:00
if [ " $SASLAUTHD_MECHANISMS " = rimap ] ; then
sed -i \
-e 's|^OPTIONS="|OPTIONS="-r |g' \
/etc/default/saslauthd
fi
2016-12-01 14:45:40 +00:00
sed -i \
-e "/smtpd_sasl_path =.*/d" \
-e "/smtpd_sasl_type =.*/d" \
-e "/dovecot_destination_recipient_limit =.*/d" \
/etc/postfix/main.cf
gpasswd -a postfix sasl
}
2016-10-30 13:11:36 +00:00
2016-12-01 14:45:40 +00:00
function _setup_postfix_aliases( ) {
notify 'task' 'Setting up Postfix Aliases'
echo -n > /etc/postfix/virtual
echo -n > /etc/postfix/regexp
if [ -f /tmp/docker-mailserver/postfix-virtual.cf ] ; then
# Copying virtual file
cp -f /tmp/docker-mailserver/postfix-virtual.cf /etc/postfix/virtual
while read from to
do
# Setting variables for better readability
uname = $( echo ${ from } | cut -d @ -f1)
domain = $( echo ${ from } | cut -d @ -f2)
# if they are equal it means the line looks like: "user1 other@domain.tld"
test " $uname " != " $domain " && echo ${ domain } >> /tmp/vhost.tmp
done < /tmp/docker-mailserver/postfix-virtual.cf
else
2016-12-23 22:56:39 +00:00
notify 'inf' "Warning 'config/postfix-virtual.cf' is not provided. No mail alias/forward created."
2016-12-01 14:45:40 +00:00
fi
if [ -f /tmp/docker-mailserver/postfix-regexp.cf ] ; then
# Copying regexp alias file
2016-12-23 22:56:39 +00:00
notify 'inf' "Adding regexp alias file postfix-regexp.cf"
2016-12-01 14:45:40 +00:00
cp -f /tmp/docker-mailserver/postfix-regexp.cf /etc/postfix/regexp
sed -i -e ' /^virtual_alias_maps/{
s/ regexp:.*//
s/$/ regexp:\/ etc\/ postfix\/ regexp/
} ' /etc/postfix/main.cf
fi
}
function _setup_dkim( ) {
notify 'task' 'Setting up DKIM'
2016-12-23 22:56:39 +00:00
mkdir -p /etc/opendkim && touch /etc/opendkim/SigningTable
2016-12-01 14:45:40 +00:00
# Check if keys are already available
if [ -e "/tmp/docker-mailserver/opendkim/KeyTable" ] ; then
cp -a /tmp/docker-mailserver/opendkim/* /etc/opendkim/
2016-12-23 22:56:39 +00:00
notify 'inf' "DKIM keys added for: `ls -C /etc/opendkim/keys/`"
notify 'inf' "Changing permissions on /etc/opendkim"
2016-12-01 14:45:40 +00:00
chown -R opendkim:opendkim /etc/opendkim/
# And make sure permissions are right
chmod -R 0700 /etc/opendkim/keys/
else
2016-12-23 22:56:39 +00:00
notify 'warn' "No DKIM key provided. Check the documentation to find how to get your keys."
2016-12-01 14:45:40 +00:00
fi
}
function _setup_ssl( ) {
notify 'task' 'Setting up SSL'
# SSL Configuration
case $SSL_TYPE in
"letsencrypt" )
# letsencrypt folders and files mounted in /etc/letsencrypt
2017-01-09 22:49:46 +00:00
if [ -e " /etc/letsencrypt/live/ $HOSTNAME /cert.pem " ] \
&& [ -e " /etc/letsencrypt/live/ $HOSTNAME /fullchain.pem " ] ; then
2016-12-01 14:45:40 +00:00
KEY = ""
2017-01-09 22:49:46 +00:00
if [ -e " /etc/letsencrypt/live/ $HOSTNAME /privkey.pem " ] ; then
2016-12-01 14:45:40 +00:00
KEY = "privkey"
2017-01-09 22:49:46 +00:00
elif [ -e " /etc/letsencrypt/live/ $HOSTNAME /key.pem " ] ; then
2016-12-01 14:45:40 +00:00
KEY = "key"
fi
if [ -n " $KEY " ] ; then
2017-01-09 22:49:46 +00:00
notify 'inf' " Adding $HOSTNAME SSL certificate "
2016-12-01 14:45:40 +00:00
# Postfix configuration
2017-01-09 22:49:46 +00:00
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
sed -i -r 's~smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key~smtpd_tls_key_file=/etc/letsencrypt/live/' $HOSTNAME '/' " $KEY " '\.pem~g' /etc/postfix/main.cf
2016-12-01 14:45:40 +00:00
# Dovecot configuration
2017-01-09 22:49:46 +00:00
sed -i -e 's~ssl_cert = </etc/dovecot/dovecot\.pem~ssl_cert = </etc/letsencrypt/live/' $HOSTNAME '/fullchain\.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
2016-12-01 14:45:40 +00:00
2016-12-23 22:56:39 +00:00
notify 'inf' "SSL configured with 'letsencrypt' certificates"
2016-12-01 14:45:40 +00:00
fi
fi
; ;
"custom" )
# Adding CA signed SSL certificate if provided in 'postfix/ssl' folder
2017-01-09 22:49:46 +00:00
if [ -e " /tmp/docker-mailserver/ssl/ $HOSTNAME -full.pem " ] ; then
notify 'inf' " Adding $HOSTNAME SSL certificate "
2016-12-01 14:45:40 +00:00
mkdir -p /etc/postfix/ssl
2017-01-09 22:49:46 +00:00
cp " /tmp/docker-mailserver/ssl/ $HOSTNAME -full.pem " /etc/postfix/ssl
2016-12-01 14:45:40 +00:00
# Postfix configuration
2017-01-09 22:49:46 +00:00
sed -i -r 's~smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem~smtpd_tls_cert_file=/etc/postfix/ssl/' $HOSTNAME '-full.pem~g' /etc/postfix/main.cf
sed -i -r 's~smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key~smtpd_tls_key_file=/etc/postfix/ssl/' $HOSTNAME '-full.pem~g' /etc/postfix/main.cf
2016-12-01 14:45:40 +00:00
# Dovecot configuration
2017-01-09 22:49:46 +00:00
sed -i -e 's~ssl_cert = </etc/dovecot/dovecot\.pem~ssl_cert = </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
2016-12-01 14:45:40 +00:00
2016-12-23 22:56:39 +00:00
notify 'inf' "SSL configured with 'CA signed/custom' certificates"
2016-12-01 14:45:40 +00:00
fi
; ;
"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)
if [ -n " $SSL_CERT_PATH " ] \
&& [ -n " $SSL_KEY_PATH " ] ; then
2016-12-23 22:56:39 +00:00
notify 'inf' " Configuring certificates using cert $SSL_CERT_PATH and key $SSL_KEY_PATH "
2016-12-01 14:45:40 +00:00
mkdir -p /etc/postfix/ssl
cp " $SSL_CERT_PATH " /etc/postfix/ssl/cert
cp " $SSL_KEY_PATH " /etc/postfix/ssl/key
chmod 600 /etc/postfix/ssl/cert
chmod 600 /etc/postfix/ssl/key
# Postfix configuration
sed -i -r 's~smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem~smtpd_tls_cert_file=/etc/postfix/ssl/cert~g' /etc/postfix/main.cf
sed -i -r 's~smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key~smtpd_tls_key_file=/etc/postfix/ssl/key~g' /etc/postfix/main.cf
# Dovecot configuration
sed -i -e 's~ssl_cert = </etc/dovecot/dovecot\.pem~ssl_cert = </etc/postfix/ssl/cert~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
2016-12-23 22:56:39 +00:00
notify 'inf' "SSL configured with 'Manual' certificates"
2016-12-01 14:45:40 +00:00
fi
; ;
"self-signed" )
# Adding self-signed SSL certificate if provided in 'postfix/ssl' folder
2017-01-09 22:49:46 +00:00
if [ -e " /tmp/docker-mailserver/ssl/ $HOSTNAME -cert.pem " ] \
&& [ -e " /tmp/docker-mailserver/ssl/ $HOSTNAME -key.pem " ] \
&& [ -e " /tmp/docker-mailserver/ssl/ $HOSTNAME -combined.pem " ] \
2016-12-01 14:45:40 +00:00
&& [ -e "/tmp/docker-mailserver/ssl/demoCA/cacert.pem" ] ; then
2017-01-09 22:49:46 +00:00
notify 'inf' " Adding $HOSTNAME SSL certificate "
2016-12-01 14:45:40 +00:00
mkdir -p /etc/postfix/ssl
2017-01-09 22:49:46 +00:00
cp " /tmp/docker-mailserver/ssl/ $HOSTNAME -cert.pem " /etc/postfix/ssl
cp " /tmp/docker-mailserver/ssl/ $HOSTNAME -key.pem " /etc/postfix/ssl
2016-12-01 14:45:40 +00:00
# Force permission on key file
2017-01-09 22:49:46 +00:00
chmod 600 /etc/postfix/ssl/$HOSTNAME -key.pem
cp " /tmp/docker-mailserver/ssl/ $HOSTNAME -combined.pem " /etc/postfix/ssl
2016-12-01 14:45:40 +00:00
cp /tmp/docker-mailserver/ssl/demoCA/cacert.pem /etc/postfix/ssl
# Postfix configuration
2017-01-09 22:49:46 +00:00
sed -i -r 's~smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem~smtpd_tls_cert_file=/etc/postfix/ssl/' $HOSTNAME '-cert.pem~g' /etc/postfix/main.cf
sed -i -r 's~smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key~smtpd_tls_key_file=/etc/postfix/ssl/' $HOSTNAME '-key.pem~g' /etc/postfix/main.cf
2016-12-01 14:45:40 +00:00
sed -i -r 's~#smtpd_tls_CAfile=~smtpd_tls_CAfile=/etc/postfix/ssl/cacert.pem~g' /etc/postfix/main.cf
sed -i -r 's~#smtp_tls_CAfile=~smtp_tls_CAfile=/etc/postfix/ssl/cacert.pem~g' /etc/postfix/main.cf
2017-01-09 22:49:46 +00:00
ln -s /etc/postfix/ssl/cacert.pem " /etc/ssl/certs/cacert- $HOSTNAME .pem "
2016-12-01 14:45:40 +00:00
# Dovecot configuration
2017-01-09 22:49:46 +00:00
sed -i -e 's~ssl_cert = </etc/dovecot/dovecot\.pem~ssl_cert = </etc/postfix/ssl/' $HOSTNAME '-combined\.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
2016-12-01 14:45:40 +00:00
2016-12-23 22:56:39 +00:00
notify 'inf' "SSL configured with 'self-signed' certificates"
2016-12-01 14:45:40 +00:00
fi
; ;
esac
}
function _setup_postfix_vhost( ) {
notify 'task' "Setting up Postfix vhost"
if [ -f /tmp/vhost.tmp ] ; then
cat /tmp/vhost.tmp | sort | uniq > /etc/postfix/vhost && rm /tmp/vhost.tmp
fi
}
function _setup_docker_permit( ) {
notify 'task' 'Setting up PERMIT_DOCKER Option'
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" )
2016-12-23 22:56:39 +00:00
notify 'inf' " Adding $container_network /16 to my networks "
2016-12-01 14:45:40 +00:00
postconf -e " $( postconf | grep '^mynetworks =' ) $container_network /16 "
2016-12-23 22:56:39 +00:00
echo $container_network /16 >> /etc/opendmarc/ignore.hosts
echo $container_network /16 >> /etc/opendkim/TrustedHosts
2016-12-01 14:45:40 +00:00
; ;
"network" )
2016-12-23 22:56:39 +00:00
notify 'inf' "Adding docker network in my networks"
2016-12-01 14:45:40 +00:00
postconf -e " $( postconf | grep '^mynetworks =' ) 172.16.0.0/12 "
2016-12-23 22:56:39 +00:00
echo 172.16.0.0/12 >> /etc/opendmarc/ignore.hosts
echo 172.16.0.0/12 >> /etc/opendkim/TrustedHosts
2016-12-01 14:45:40 +00:00
; ;
* )
2016-12-23 22:56:39 +00:00
notify 'inf' "Adding container ip in my networks"
2016-12-01 14:45:40 +00:00
postconf -e " $( postconf | grep '^mynetworks =' ) $container_ip /32 "
2016-12-23 22:56:39 +00:00
echo $container_ip /32 >> /etc/opendmarc/ignore.hosts
echo $container_ip /32 >> /etc/opendkim/TrustedHosts
2016-12-01 14:45:40 +00:00
; ;
esac
}
2017-01-09 22:52:36 +00:00
function _setup_postfix_virtual_transport( ) {
notify 'task' 'Setting up Postfix virtual transport'
2017-02-06 11:11:15 +00:00
[ -z " ${ POSTFIX_DAGENT } " ] && \
2017-01-09 22:52:36 +00:00
echo " ${ POSTFIX_DAGENT } not set. " && \
return 1
2017-02-07 19:53:34 +00:00
postconf -e " virtual_transport = ${ POSTFIX_DAGENT } "
2017-01-09 22:52:36 +00:00
}
2016-12-01 14:45:40 +00:00
function _setup_postfix_override_configuration( ) {
notify 'task' 'Setting up Postfix Override configuration'
if [ -f /tmp/docker-mailserver/postfix-main.cf ] ; then
while read line; do
2017-04-07 20:28:19 +00:00
# all valid postfix options start with a lower case letter
# http://www.postfix.org/postconf.5.html
2017-03-28 08:59:02 +00:00
if [ [ " $line " = ~ ^[ a-z] ] ] ; then
2016-12-01 14:45:40 +00:00
postconf -e " $line "
2017-03-28 08:59:02 +00:00
fi
2016-12-01 14:45:40 +00:00
done < /tmp/docker-mailserver/postfix-main.cf
2016-12-23 22:56:39 +00:00
notify 'inf' "Loaded 'config/postfix-main.cf'"
2016-12-01 14:45:40 +00:00
else
2016-12-23 22:56:39 +00:00
notify 'inf' "No extra postfix settings loaded because optional '/tmp/docker-mailserver/postfix-main.cf' not provided."
2016-12-01 14:45:40 +00:00
fi
}
function _setup_postfix_sasl_password( ) {
notify 'task' 'Setting up Postfix SASL Password'
# Support general SASL password
rm -f /etc/postfix/sasl_passwd
if [ ! -z " $SASL_PASSWD " ] ; then
echo " $SASL_PASSWD " >> /etc/postfix/sasl_passwd
fi
# Install SASL passwords
if [ -f /etc/postfix/sasl_passwd ] ; then
chown root:root /etc/postfix/sasl_passwd
chmod 0600 /etc/postfix/sasl_passwd
2016-12-23 22:56:39 +00:00
notify 'inf' "Loaded SASL_PASSWD"
2016-12-01 14:45:40 +00:00
else
2016-12-23 22:56:39 +00:00
notify 'inf' "Warning: 'SASL_PASSWD' is not provided. /etc/postfix/sasl_passwd not created."
2016-12-01 14:45:40 +00:00
fi
}
function _setup_postfix_relay_amazon_ses( ) {
notify 'task' 'Setting up Postfix Relay Amazon SES'
2016-12-23 22:56:39 +00:00
if [ -z " $AWS_SES_PORT " ] ; then
AWS_SES_PORT = 25
2016-12-01 14:45:40 +00:00
fi
2016-12-23 22:56:39 +00:00
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"
2016-12-01 14:45:40 +00:00
}
function _setup_security_stack( ) {
2016-12-23 22:56:39 +00:00
notify 'task' "Setting up Security Stack"
2016-12-01 14:45:40 +00:00
2016-12-25 21:54:37 +00:00
# recreate auto-generated file
dms_amavis_file = "/etc/amavis/conf.d/51-dms_auto_generated"
echo "# WARNING: this file is auto-generated." > $dms_amavis_file
echo "use strict;" >> $dms_amavis_file
# Spamassassin
if [ " $ENABLE_SPAMASSASSIN " = 0 ] ; then
notify 'warn' "Spamassassin is disabled. You can enable it with 'ENABLE_SPAMASSASSIN=1'"
echo "@bypass_spam_checks_maps = (1);" >> $dms_amavis_file
elif [ " $ENABLE_SPAMASSASSIN " = 1 ] ; then
notify 'inf' "Enabling and 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/
fi
# Clamav
if [ " $ENABLE_CLAMAV " = 0 ] ; then
notify 'warn' "Clamav is disabled. You can enable it with 'ENABLE_CLAMAV=1'"
echo "@bypass_virus_checks_maps = (1);" >> $dms_amavis_file
elif [ " $ENABLE_CLAMAV " = 1 ] ; then
2016-12-25 14:41:02 +00:00
notify 'inf' "Enabling clamav"
fi
2016-12-25 21:54:37 +00:00
echo "1; # ensure a defined return" >> $dms_amavis_file
# Fail2ban
2016-12-01 14:45:40 +00:00
if [ " $ENABLE_FAIL2BAN " = 1 ] ; then
2016-12-23 22:56:39 +00:00
notify 'inf' "Fail2ban enabled"
2016-12-01 14:45:40 +00:00
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
rm -f /etc/logrotate.d/fail2ban
fi
2016-08-21 20:10:13 +00:00
2016-12-01 14:45:40 +00:00
# Fix cron.daily for spamassassin
sed -i -e 's~invoke-rc.d spamassassin reload~/etc/init\.d/spamassassin reload~g' /etc/cron.daily/spamassassin
# Copy user provided configuration files if provided
if [ -f /tmp/docker-mailserver/amavis.cf ] ; then
cp /tmp/docker-mailserver/amavis.cf /etc/amavis/conf.d/50-user
fi
}
function _setup_elk_forwarder( ) {
notify 'task' 'Setting up Elk forwarder'
ELK_PORT = ${ ELK_PORT : = "5044" }
ELK_HOST = ${ ELK_HOST : = "elk" }
2016-12-23 22:56:39 +00:00
notify 'inf' " Enabling log forwarding to ELK ( $ELK_HOST : $ELK_PORT ) "
2016-12-01 14:45:40 +00:00
cat /etc/filebeat/filebeat.yml.tmpl \
| sed " s@\$ELK_HOST@ $ELK_HOST @g " \
| sed " s@\$ELK_PORT@ $ELK_PORT @g " \
> /etc/filebeat/filebeat.yml
}
2017-03-14 14:22:19 +00:00
function _setup_environment( ) {
notify 'task' 'Setting up /etc/environment'
local banner = "# docker environment"
local var
if ! grep -q " $banner " /etc/environment; then
echo $banner >> /etc/environment
for var in "VIRUSMAILS_DELETE_DELAY" ; do
echo " $var = ${ !var } " >> /etc/environment
done
fi
}
2016-12-01 14:45:40 +00:00
##########################################################################
# << Setup Stack
##########################################################################
##########################################################################
# >> Fix Stack
2016-04-11 22:04:33 +00:00
#
2016-12-01 14:45:40 +00:00
# Description: Place functions for temporary workarounds and fixes here
##########################################################################
function fix( ) {
2016-12-23 22:56:39 +00:00
notify 'taskgrg' "Post-configuration checks..."
2016-12-01 14:45:40 +00:00
for _func in " ${ FUNCS_FIX [@] } " ; do
$_func
[ $? != 0 ] && defunc
done
}
function _fix_var_mail_permissions( ) {
2017-02-08 22:31:56 +00:00
notify 'task' 'Checking /var/mail permissions'
2016-12-01 14:45:40 +00:00
# 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
2016-12-23 22:56:39 +00:00
notify 'inf' "Fixing /var/mail permissions"
2016-12-01 14:45:40 +00:00
chown -R 5000:5000 /var/mail
else
2016-12-23 22:56:39 +00:00
notify 'inf' "Permissions in /var/mail look OK"
2017-01-02 12:39:46 +00:00
return 0
2016-12-01 14:45:40 +00:00
fi
}
2017-02-07 19:53:34 +00:00
function _fix_var_amavis_permissions( ) {
2017-02-08 22:31:56 +00:00
if [ " $ONE_DIR " -eq 0 ] ; then
amavis_state_dir = /var/lib/amavis
else
amavis_state_dir = /var/mail-state/lib-amavis
fi
notify 'task' 'Checking $amavis_state_dir permissions'
amavis_permissions_status = $( find -H $amavis_state_dir -maxdepth 3 -a \( \! -user amavis -o \! -group amavis \) )
2017-02-07 19:53:34 +00:00
2017-02-08 22:31:56 +00:00
if [ -n " $amavis_permissions_status " ] ; then
notify 'inf' " Fixing $amavis_state_dir permissions "
chown -hR amavis:amavis $amavis_state_dir
2017-02-07 19:53:34 +00:00
else
2017-02-08 22:31:56 +00:00
notify 'inf' " Permissions in $amavis_state_dir look OK "
2017-02-07 19:53:34 +00:00
return 0
fi
}
2016-12-01 14:45:40 +00:00
##########################################################################
# << Fix Stack
##########################################################################
##########################################################################
# >> Misc Stack
2016-04-11 22:04:33 +00:00
#
2016-12-01 14:45:40 +00:00
# Description: Place functions that do not fit in the sections above here
##########################################################################
function misc( ) {
2016-12-23 22:56:39 +00:00
notify 'taskgrp' 'Starting Misc'
2016-12-01 14:45:40 +00:00
for _func in " ${ FUNCS_MISC [@] } " ; do
$_func
2016-12-23 22:56:39 +00:00
[ $? != 0 ] && defunc
2016-12-01 14:45:40 +00:00
done
}
function _misc_save_states( ) {
2017-01-09 16:11:10 +00:00
# consolidate all states into a single directory (`/var/mail-state`) to allow persistence using docker volumes
2016-12-01 14:45:40 +00:00
statedir = /var/mail-state
if [ " $ONE_DIR " = 1 -a -d $statedir ] ; then
2016-12-23 22:56:39 +00:00
notify 'inf' " Consolidating all state onto $statedir "
2017-02-09 16:05:36 +00:00
for d in /var/spool/postfix /var/lib/postfix /var/lib/amavis /var/lib/clamav /var/lib/spamassasin /var/lib/fail2ban /var/lib/postgrey; do
2016-12-01 14:45:40 +00:00
dest = $statedir /` echo $d | sed -e 's/.var.//; s/\//-/g' `
if [ -d $dest ] ; then
2016-12-23 22:56:39 +00:00
notify 'inf' " Destination $dest exists, linking $d to it "
2016-12-01 14:45:40 +00:00
rm -rf $d
ln -s $dest $d
elif [ -d $d ] ; then
2016-12-23 22:56:39 +00:00
notify 'inf' " Moving contents of $d to $dest : " ` ls $d `
2016-12-01 14:45:40 +00:00
mv $d $dest
ln -s $dest $d
else
2016-12-23 22:56:39 +00:00
notify 'inf' " Linking $d to $dest "
2016-12-01 14:45:40 +00:00
mkdir -p $dest
ln -s $dest $d
fi
done
fi
}
##########################################################################
# >> Start Daemons
##########################################################################
function start_daemons( ) {
2016-12-23 22:56:39 +00:00
notify 'taskgrp' 'Starting mail server'
2016-12-01 14:45:40 +00:00
for _func in " ${ DAEMONS_START [@] } " ; do
$_func
2016-12-23 22:56:39 +00:00
[ $? != 0 ] && defunc
2016-12-01 14:45:40 +00:00
done
}
2016-12-23 22:56:39 +00:00
function _start_daemons_cron( ) {
notify 'task' 'Starting cron' 'n'
2017-02-07 19:53:34 +00:00
display_startup_daemon "cron"
2016-12-23 22:56:39 +00:00
}
2016-12-01 14:45:40 +00:00
2016-12-23 22:56:39 +00:00
function _start_daemons_rsyslog( ) {
notify 'task' 'Starting rsyslog' 'n'
2017-02-07 19:53:34 +00:00
display_startup_daemon "/etc/init.d/rsyslog start"
2016-12-01 14:45:40 +00:00
}
function _start_daemons_saslauthd( ) {
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting saslauthd' 'n'
display_startup_daemon "/etc/init.d/saslauthd start"
2016-12-01 14:45:40 +00:00
}
function _start_daemons_fail2ban( ) {
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting fail2ban' 'n'
2016-12-01 14:45:40 +00:00
touch /var/log/auth.log
2016-12-18 12:06:45 +00:00
# Delete fail2ban.sock that probably was left here after container restart
2017-01-09 22:49:46 +00:00
if [ -e /var/run/fail2ban/fail2ban.sock ] ; then
rm /var/run/fail2ban/fail2ban.sock
fi
2016-12-23 22:56:39 +00:00
display_startup_daemon "/etc/init.d/fail2ban start"
2016-12-01 14:45:40 +00:00
}
function _start_daemons_opendkim( ) {
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting opendkim' 'n'
display_startup_daemon "/etc/init.d/opendkim start"
2016-12-01 14:45:40 +00:00
}
function _start_daemons_opendmarc( ) {
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting opendmarc' 'n'
display_startup_daemon "/etc/init.d/opendmarc start"
2016-12-01 14:45:40 +00:00
}
function _start_daemons_postfix( ) {
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting postfix' 'n'
display_startup_daemon "/etc/init.d/postfix start"
2016-12-01 14:45:40 +00:00
}
function _start_daemons_dovecot( ) {
# Here we are starting sasl and imap, not pop3 because it's disabled by default
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting dovecot services' 'n'
display_startup_daemon "/usr/sbin/dovecot -c /etc/dovecot/dovecot.conf"
2016-12-01 14:45:40 +00:00
if [ " $ENABLE_POP3 " = 1 ] ; then
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting pop3 services' 'n'
2016-12-01 14:45:40 +00:00
mv /etc/dovecot/protocols.d/pop3d.protocol.disab /etc/dovecot/protocols.d/pop3d.protocol
2016-12-23 22:56:39 +00:00
display_startup_daemon "/usr/sbin/dovecot reload"
2016-12-01 14:45:40 +00:00
fi
if [ -f /tmp/docker-mailserver/dovecot.cf ] ; then
cp /tmp/docker-mailserver/dovecot.cf /etc/dovecot/local.conf
/usr/sbin/dovecot reload
fi
2017-02-07 19:53:34 +00:00
# @TODO fix: on integration test
2016-12-01 14:45:40 +00:00
# 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( ) {
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting filebeat' 'n'
display_startup_daemon "/etc/init.d/filebeat start"
2016-12-01 14:45:40 +00:00
}
function _start_daemons_fetchmail( ) {
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting fetchmail' 'n'
2016-12-01 14:45:40 +00:00
/usr/local/bin/setup-fetchmail
2016-12-23 22:56:39 +00:00
display_startup_daemon "/etc/init.d/fetchmail start"
2016-12-01 14:45:40 +00:00
}
function _start_daemons_clamav( ) {
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting clamav' 'n'
display_startup_daemon "/etc/init.d/clamav-daemon start"
2016-12-01 14:45:40 +00:00
}
2017-02-06 09:21:18 +00:00
function _start_daemons_postgrey( ) {
notify 'task' 'Starting postgrey' 'n'
display_startup_daemon "/etc/init.d/postgrey start"
}
2016-12-01 14:45:40 +00:00
function _start_daemons_amavis( ) {
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting amavis' 'n'
display_startup_daemon "/etc/init.d/amavis start"
2016-12-01 14:45:40 +00:00
}
2017-01-20 22:30:29 +00:00
2016-12-01 14:45:40 +00:00
##########################################################################
# << Start Daemons
##########################################################################
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, unless you exactly know what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# >>
2016-12-23 22:56:39 +00:00
if [ [ ${ DEFAULT_VARS [ "DMS_DEBUG" ] } = = 1 ] ] ; then
notify 'taskgrp' ""
notify 'taskgrp' "#"
notify 'taskgrp' "#"
notify 'taskgrp' "# ENV"
notify 'taskgrp' "#"
notify 'taskgrp' "#"
notify 'taskgrp' ""
printenv
fi
notify 'taskgrp' ""
notify 'taskgrp' "#"
notify 'taskgrp' "#"
notify 'taskgrp' "# docker-mailserver"
notify 'taskgrp' "#"
notify 'taskgrp' "#"
notify 'taskgrp' ""
2016-12-01 14:45:40 +00:00
register_functions
2017-02-07 19:53:34 +00:00
check
2016-12-01 14:45:40 +00:00
setup
fix
misc
start_daemons
2016-12-23 22:56:39 +00:00
notify 'taskgrp' ""
notify 'taskgrp' "#"
2017-01-09 22:49:46 +00:00
notify 'taskgrp' " # $HOSTNAME is up and running "
2016-12-23 22:56:39 +00:00
notify 'taskgrp' "#"
notify 'taskgrp' ""
tail -fn 0 /var/log/mail/mail.log
2016-12-01 14:45:40 +00:00
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, unless you exactly know what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# <<
exit 0