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" } "
2017-10-04 20:10:18 +00:00
DEFAULT_VARS[ "FETCHMAIL_POLL" ] = " ${ FETCHMAIL_POLL : = "300" } "
2016-12-25 21:54:37 +00:00
DEFAULT_VARS[ "ENABLE_LDAP" ] = " ${ ENABLE_LDAP : = "0" } "
2018-11-04 18:50:40 +00:00
DEFAULT_VARS[ "LDAP_START_TLS" ] = " ${ LDAP_START_TLS : = "no" } "
DEFAULT_VARS[ "DOVECOT_TLS" ] = " ${ DOVECOT_TLS : = "no" } "
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" } "
2018-11-01 18:32:36 +00:00
DEFAULT_VARS[ "POSTGREY_AUTO_WHITELIST_CLIENTS" ] = " ${ POSTGREY_AUTO_WHITELIST_CLIENTS : = "5" } "
2017-02-06 09:21:18 +00:00
DEFAULT_VARS[ "POSTGREY_TEXT" ] = " ${ POSTGREY_TEXT : = "Delayed by postgrey" } "
2018-10-20 18:10:30 +00:00
DEFAULT_VARS[ "POSTFIX_MESSAGE_SIZE_LIMIT" ] = " ${ POSTFIX_MESSAGE_SIZE_LIMIT : = "10240000" } " # ~10 MB by default
2018-10-15 19:17:45 +00:00
DEFAULT_VARS[ "POSTFIX_MAILBOX_SIZE_LIMIT" ] = " ${ POSTFIX_MAILBOX_SIZE_LIMIT : = "0" } " # no limit by default
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 } "
Introducing Postscreen (#799)
* Introduced Postscreen
cheaper, earlier and simpler blocking of zombies/spambots.
From http://postfix.cs.utah.edu/POSTSCREEN_README.html :
As a first layer, postscreen(8) blocks connections from zombies and other spambots that are responsible for about 90% of all spam. It is implemented as a single process to make this defense as cheap as possible.
Things we need to consider:
- Do we need a whitelist/backlist file? (http://postfix.cs.utah.edu/postconf.5.html#postscreen_access_list)
- Via introducing an optional config/postfix-access.cidr
- The only permanent whitelisting I could imagine are monitoring services(which might (still?) behave weird/hastely) or blacklisting backup servers(since no traffic should be coming from them anyway)
- Do we need deep inspections? They are desireable, but these tests are expensive: a good client must disconnect after it passes the test, before it can talk to a real Postfix SMTP server. Considered tests are:
- postscreen_bare_newline_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_bare_newline_action)
- postscreen_non_smtp_command_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_non_smtp_command_action)
- postscreen_pipelining_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_pipelining_action)
- Do we need to make the blacklisting via dnsblocking configurable? It's currently set and weighted as follows, where a score of 3 results in blocking, a score of -1 results in whitelisting:
(*: adds the specified weight to the SMTP client's DNSBL score. Specify a negative number for whitelisting.)
(http://postfix.cs.utah.edu/postconf.5.html#postscreen_dnsbl_sites)
- zen.spamhaus.org*3
- bl.mailspike.net
- b.barracudacentral.org*2
- bl.spameatingmonkey.net
- bl.spamcop.net
- dnsbl.sorbs.net
- psbl.surriel.com
- list.dnswl.org=127.0.[0..255].0*-2
- list.dnswl.org=127.0.[0..255].1*-3
- list.dnswl.org=127.0.[0..255].[2..3]*-4
- What to do when blacklisting? I currently set it to drop. We could
- ignore: Ignore the failure of this test. Allow other tests to complete. Repeat this test the next time the client connects. This option is useful for testing and collecting statistics without blocking mail.
- enforce: Allow other tests to complete. Reject attempts to deliver mail with a 550 SMTP reply, and log the helo/sender/recipient information. Repeat this test the next time the client connects.
- drop: Drop the connection immediately with a 521 SMTP reply. Repeat this test the next time the client connects.
In the end I think we could drop postgrey support. Postscreen replaces postgrey in its entirety, while being more selective and not delaying mail. Especially if we consider using the deep inspection options of postscreen.
Hope that wasn't too much to read! ;)
* main.cf got misformatted..
Don't know how, should be ok now.
* fixed malformatted main.cf & repaired master.cf
* reenabled rbl stuff.. It's cached, therefore doesn't hurt
* fixed tests
* added tests, repaired tests, added info, introduced new Variable POSTSCREEN_ACTION, fixes
2018-02-04 20:31:08 +00:00
DEFAULT_VARS[ "POSTSCREEN_ACTION" ] = " ${ POSTSCREEN_ACTION : = "enforce" } "
2018-03-07 18:33:43 +00:00
DEFAULT_VARS[ "SPOOF_PROTECTION" ] = " ${ SPOOF_PROTECTION : = "0" } "
2018-02-22 07:36:12 +00:00
DEFAULT_VARS[ "TLS_LEVEL" ] = " ${ TLS_LEVEL : = "modern" } "
2018-03-18 19:15:06 +00:00
DEFAULT_VARS[ "ENABLE_SRS" ] = " ${ ENABLE_SRS : = "0" } "
2018-03-18 18:52:28 +00:00
DEFAULT_VARS[ "REPORT_RECIPIENT" ] = " ${ REPORT_RECIPIENT : = "0" } "
DEFAULT_VARS[ "REPORT_INTERVAL" ] = " ${ REPORT_INTERVAL : = "daily" } "
2018-04-04 16:48:55 +00:00
DEFAULT_VARS[ "VIRUSMAILS_DELETE_DELAY" ] = " ${ VIRUSMAILS_DELETE_DELAY : = "7" } "
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) "
2019-08-01 07:58:22 +00:00
CHKSUM_FILE = /tmp/docker-mailserver-config-chksum
2017-01-09 22:49:46 +00:00
##########################################################################
# << 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"
2019-07-23 14:12:12 +00:00
_register_setup_function "_setup_dovecot_dhparam"
2016-12-01 14:45:40 +00:00
_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
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
2017-04-26 12:56:33 +00:00
_register_setup_function "_setup_postfix_sasl"
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"
2017-09-06 21:41:23 +00:00
_register_setup_function "_setup_postfix_dhparam"
Introducing Postscreen (#799)
* Introduced Postscreen
cheaper, earlier and simpler blocking of zombies/spambots.
From http://postfix.cs.utah.edu/POSTSCREEN_README.html :
As a first layer, postscreen(8) blocks connections from zombies and other spambots that are responsible for about 90% of all spam. It is implemented as a single process to make this defense as cheap as possible.
Things we need to consider:
- Do we need a whitelist/backlist file? (http://postfix.cs.utah.edu/postconf.5.html#postscreen_access_list)
- Via introducing an optional config/postfix-access.cidr
- The only permanent whitelisting I could imagine are monitoring services(which might (still?) behave weird/hastely) or blacklisting backup servers(since no traffic should be coming from them anyway)
- Do we need deep inspections? They are desireable, but these tests are expensive: a good client must disconnect after it passes the test, before it can talk to a real Postfix SMTP server. Considered tests are:
- postscreen_bare_newline_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_bare_newline_action)
- postscreen_non_smtp_command_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_non_smtp_command_action)
- postscreen_pipelining_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_pipelining_action)
- Do we need to make the blacklisting via dnsblocking configurable? It's currently set and weighted as follows, where a score of 3 results in blocking, a score of -1 results in whitelisting:
(*: adds the specified weight to the SMTP client's DNSBL score. Specify a negative number for whitelisting.)
(http://postfix.cs.utah.edu/postconf.5.html#postscreen_dnsbl_sites)
- zen.spamhaus.org*3
- bl.mailspike.net
- b.barracudacentral.org*2
- bl.spameatingmonkey.net
- bl.spamcop.net
- dnsbl.sorbs.net
- psbl.surriel.com
- list.dnswl.org=127.0.[0..255].0*-2
- list.dnswl.org=127.0.[0..255].1*-3
- list.dnswl.org=127.0.[0..255].[2..3]*-4
- What to do when blacklisting? I currently set it to drop. We could
- ignore: Ignore the failure of this test. Allow other tests to complete. Repeat this test the next time the client connects. This option is useful for testing and collecting statistics without blocking mail.
- enforce: Allow other tests to complete. Reject attempts to deliver mail with a 550 SMTP reply, and log the helo/sender/recipient information. Repeat this test the next time the client connects.
- drop: Drop the connection immediately with a 521 SMTP reply. Repeat this test the next time the client connects.
In the end I think we could drop postgrey support. Postscreen replaces postgrey in its entirety, while being more selective and not delaying mail. Especially if we consider using the deep inspection options of postscreen.
Hope that wasn't too much to read! ;)
* main.cf got misformatted..
Don't know how, should be ok now.
* fixed malformatted main.cf & repaired master.cf
* reenabled rbl stuff.. It's cached, therefore doesn't hurt
* fixed tests
* added tests, repaired tests, added info, introduced new Variable POSTSCREEN_ACTION, fixes
2018-02-04 20:31:08 +00:00
_register_setup_function "_setup_postfix_postscreen"
2018-10-15 19:17:45 +00:00
_register_setup_function "_setup_postfix_sizelimits"
2018-03-07 18:33:43 +00:00
if [ " $SPOOF_PROTECTION " = 1 ] ; then
_register_setup_function "_setup_spoof_protection"
fi
2018-03-18 19:15:06 +00:00
if [ " $ENABLE_SRS " = 1 ] ; then
_register_setup_function "_setup_SRS"
_register_start_daemon "_start_daemons_postsrsd"
fi
2018-02-18 12:29:43 +00:00
_register_setup_function "_setup_postfix_access_control"
2016-12-23 22:56:39 +00:00
if [ ! -z " $AWS_SES_HOST " -a ! -z " $AWS_SES_USERPASS " ] ; then
2018-04-02 08:45:58 +00:00
_register_setup_function "_setup_postfix_relay_hosts"
fi
2019-01-19 10:10:31 +00:00
if [ ! -z " $DEFAULT_RELAY_HOST " ] ; then
_register_setup_function "_setup_postfix_default_relay_host"
fi
2018-04-02 08:45:58 +00:00
if [ ! -z " $RELAY_HOST " ] ; then
_register_setup_function "_setup_postfix_relay_hosts"
2016-12-23 22:56:39 +00:00
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
2018-03-07 18:33:43 +00:00
_register_setup_function "_setup_environment"
2018-03-18 18:52:28 +00:00
_register_setup_function "_setup_logrotate"
if [ " $REPORT_RECIPIENT " != 0 ] ; then
_register_setup_function "_setup_mail_summary"
fi
2017-03-14 14:22:19 +00:00
2019-08-01 10:05:48 +00:00
# Compute last as the config files are modified in-place
_register_setup_function "_setup_chksum_file"
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"
2017-07-23 19:31:41 +00:00
if [ " $ENABLE_CLAMAV " = 0 ] ; then
_register_fix_function "_fix_cleanup_clamav"
fi
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-10-10 06:15:18 +00:00
# Change detector
if [ " $ENABLE_LDAP " = 0 ] ; then
_register_start_daemon "_start_changedetector"
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
2018-11-11 19:46:53 +00:00
notify 'inf' " Domain has been set to $DOMAINNAME "
notify 'inf' " Hostname has been set to $HOSTNAME "
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"
2018-11-04 19:23:50 +00:00
kill ` cat /var/run/supervisord.pid` && return 1
2017-02-07 19:53:34 +00:00
else
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 ] "
2018-04-05 17:04:55 +00:00
# update POSTMASTER_ADDRESS - must be done done after _check_hostname()
DEFAULT_VARS[ "POSTMASTER_ADDRESS" ] = " ${ POSTMASTER_ADDRESS : =postmaster@ ${ DOMAINNAME } } "
2018-05-01 17:57:31 +00:00
# update REPORT_SENDER - must be done done after _check_hostname()
DEFAULT_VARS[ "REPORT_SENDER" ] = " ${ REPORT_SENDER : =mailserver-report@ ${ HOSTNAME } } "
2018-04-05 17:04:55 +00:00
2016-12-01 14:45:40 +00:00
for var in ${ !DEFAULT_VARS[@] } ; do
2018-10-14 08:07:05 +00:00
echo " export $var =\" ${ DEFAULT_VARS [ $var ] } \" " >> /root/.bashrc
2017-08-07 15:39:40 +00:00
[ $? != 0 ] && notify 'err' " Unable to set $var = ${ DEFAULT_VARS [ $var ] } " && kill -15 ` cat /var/run/supervisord.pid` && 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
}
2019-08-01 07:58:22 +00:00
function _setup_chksum_file( ) {
notify 'task' "Setting up configuration checksum file"
if [ -d /tmp/docker-mailserver ] ; then
pushd /tmp/docker-mailserver
declare -a cf_files = ( )
for file in postfix-accounts.cf postfix-virtual.cf postfix-aliases.cf; do
[ -f " $file " ] && cf_files += ( " $file " )
done
notify 'inf' " Creating $CHKSUM_FILE "
sha512sum ${ cf_files [@]/#/--tag } >$CHKSUM_FILE
popd
else
# We could just skip the file, but perhaps config can be added later?
# If so it must be processed by the check for changes script
notify 'inf' " Creating empty $CHKSUM_FILE (no config) "
touch $CHKSUM_FILE
fi
}
2016-12-01 14:45:40 +00:00
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
2018-02-27 19:44:45 +00:00
sed -i 's/^postmaster_address = .*$/postmaster_address = ' $POSTMASTER_ADDRESS '/g' /etc/dovecot/conf.d/15-lda.conf
2016-12-01 14:45:40 +00:00
# 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
2017-05-10 07:54:02 +00:00
# Copy pipe and filter programs, if any
rm -f /usr/lib/dovecot/sieve-filter/*
rm -f /usr/lib/dovecot/sieve-pipe/*
2018-04-05 16:54:01 +00:00
[ -d /tmp/docker-mailserver/sieve-filter ] && cp /tmp/docker-mailserver/sieve-filter/* /usr/lib/dovecot/sieve-filter/
[ -d /tmp/docker-mailserver/sieve-pipe ] && cp /tmp/docker-mailserver/sieve-pipe/* /usr/lib/dovecot/sieve-pipe/
if [ -f /tmp/docker-mailserver/before.dovecot.sieve ] ; then
sed -i "s/#sieve_before =/sieve_before =/" /etc/dovecot/conf.d/90-sieve.conf
cp /tmp/docker-mailserver/before.dovecot.sieve /usr/lib/dovecot/sieve-global/
sievec /usr/lib/dovecot/sieve-global/before.dovecot.sieve
else
sed -i "s/ sieve_before =/ #sieve_before =/" /etc/dovecot/conf.d/90-sieve.conf
2017-05-10 07:54:02 +00:00
fi
2018-04-05 16:54:01 +00:00
if [ -f /tmp/docker-mailserver/after.dovecot.sieve ] ; then
sed -i "s/#sieve_after =/sieve_after =/" /etc/dovecot/conf.d/90-sieve.conf
cp /tmp/docker-mailserver/after.dovecot.sieve /usr/lib/dovecot/sieve-global/
sievec /usr/lib/dovecot/sieve-global/after.dovecot.sieve
else
sed -i "s/ sieve_after =/ #sieve_after =/" /etc/dovecot/conf.d/90-sieve.conf
2017-05-10 07:54:02 +00:00
fi
2018-04-05 16:54:01 +00:00
chown docker:docker -R /usr/lib/dovecot/sieve*
chmod 550 -R /usr/lib/dovecot/sieve*
2016-12-01 14:45:40 +00:00
}
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
2017-05-22 07:28:32 +00:00
notify 'inf' "'config/docker-mailserver/postfix-accounts.cf' is not provided. No mail account created."
2016-12-01 14:45:40 +00:00
fi
2017-05-22 07:28:32 +00:00
if [ [ ! $( grep '@' /tmp/docker-mailserver/postfix-accounts.cf | grep '|' ) ] ] ; then
if [ $ENABLE_LDAP -eq 0 ] ; then
notify 'fatal' "Unless using LDAP, you need at least 1 email account to start the server."
defunc
fi
fi
2016-12-01 14:45:40 +00:00
}
function _setup_ldap( ) {
notify 'task' 'Setting up Ldap'
2017-04-26 12:56:09 +00:00
notify 'inf' 'Checking for custom configs'
# cp config files if in place
2017-08-19 08:32:00 +00:00
for i in 'users' 'groups' 'aliases' 'domains' ; do
2017-04-26 12:56:09 +00:00
fpath = " /tmp/docker-mailserver/ldap- ${ i } .cf "
if [ -f $fpath ] ; then
2017-07-03 11:16:16 +00:00
cp ${ fpath } /etc/postfix/ldap-${ i } .cf
2017-04-26 12:56:09 +00:00
fi
2016-12-01 14:45:40 +00:00
done
2017-04-26 12:56:09 +00:00
notify 'inf' 'Starting to override configs'
2018-03-07 18:33:43 +00:00
for f in /etc/postfix/ldap-users.cf /etc/postfix/ldap-groups.cf /etc/postfix/ldap-aliases.cf /etc/postfix/ldap-domains.cf /etc/postfix/maps/sender_login_maps.ldap
2017-07-03 11:16:16 +00:00
do
[ [ $f = ~ ldap-user ] ] && export LDAP_QUERY_FILTER = " ${ LDAP_QUERY_FILTER_USER } "
[ [ $f = ~ ldap-group ] ] && export LDAP_QUERY_FILTER = " ${ LDAP_QUERY_FILTER_GROUP } "
[ [ $f = ~ ldap-aliases ] ] && export LDAP_QUERY_FILTER = " ${ LDAP_QUERY_FILTER_ALIAS } "
2017-08-19 08:32:00 +00:00
[ [ $f = ~ ldap-domains ] ] && export LDAP_QUERY_FILTER = " ${ LDAP_QUERY_FILTER_DOMAIN } "
2017-07-09 22:11:00 +00:00
configomat.sh "LDAP_" " ${ f } "
2017-07-03 11:16:16 +00:00
done
notify 'inf' "Configuring dovecot LDAP"
declare -A _dovecot_ldap_mapping
_dovecot_ldap_mapping[ "DOVECOT_BASE" ] = " ${ DOVECOT_BASE : = " ${ LDAP_SEARCH_BASE } " } "
_dovecot_ldap_mapping[ "DOVECOT_DN" ] = " ${ DOVECOT_DN : = " ${ LDAP_BIND_DN } " } "
_dovecot_ldap_mapping[ "DOVECOT_DNPASS" ] = " ${ DOVECOT_DNPASS : = " ${ LDAP_BIND_PW } " } "
_dovecot_ldap_mapping[ "DOVECOT_HOSTS" ] = " ${ DOVECOT_HOSTS : = " ${ LDAP_SERVER_HOST } " } "
# Not sure whether this can be the same or not
# _dovecot_ldap_mapping["DOVECOT_PASS_FILTER"]="${DOVECOT_PASS_FILTER:="${LDAP_QUERY_FILTER_USER}"}"
# _dovecot_ldap_mapping["DOVECOT_USER_FILTER"]="${DOVECOT_USER_FILTER:="${LDAP_QUERY_FILTER_USER}"}"
for var in ${ !_dovecot_ldap_mapping[@] } ; do
export $var = ${ _dovecot_ldap_mapping [ $var ] }
done
2017-07-09 22:11:00 +00:00
configomat.sh "DOVECOT_" "/etc/dovecot/dovecot-ldap.conf.ext"
2017-07-03 11:16:16 +00:00
2016-12-01 14:45:40 +00:00
# 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
2017-08-19 08:32:00 +00:00
[ -f /etc/postfix/ldap-domains.cf ] && \
postconf -e "virtual_mailbox_domains = /etc/postfix/vhost, ldap:/etc/postfix/ldap-domains.cf" || \
notify 'inf' "==> Warning: /etc/postfix/ldap-domains.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"
2018-02-18 09:37:31 +00:00
sed -i -e 's/, reject_rbl_client bl.spamcop.net$/, reject_rbl_client bl.spamcop.net, check_policy_service inet:127.0.0.1:10023/' /etc/postfix/main.cf
2018-11-01 18:32:36 +00:00
sed -i -e " s/\"--inet=127.0.0.1:10023\"/\"--inet=127.0.0.1:10023 --delay= $POSTGREY_DELAY --max-age= $POSTGREY_MAX_AGE --auto-whitelist-clients= $POSTGREY_AUTO_WHITELIST_CLIENTS \"/ " /etc/default/postgrey
2017-02-06 09:21:18 +00:00
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-05-10 07:42:44 +00:00
if [ -f /tmp/docker-mailserver/whitelist_clients.local ] ; then
cp -f /tmp/docker-mailserver/whitelist_clients.local /etc/postgrey/whitelist_clients.local
fi
2018-11-01 18:32:36 +00:00
if [ -f /tmp/docker-mailserver/whitelist_recipients ] ; then
cp -f /tmp/docker-mailserver/whitelist_recipients /etc/postgrey/whitelist_recipients
fi
2017-02-06 09:21:18 +00:00
}
Introducing Postscreen (#799)
* Introduced Postscreen
cheaper, earlier and simpler blocking of zombies/spambots.
From http://postfix.cs.utah.edu/POSTSCREEN_README.html :
As a first layer, postscreen(8) blocks connections from zombies and other spambots that are responsible for about 90% of all spam. It is implemented as a single process to make this defense as cheap as possible.
Things we need to consider:
- Do we need a whitelist/backlist file? (http://postfix.cs.utah.edu/postconf.5.html#postscreen_access_list)
- Via introducing an optional config/postfix-access.cidr
- The only permanent whitelisting I could imagine are monitoring services(which might (still?) behave weird/hastely) or blacklisting backup servers(since no traffic should be coming from them anyway)
- Do we need deep inspections? They are desireable, but these tests are expensive: a good client must disconnect after it passes the test, before it can talk to a real Postfix SMTP server. Considered tests are:
- postscreen_bare_newline_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_bare_newline_action)
- postscreen_non_smtp_command_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_non_smtp_command_action)
- postscreen_pipelining_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_pipelining_action)
- Do we need to make the blacklisting via dnsblocking configurable? It's currently set and weighted as follows, where a score of 3 results in blocking, a score of -1 results in whitelisting:
(*: adds the specified weight to the SMTP client's DNSBL score. Specify a negative number for whitelisting.)
(http://postfix.cs.utah.edu/postconf.5.html#postscreen_dnsbl_sites)
- zen.spamhaus.org*3
- bl.mailspike.net
- b.barracudacentral.org*2
- bl.spameatingmonkey.net
- bl.spamcop.net
- dnsbl.sorbs.net
- psbl.surriel.com
- list.dnswl.org=127.0.[0..255].0*-2
- list.dnswl.org=127.0.[0..255].1*-3
- list.dnswl.org=127.0.[0..255].[2..3]*-4
- What to do when blacklisting? I currently set it to drop. We could
- ignore: Ignore the failure of this test. Allow other tests to complete. Repeat this test the next time the client connects. This option is useful for testing and collecting statistics without blocking mail.
- enforce: Allow other tests to complete. Reject attempts to deliver mail with a 550 SMTP reply, and log the helo/sender/recipient information. Repeat this test the next time the client connects.
- drop: Drop the connection immediately with a 521 SMTP reply. Repeat this test the next time the client connects.
In the end I think we could drop postgrey support. Postscreen replaces postgrey in its entirety, while being more selective and not delaying mail. Especially if we consider using the deep inspection options of postscreen.
Hope that wasn't too much to read! ;)
* main.cf got misformatted..
Don't know how, should be ok now.
* fixed malformatted main.cf & repaired master.cf
* reenabled rbl stuff.. It's cached, therefore doesn't hurt
* fixed tests
* added tests, repaired tests, added info, introduced new Variable POSTSCREEN_ACTION, fixes
2018-02-04 20:31:08 +00:00
function _setup_postfix_postscreen( ) {
notify 'inf' "Configuring postscreen"
sed -i -e " s/postscreen_dnsbl_action = enforce/postscreen_dnsbl_action = $POSTSCREEN_ACTION / " \
-e " s/postscreen_greet_action = enforce/postscreen_greet_action = $POSTSCREEN_ACTION / " \
2018-02-18 09:37:31 +00:00
-e " s/postscreen_bare_newline_action = enforce/postscreen_bare_newline_action = $POSTSCREEN_ACTION / " /etc/postfix/main.cf
Introducing Postscreen (#799)
* Introduced Postscreen
cheaper, earlier and simpler blocking of zombies/spambots.
From http://postfix.cs.utah.edu/POSTSCREEN_README.html :
As a first layer, postscreen(8) blocks connections from zombies and other spambots that are responsible for about 90% of all spam. It is implemented as a single process to make this defense as cheap as possible.
Things we need to consider:
- Do we need a whitelist/backlist file? (http://postfix.cs.utah.edu/postconf.5.html#postscreen_access_list)
- Via introducing an optional config/postfix-access.cidr
- The only permanent whitelisting I could imagine are monitoring services(which might (still?) behave weird/hastely) or blacklisting backup servers(since no traffic should be coming from them anyway)
- Do we need deep inspections? They are desireable, but these tests are expensive: a good client must disconnect after it passes the test, before it can talk to a real Postfix SMTP server. Considered tests are:
- postscreen_bare_newline_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_bare_newline_action)
- postscreen_non_smtp_command_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_non_smtp_command_action)
- postscreen_pipelining_enable (http://postfix.cs.utah.edu/postconf.5.html#postscreen_pipelining_action)
- Do we need to make the blacklisting via dnsblocking configurable? It's currently set and weighted as follows, where a score of 3 results in blocking, a score of -1 results in whitelisting:
(*: adds the specified weight to the SMTP client's DNSBL score. Specify a negative number for whitelisting.)
(http://postfix.cs.utah.edu/postconf.5.html#postscreen_dnsbl_sites)
- zen.spamhaus.org*3
- bl.mailspike.net
- b.barracudacentral.org*2
- bl.spameatingmonkey.net
- bl.spamcop.net
- dnsbl.sorbs.net
- psbl.surriel.com
- list.dnswl.org=127.0.[0..255].0*-2
- list.dnswl.org=127.0.[0..255].1*-3
- list.dnswl.org=127.0.[0..255].[2..3]*-4
- What to do when blacklisting? I currently set it to drop. We could
- ignore: Ignore the failure of this test. Allow other tests to complete. Repeat this test the next time the client connects. This option is useful for testing and collecting statistics without blocking mail.
- enforce: Allow other tests to complete. Reject attempts to deliver mail with a 550 SMTP reply, and log the helo/sender/recipient information. Repeat this test the next time the client connects.
- drop: Drop the connection immediately with a 521 SMTP reply. Repeat this test the next time the client connects.
In the end I think we could drop postgrey support. Postscreen replaces postgrey in its entirety, while being more selective and not delaying mail. Especially if we consider using the deep inspection options of postscreen.
Hope that wasn't too much to read! ;)
* main.cf got misformatted..
Don't know how, should be ok now.
* fixed malformatted main.cf & repaired master.cf
* reenabled rbl stuff.. It's cached, therefore doesn't hurt
* fixed tests
* added tests, repaired tests, added info, introduced new Variable POSTSCREEN_ACTION, fixes
2018-02-04 20:31:08 +00:00
}
2017-02-06 09:21:18 +00:00
2018-10-15 19:17:45 +00:00
function _setup_postfix_sizelimits( ) {
notify 'inf' "Configuring postfix message size limit"
postconf -e " message_size_limit = ${ DEFAULT_VARS [ "POSTFIX_MESSAGE_SIZE_LIMIT" ] } "
notify 'inf' "Configuring postfix mailbox size limit"
postconf -e " mailbox_size_limit = ${ DEFAULT_VARS [ "POSTFIX_MAILBOX_SIZE_LIMIT" ] } "
}
2018-03-07 18:33:43 +00:00
function _setup_spoof_protection ( ) {
notify 'inf' "Configuring Spoof Protection"
sed -i 's|smtpd_sender_restrictions =|smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch,|' /etc/postfix/main.cf
[ " $ENABLE_LDAP " = 1 ] \
&& postconf -e "smtpd_sender_login_maps=ldap:/etc/postfix/ldap-users.cf ldap:/etc/postfix/ldap-aliases.cf ldap:/etc/postfix/ldap-groups.cf" \
2018-09-12 16:55:13 +00:00
|| postconf -e "smtpd_sender_login_maps=texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/regexp, pcre:/etc/postfix/maps/sender_login_maps.pcre"
2018-03-07 18:33:43 +00:00
}
2018-02-18 12:29:43 +00:00
function _setup_postfix_access_control( ) {
notify 'inf' "Configuring user access"
[ -f /tmp/docker-mailserver/postfix-send-access.cf ] && sed -i 's|smtpd_sender_restrictions =|smtpd_sender_restrictions = check_sender_access texthash:/tmp/docker-mailserver/postfix-send-access.cf,|' /etc/postfix/main.cf
[ -f /tmp/docker-mailserver/postfix-receive-access.cf ] && sed -i 's|smtpd_recipient_restrictions =|smtpd_recipient_restrictions = check_recipient_access texthash:/tmp/docker-mailserver/postfix-receive-access.cf,|' /etc/postfix/main.cf
}
2017-01-03 09:55:03 +00:00
function _setup_postfix_sasl( ) {
2017-04-26 12:56:33 +00:00
if [ [ ${ ENABLE_SASLAUTHD } = = 1 ] ] ; then
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-04-26 12:56:33 +00:00
fi
# cyrus sasl or dovecot sasl
if [ [ ${ ENABLE_SASLAUTHD } = = 1 ] ] || [ [ ${ SMTP_ONLY } = = 0 ] ] ; then
sed -i -e 's|^smtpd_sasl_auth_enable[[:space:]]\+.*|smtpd_sasl_auth_enable = yes|g' /etc/postfix/main.cf
2017-07-03 11:16:16 +00:00
else
2017-04-26 12:56:33 +00:00
sed -i -e 's|^smtpd_sasl_auth_enable[[:space:]]\+.*|smtpd_sasl_auth_enable = no|g' /etc/postfix/main.cf
fi
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://'
2018-06-02 19:16:16 +00:00
[ -z " $SASLAUTHD_LDAP_START_TLS " ] && SASLAUTHD_LDAP_START_TLS = no
[ -z " $SASLAUTHD_LDAP_TLS_CHECK_PEER " ] && SASLAUTHD_LDAP_TLS_CHECK_PEER = no
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 }
2018-06-02 19:16:16 +00:00
ldap_start_tls: $SASLAUTHD_LDAP_START_TLS
ldap_tls_check_peer: $SASLAUTHD_LDAP_TLS_CHECK_PEER
2016-10-30 13:11:36 +00:00
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" \
2017-07-03 11:16:16 +00:00
/etc/postfix/master.cf
2016-12-19 12:39:30 +00:00
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
2018-11-01 19:17:07 +00:00
# fixing old virtual user file
2018-03-14 19:00:38 +00:00
[ [ $( grep " , $" /tmp/docker-mailserver/postfix-virtual.cf) ] ] && sed -i -e "s/, /,/g" -e " s/, $//g " /tmp/docker-mailserver/postfix-virtual.cf
2016-12-01 14:45:40 +00:00
# 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/{
2017-12-07 18:44:45 +00:00
s/ pcre:.*//
s/$/ pcre:\/ etc\/ postfix\/ regexp/
2016-12-01 14:45:40 +00:00
} ' /etc/postfix/main.cf
fi
2018-04-23 18:35:33 +00:00
notify 'inf' "Configuring root alias"
echo " root: ${ POSTMASTER_ADDRESS } " > /etc/aliases
2018-11-01 19:17:07 +00:00
if [ -f /tmp/docker-mailserver/postfix-aliases.cf ] ; then
cat /tmp/docker-mailserver/postfix-aliases.cf>>/etc/aliases
else
notify 'inf' "'config/postfix-aliases.cf' is not provided and will be auto created."
echo -n >/tmp/docker-mailserver/postfix-aliases.cf
fi
2018-04-23 18:35:33 +00:00
postalias /etc/aliases
2016-12-01 14:45:40 +00:00
}
2018-03-18 19:15:06 +00:00
function _setup_SRS( ) {
notify 'task' 'Setting up SRS'
postconf -e "sender_canonical_maps = tcp:localhost:10001"
postconf -e "sender_canonical_classes = envelope_sender"
postconf -e "recipient_canonical_maps = tcp:localhost:10002"
postconf -e "recipient_canonical_classes = envelope_recipient,header_recipient"
}
2016-12-01 14:45:40 +00:00
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."
2017-06-07 13:35:42 +00:00
2018-11-01 19:17:07 +00:00
local _f_keytable = "/etc/opendkim/KeyTable"
[ ! -f " $_f_keytable " ] && touch " $_f_keytable "
2016-12-01 14:45:40 +00:00
fi
2019-08-03 05:26:44 +00:00
# Setup nameservers paramater from /etc/resolv.conf if not defined
if ! grep '^Nameservers' /etc/opendkim.conf; then
echo " Nameservers $( grep '^nameserver' /etc/resolv.conf | awk -F " " '{print $2}' ) " >> /etc/opendkim.conf
notify 'inf' "Nameservers added to /etc/opendkim.conf"
fi
2016-12-01 14:45:40 +00:00
}
function _setup_ssl( ) {
notify 'task' 'Setting up SSL'
2018-02-22 07:36:12 +00:00
# TLS strength/level configuration
case $TLS_LEVEL in
"modern" )
# Postfix configuration
2018-03-26 18:50:28 +00:00
sed -i -r 's/^smtpd_tls_mandatory_protocols =.*$/smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1/' /etc/postfix/main.cf
sed -i -r 's/^smtpd_tls_protocols =.*$/smtpd_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1/' /etc/postfix/main.cf
sed -i -r 's/^smtp_tls_protocols =.*$/smtp_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1/' /etc/postfix/main.cf
sed -i -r 's/^tls_high_cipherlist =.*$/tls_high_cipherlist = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256/' /etc/postfix/main.cf
2018-02-22 07:36:12 +00:00
# Dovecot configuration
2018-03-26 18:50:28 +00:00
sed -i -r 's/^ssl_protocols =.*$/ssl_protocols = !SSLv3,!TLSv1,!TLSv1.1/' /etc/dovecot/conf.d/10-ssl.conf
sed -i -r 's/^ssl_cipher_list =.*$/ssl_cipher_list = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256/' /etc/dovecot/conf.d/10-ssl.conf
2018-02-22 07:36:12 +00:00
notify 'inf' "TLS configured with 'modern' ciphers"
; ;
"intermediate" )
# Postfix configuration
2018-03-26 18:50:28 +00:00
sed -i -r 's/^smtpd_tls_mandatory_protocols =.*$/smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3/' /etc/postfix/main.cf
sed -i -r 's/^smtpd_tls_protocols =.*$/smtpd_tls_protocols = !SSLv2,!SSLv3/' /etc/postfix/main.cf
sed -i -r 's/^smtp_tls_protocols =.*$/smtp_tls_protocols = !SSLv2,!SSLv3/' /etc/postfix/main.cf
sed -i -r 's/^tls_high_cipherlist =.*$/tls_high_cipherlist = ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS/' /etc/postfix/main.cf
2018-02-22 07:36:12 +00:00
# Dovecot configuration
sed -i -r 's/^ssl_protocols = .*$/ssl_protocols = !SSLv3/' /etc/dovecot/conf.d/10-ssl.conf
sed -i -r 's/^ssl_cipher_list = .*$/ssl_cipher_list = ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS/' /etc/dovecot/conf.d/10-ssl.conf
notify 'inf' "TLS configured with 'intermediate' ciphers"
; ;
esac
# SSL certificate Configuration
2016-12-01 14:45:40 +00:00
case $SSL_TYPE in
"letsencrypt" )
# letsencrypt folders and files mounted in /etc/letsencrypt
2018-03-07 19:21:46 +00:00
if [ -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"
2018-03-15 07:01:44 +00:00
else
notify 'err' "Cannot access '/etc/letsencrypt/live/" $HOSTNAME "/privkey.pem' nor 'key.pem'"
2016-12-01 14:45:40 +00:00
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
2018-02-04 20:27:47 +00:00
sed -i -e 's~ssl_cert = </etc/dovecot/ssl/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/ssl/dovecot\.key~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"
2018-03-15 07:01:44 +00:00
else
notify 'err' "Key filename not set!"
2016-12-01 14:45:40 +00:00
fi
2018-03-15 07:01:44 +00:00
else
notify 'err' "Cannot access '/etc/letsencrypt/live/" $HOSTNAME "/fullchain.pem'"
2016-12-01 14:45:40 +00:00
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
2018-02-04 20:27:47 +00:00
sed -i -e 's~ssl_cert = </etc/dovecot/ssl/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/ssl/dovecot\.key~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
2018-02-04 20:27:47 +00:00
sed -i -e 's~ssl_cert = </etc/dovecot/ssl/dovecot\.pem~ssl_cert = </etc/postfix/ssl/cert~g' /etc/dovecot/conf.d/10-ssl.conf
sed -i -e 's~ssl_key = </etc/dovecot/ssl/dovecot\.key~ssl_key = </etc/postfix/ssl/key~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 '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
2018-02-04 20:27:47 +00:00
sed -i -e 's~ssl_cert = </etc/dovecot/ssl/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/ssl/dovecot\.key~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
; ;
2018-12-02 11:59:16 +00:00
'' )
# $SSL_TYPE=empty, no SSL certificate, plain text access
# Dovecot configuration
sed -i -e 's~#disable_plaintext_auth = yes~disable_plaintext_auth = no~g' /etc/dovecot/conf.d/10-auth.conf
sed -i -e 's~ssl = required~ssl = yes~g' /etc/dovecot/conf.d/10-ssl.conf
notify 'inf' "SSL configured with plain text access"
; ;
* )
# Unknown option, default behavior, no action is required
notify 'warn' "SSL configured by default"
; ;
2016-12-01 14:45:40 +00:00
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 "
2019-08-02 13:05:00 +00:00
container_networks = $( ip -o -4 addr show type veth | egrep -o '[0-9\.]+/[0-9]+' )
2016-12-01 14:45:40 +00:00
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
; ;
2019-08-02 13:05:00 +00:00
"connected-networks" )
for network in $container_networks ; do
2019-08-07 00:24:56 +00:00
network = $( _sanitize_ipv4_to_subnet_cidr $network )
2019-08-02 13:05:00 +00:00
notify 'inf' " Adding docker network $network in my networks "
postconf -e " $( postconf | grep '^mynetworks =' ) $network "
echo $network >> /etc/opendmarc/ignore.hosts
echo $network >> /etc/opendkim/TrustedHosts
done
; ;
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. " && \
2017-08-07 15:39:40 +00:00
kill -15 ` cat /var/run/supervisord.pid` && 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
2017-06-13 11:20:25 +00:00
if [ -f /tmp/docker-mailserver/postfix-master.cf ] ; then
while read line; do
2019-07-24 13:11:00 +00:00
if [ [ " $line " = ~ ^[ 0-9a-z] ] ] ; then
2017-06-13 11:20:25 +00:00
postconf -P " $line "
fi
done < /tmp/docker-mailserver/postfix-master.cf
notify 'inf' "Loaded 'config/postfix-master.cf'"
else
notify 'inf' "No extra postfix settings loaded because optional '/tmp/docker-mailserver/postfix-master.cf' not provided."
fi
2017-08-09 21:19:00 +00:00
notify 'inf' "set the compatibility level to 2"
postconf compatibility_level = 2
2016-12-01 14:45:40 +00:00
}
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
}
2019-01-19 10:10:31 +00:00
function _setup_postfix_default_relay_host( ) {
notify 'task' 'Applying default relay host to Postfix'
notify 'inf' " Applying default relay host $DEFAULT_RELAY_HOST to /etc/postfix/main.cf "
postconf -e " relayhost = $DEFAULT_RELAY_HOST "
}
2018-04-02 08:45:58 +00:00
function _setup_postfix_relay_hosts( ) {
notify 'task' 'Setting up Postfix Relay Hosts'
# copy old AWS_SES variables to new variables
if [ -z " $RELAY_HOST " ] ; then
if [ ! -z " $AWS_SES_HOST " ] ; then
notify 'inf' "Using deprecated AWS_SES environment variables"
RELAY_HOST = $AWS_SES_HOST
fi
fi
if [ -z " $RELAY_PORT " ] ; then
if [ -z " $AWS_SES_PORT " ] ; then
RELAY_PORT = 25
else
RELAY_PORT = $AWS_SES_PORT
fi
fi
if [ -z " $RELAY_USER " ] ; then
if [ ! -z " $AWS_SES_USERPASS " ] ; then
# NB this will fail if the password contains a colon!
RELAY_USER = $( echo " $AWS_SES_USERPASS " | cut -f 1 -d ":" )
RELAY_PASSWORD = $( echo " $AWS_SES_USERPASS " | cut -f 2 -d ":" )
fi
fi
notify 'inf' " Setting up outgoing email relaying via $RELAY_HOST : $RELAY_PORT "
# setup /etc/postfix/sasl_passwd
# --
# @domain1.com postmaster@domain1.com:your-password-1
# @domain2.com postmaster@domain2.com:your-password-2
# @domain3.com postmaster@domain3.com:your-password-3
#
# [smtp.mailgun.org]:587 postmaster@domain2.com:your-password-2
if [ -f /tmp/docker-mailserver/postfix-sasl-password.cf ] ; then
notify 'inf' "Adding relay authentication from postfix-sasl-password.cf"
while read line; do
if ! echo " $line " | grep -q -e "\s*#" ; then
echo " $line " >> /etc/postfix/sasl_passwd
fi
done < /tmp/docker-mailserver/postfix-sasl-password.cf
2016-12-01 14:45:40 +00:00
fi
2018-04-02 08:45:58 +00:00
# add default relay
if [ ! -z " $RELAY_USER " ] && [ ! -z " $RELAY_PASSWORD " ] ; then
echo " [ $RELAY_HOST ]: $RELAY_PORT $RELAY_USER : $RELAY_PASSWORD " >> /etc/postfix/sasl_passwd
else
if [ ! -f /tmp/docker-mailserver/postfix-sasl-password.cf ] ; then
notify 'warn' "No relay auth file found and no default set"
fi
fi
2018-04-23 18:42:47 +00:00
if [ -f /etc/postfix/sasl_passwd ] ; then
chown root:root /etc/postfix/sasl_passwd
chmod 0600 /etc/postfix/sasl_passwd
fi
2018-04-02 08:45:58 +00:00
# end /etc/postfix/sasl_passwd
# setup /etc/postfix/relayhost_map
# --
# @domain1.com [smtp.mailgun.org]:587
# @domain2.com [smtp.mailgun.org]:587
# @domain3.com [smtp.mailgun.org]:587
echo -n > /etc/postfix/relayhost_map
if [ -f /tmp/docker-mailserver/postfix-relaymap.cf ] ; then
notify 'inf' "Adding relay mappings from postfix-relaymap.cf"
while read line; do
if ! echo " $line " | grep -q -e "\s*#" ; then
echo " $line " >> /etc/postfix/relayhost_map
fi
done < /tmp/docker-mailserver/postfix-relaymap.cf
fi
grep -v " ^\s* $\|^\s*\# " /tmp/docker-mailserver/postfix-accounts.cf | while IFS = $'|' read login pass
do
domain = $( echo ${ login } | cut -d @ -f2)
if ! grep -q -e " ^@ ${ domain } \b " /etc/postfix/relayhost_map; then
notify 'inf' " Adding relay mapping for ${ domain } "
echo " @ ${ domain } [ $RELAY_HOST ]: $RELAY_PORT " >> /etc/postfix/relayhost_map
fi
done
# remove lines with no destination
sed -i '/^@\S*\s*$/d' /etc/postfix/relayhost_map
chown root:root /etc/postfix/relayhost_map
chmod 0600 /etc/postfix/relayhost_map
# end /etc/postfix/relayhost_map
2016-12-23 22:56:39 +00:00
postconf -e \
"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" \
2018-04-02 08:45:58 +00:00
"smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt" \
"sender_dependent_relayhost_maps = texthash:/etc/postfix/relayhost_map" \
"smtp_sender_dependent_authentication = yes"
2016-12-01 14:45:40 +00:00
}
2017-09-06 21:41:23 +00:00
function _setup_postfix_dhparam( ) {
notify 'task' 'Setting up Postfix dhparam'
if [ " $ONE_DIR " = 1 ] ; then
DHPARAMS_FILE = /var/mail-state/lib-postfix/dhparams.pem
if [ ! -f $DHPARAMS_FILE ] ; then
notify 'inf' "Generate new dhparams for postfix"
mkdir -p $( dirname " $DHPARAMS_FILE " )
openssl dhparam -out $DHPARAMS_FILE 2048
else
notify 'inf' "Use dhparams that was generated previously"
fi
2019-07-23 14:12:12 +00:00
# Copy from the state directory to the working location
2017-09-06 21:41:23 +00:00
rm /etc/postfix/dhparams.pem && cp $DHPARAMS_FILE /etc/postfix/dhparams.pem
else
notify 'inf' "No state dir, we use the dhparams generated on image creation"
fi
}
2019-07-23 14:12:12 +00:00
function _setup_dovecot_dhparam( ) {
notify 'task' 'Setting up Dovecot dhparam'
if [ " $ONE_DIR " = 1 ] ; then
DHPARAMS_FILE = /var/mail-state/lib-dovecot/dh.pem
if [ ! -f $DHPARAMS_FILE ] ; then
notify 'inf' "Generate new dhparams for dovecot"
mkdir -p $( dirname " $DHPARAMS_FILE " )
openssl dhparam -out $DHPARAMS_FILE 2048
else
notify 'inf' "Use dovecot dhparams that was generated previously"
fi
# Copy from the state directory to the working location
rm /etc/dovecot/dh.pem && cp $DHPARAMS_FILE /etc/dovecot/dh.pem
else
notify 'inf' "No state dir, we use the dovecot dhparams generated on image creation"
fi
}
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
2017-04-18 12:18:42 +00:00
dms_amavis_file = "/etc/amavis/conf.d/61-dms_auto_generated"
2016-12-25 21:54:37 +00:00
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
2018-03-02 21:38:57 +00:00
SA_SPAM_SUBJECT = ${ SA_SPAM_SUBJECT : = "***SPAM*** " }
if [ " $SA_SPAM_SUBJECT " = = "undef" ] ; then
sed -i -r 's/^\$sa_spam_subject_tag (.*);/\$sa_spam_subject_tag = undef;/g' /etc/amavis/conf.d/20-debian_defaults
else
sed -i -r 's/^\$sa_spam_subject_tag (.*);/\$sa_spam_subject_tag = ' " ' $SA_SPAM_SUBJECT ' " ';/g' /etc/amavis/conf.d/20-debian_defaults
fi
2016-12-25 21:54:37 +00:00
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"
2017-12-07 18:27:31 +00:00
test -e /tmp/docker-mailserver/fail2ban-fail2ban.cf && cp /tmp/docker-mailserver/fail2ban-fail2ban.cf /etc/fail2ban/fail2ban.local
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
2018-03-18 18:52:28 +00:00
function _setup_logrotate( ) {
notify 'inf' "Setting up logrotate"
LOGROTATE = "/var/log/mail/mail.log\n{\n compress\n copytruncate\n delaycompress\n"
case " $REPORT_INTERVAL " in
"daily" )
notify 'inf' "Setting postfix summary interval to daily"
LOGROTATE = " $LOGROTATE rotate 1\n daily\n "
; ;
"weekly" )
notify 'inf' "Setting postfix summary interval to weekly"
LOGROTATE = " $LOGROTATE rotate 1\n weekly\n "
; ;
"monthly" )
notify 'inf' "Setting postfix summary interval to monthly"
LOGROTATE = " $LOGROTATE rotate 1\n monthly\n "
; ;
esac
LOGROTATE = " $LOGROTATE } "
echo -e " $LOGROTATE " > /etc/logrotate.d/maillog
}
function _setup_mail_summary( ) {
notify 'inf' " Enable postfix summary with recipient $REPORT_RECIPIENT "
[ " $REPORT_RECIPIENT " = 1 ] && REPORT_RECIPIENT = $POSTMASTER_ADDRESS
2018-05-01 17:57:31 +00:00
sed -i " s|}| postrotate\n /usr/local/bin/postfix-summary $HOSTNAME \
$REPORT_RECIPIENT $REPORT_SENDER \n endscript\n } \n | " /etc/logrotate.d/maillog
2018-03-18 18:52:28 +00:00
}
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
2017-08-24 16:07:20 +00:00
notify 'taskgrg' "Remove leftover pid files from a stop/start"
rm -rf /var/run/*.pid /var/run/*/*.pid
2017-09-10 13:26:21 +00:00
touch /dev/shm/supervisor.sock
2016-12-01 14:45:40 +00:00
}
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-04-26 12:56:09 +00:00
if [ [ " $ONE_DIR " -eq 0 ] ] ; then
2017-02-08 22:31:56 +00:00
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
}
2017-07-23 19:31:41 +00:00
function _fix_cleanup_clamav( ) {
notify 'task' 'Cleaning up disabled Clamav'
rm -f /etc/logrotate.d/clamav-*
2019-07-29 09:15:49 +00:00
rm -f /etc/cron.d/clamav-freshclam
2017-07-23 19:31:41 +00:00
}
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 "
2018-03-09 18:46:49 +00:00
for d in /var/spool/postfix /var/lib/postfix /var/lib/amavis /var/lib/clamav /var/lib/spamassassin /var/lib/fail2ban /var/lib/postgrey /var/lib/dovecot; 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
2017-05-22 07:28:32 +00:00
notify 'inf' 'Fixing /var/mail-state/* permissions'
chown -R clamav /var/mail-state/lib-clamav
chown -R postfix /var/mail-state/lib-postfix
chown -R postgrey /var/mail-state/lib-postgrey
2017-10-08 12:47:45 +00:00
chown -R debian-spamd /var/mail-state/lib-spamassassin
2017-05-22 07:28:32 +00:00
chown -R postfix /var/mail-state/spool-postfix
2016-12-01 14:45:40 +00:00
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-08-07 15:39:40 +00:00
supervisorctl start 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( ) {
2017-08-07 15:39:40 +00:00
notify 'task' 'Starting rsyslog ' 'n'
supervisorctl start rsyslog
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'
2017-08-07 15:39:40 +00:00
supervisorctl start " saslauthd_ ${ SASLAUTHD_MECHANISMS } "
2016-12-01 14:45:40 +00:00
}
function _start_daemons_fail2ban( ) {
2017-08-07 15:39:40 +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
2017-08-07 15:39:40 +00:00
supervisorctl start fail2ban
2016-12-01 14:45:40 +00:00
}
function _start_daemons_opendkim( ) {
2017-08-07 15:39:40 +00:00
notify 'task' 'Starting opendkim ' 'n'
supervisorctl start opendkim
2016-12-01 14:45:40 +00:00
}
function _start_daemons_opendmarc( ) {
2017-08-07 15:39:40 +00:00
notify 'task' 'Starting opendmarc ' 'n'
supervisorctl start opendmarc
2016-12-01 14:45:40 +00:00
}
2018-03-18 19:15:06 +00:00
function _start_daemons_postsrsd( ) {
notify 'task' 'Starting postsrsd ' 'n'
supervisorctl start postsrsd
}
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'
2017-08-07 15:39:40 +00:00
supervisorctl start postfix
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
2017-08-07 15:39:40 +00:00
2016-12-23 22:56:39 +00:00
notify 'task' 'Starting dovecot services' 'n'
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
fi
if [ -f /tmp/docker-mailserver/dovecot.cf ] ; then
cp /tmp/docker-mailserver/dovecot.cf /etc/dovecot/local.conf
fi
2017-08-07 15:39:40 +00:00
supervisorctl start dovecot
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'
2017-08-07 15:39:40 +00:00
supervisorctl start filebeat
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
2017-08-07 15:39:40 +00:00
supervisorctl start fetchmail
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'
2017-08-07 15:39:40 +00:00
supervisorctl start clamav
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'
2017-07-20 08:59:41 +00:00
rm -f /var/run/postgrey/postgrey.pid
2017-08-07 15:39:40 +00:00
supervisorctl start postgrey
2017-02-06 09:21:18 +00:00
}
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'
2017-08-07 15:39:40 +00:00
supervisorctl start amavis
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
##########################################################################
2017-10-10 06:15:18 +00:00
##########################################################################
# Start check for update postfix-accounts and postfix-virtual
##########################################################################
2016-12-01 14:45:40 +00:00
2017-10-10 06:15:18 +00:00
function _start_changedetector( ) {
notify 'task' 'Starting changedetector' 'n'
supervisorctl start changedetector
}
2016-12-01 14:45:40 +00:00
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, unless you exactly know what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# >>
2019-08-07 00:24:56 +00:00
. /usr/local/bin/helper_functions.sh
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' ""
2017-08-07 15:39:40 +00:00
touch /var/log/mail/mail.log
2016-12-23 22:56:39 +00:00
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