docker-mailserver/target/scripts/startup/setup-stack.sh
Brennan Kinney 3d6e7a7bb8
service(postfix): Better handling of the compatibility_level setting (#2597)
* chore: Fix typo

* chore: Apply explicit chroot default for `sender-cleanup`

The implicit default is set to `y` as a compatibility fallback, but otherwise it is [advised to set to `n` going forward](http://www.postfix.org/COMPATIBILITY_README.html#chroot).

Test was changed to catch any backwards-compatibility logs, not just those for `chroot=y`. `using` added as a prefix to avoid catching log message whenever a setting is changed that the default compatibility level is active.

* chore: Set `compatibility_level` in `main.cf`

We retain the level`2` value previously set via scripts. This avoids log noise that isn't helpful.

Applied review feedback to give maintainers some context with this setting and why we have it presently set to `2`.
2022-06-05 12:10:20 +12:00

1236 lines
38 KiB
Bash

#! /bin/bash
function _setup
{
_log 'info' 'Configuring mail server'
for FUNC in "${FUNCS_SETUP[@]}"
do
${FUNC}
done
# All startup modifications to configs should have taken place before calling this:
_prepare_for_change_detection
}
function _setup_supervisor
{
if ! grep -q "loglevel = ${SUPERVISOR_LOGLEVEL}" /etc/supervisor/supervisord.conf
then
case "${SUPERVISOR_LOGLEVEL}" in
( 'critical' | 'error' | 'info' | 'debug' )
sed -i -E \
"s|(loglevel).*|\1 = ${SUPERVISOR_LOGLEVEL}|g" \
/etc/supervisor/supervisord.conf
supervisorctl reload
exit
;;
( 'warn' )
return 0
;;
( * )
_log 'warn' \
"SUPERVISOR_LOGLEVEL '${SUPERVISOR_LOGLEVEL}' unknown. Using default 'warn'"
;;
esac
fi
return 0
}
function _setup_default_vars
{
_log 'debug' 'Setting up default variables'
: >/root/.bashrc # make DMS variables available in login shells and their subprocesses
: >/etc/dms-settings # this file can be sourced by other scripts
local VAR
for VAR in "${!VARS[@]}"
do
echo "export ${VAR}='${VARS[${VAR}]}'" >>/root/.bashrc
echo "${VAR}='${VARS[${VAR}]}'" >>/etc/dms-settings
done
sort -o /root/.bashrc /root/.bashrc
sort -o /etc/dms-settings /etc/dms-settings
}
# File/folder permissions are fine when using docker volumes, but may be wrong
# when file system folders are mounted into the container.
# Set the expected values and create missing folders/files just in case.
function _setup_file_permissions
{
_log 'debug' 'Setting file and directory permissions'
mkdir -p /var/log/supervisor
mkdir -p /var/log/mail
chown syslog:root /var/log/mail
touch /var/log/mail/clamav.log
chown clamav:adm /var/log/mail/clamav.log
chmod 640 /var/log/mail/clamav.log
touch /var/log/mail/freshclam.log
chown clamav:adm /var/log/mail/freshclam.log
chmod 640 /var/log/mail/freshclam.log
}
function _setup_mailname
{
_log 'debug' "Setting up mailname and creating '/etc/mailname'"
echo "${DOMAINNAME}" >/etc/mailname
}
function _setup_amavis
{
if [[ ${ENABLE_AMAVIS} -eq 1 ]]
then
_log 'debug' 'Setting up Amavis'
sed -i \
"s|^#\$myhostname = \"mail.example.com\";|\$myhostname = \"${HOSTNAME}\";|" \
/etc/amavis/conf.d/05-node_id
else
_log 'debug' "Removing Amavis from Postfix's configuration"
sed -i 's|content_filter =.*|content_filter =|' /etc/postfix/main.cf
[[ ${ENABLE_CLAMAV} -eq 1 ]] && _log 'warn' 'ClamAV will not work when Amavis is disabled. Remove ENABLE_AMAVIS=0 from your configuration to fix it.'
[[ ${ENABLE_SPAMASSASSIN} -eq 1 ]] && _log 'warn' 'Spamassassin will not work when Amavis is disabled. Remove ENABLE_AMAVIS=0 from your configuration to fix it.'
fi
}
function _setup_dmarc_hostname
{
_log 'debug' 'Setting up DMARC'
sed -i -e \
"s|^AuthservID.*$|AuthservID ${HOSTNAME}|g" \
-e "s|^TrustedAuthservIDs.*$|TrustedAuthservIDs ${HOSTNAME}|g" \
/etc/opendmarc.conf
}
function _setup_postfix_hostname
{
_log 'debug' 'Applying hostname and domainname to Postfix'
postconf -e "myhostname = ${HOSTNAME}"
postconf -e "mydomain = ${DOMAINNAME}"
}
function _setup_dovecot_hostname
{
_log 'debug' 'Applying hostname to Dovecot'
sed -i \
"s|^#hostname =.*$|hostname = '${HOSTNAME}'|g" \
/etc/dovecot/conf.d/15-lda.conf
}
function _setup_dovecot
{
_log 'debug' '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
sed -i 's|^postmaster_address = .*$|postmaster_address = '"${POSTMASTER_ADDRESS}"'|g' /etc/dovecot/conf.d/15-lda.conf
if ! grep -q -E '^stats_writer_socket_path=' /etc/dovecot/dovecot.conf
then
printf '\n%s\n' 'stats_writer_socket_path=' >>/etc/dovecot/dovecot.conf
fi
# set mail_location according to mailbox format
case "${DOVECOT_MAILBOX_FORMAT}" in
( 'sdbox' | 'mdbox' )
_log 'trace' "Dovecot ${DOVECOT_MAILBOX_FORMAT} format configured"
sed -i -e \
"s|^mail_location = .*$|mail_location = ${DOVECOT_MAILBOX_FORMAT}:\/var\/mail\/%d\/%n|g" \
/etc/dovecot/conf.d/10-mail.conf
_log 'trace' 'Enabling cron job for dbox purge'
mv /etc/cron.d/dovecot-purge.disabled /etc/cron.d/dovecot-purge
chmod 644 /etc/cron.d/dovecot-purge
;;
( * )
_log 'trace' 'Dovecot default format (maildir) configured'
sed -i -e 's|^mail_location = .*$|mail_location = maildir:\/var\/mail\/%d\/%n|g' /etc/dovecot/conf.d/10-mail.conf
;;
esac
# enable Managesieve service by setting the symlink
# to the configuration file Dovecot will actually find
if [[ ${ENABLE_MANAGESIEVE} -eq 1 ]]
then
_log 'trace' 'Sieve management enabled'
mv /etc/dovecot/protocols.d/managesieved.protocol.disab /etc/dovecot/protocols.d/managesieved.protocol
fi
# copy pipe and filter programs, if any
rm -f /usr/lib/dovecot/sieve-filter/*
rm -f /usr/lib/dovecot/sieve-pipe/*
[[ -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/
# create global sieve directories
mkdir -p /usr/lib/dovecot/sieve-global/before
mkdir -p /usr/lib/dovecot/sieve-global/after
if [[ -f /tmp/docker-mailserver/before.dovecot.sieve ]]
then
cp /tmp/docker-mailserver/before.dovecot.sieve /usr/lib/dovecot/sieve-global/before/50-before.dovecot.sieve
sievec /usr/lib/dovecot/sieve-global/before/50-before.dovecot.sieve
else
rm -f /usr/lib/dovecot/sieve-global/before/50-before.dovecot.sieve /usr/lib/dovecot/sieve-global/before/50-before.dovecot.svbin
fi
if [[ -f /tmp/docker-mailserver/after.dovecot.sieve ]]
then
cp /tmp/docker-mailserver/after.dovecot.sieve /usr/lib/dovecot/sieve-global/after/50-after.dovecot.sieve
sievec /usr/lib/dovecot/sieve-global/after/50-after.dovecot.sieve
else
rm -f /usr/lib/dovecot/sieve-global/after/50-after.dovecot.sieve /usr/lib/dovecot/sieve-global/after/50-after.dovecot.svbin
fi
# sieve will move spams to .Junk folder when SPAMASSASSIN_SPAM_TO_INBOX=1 and MOVE_SPAM_TO_JUNK=1
if [[ ${SPAMASSASSIN_SPAM_TO_INBOX} -eq 1 ]] && [[ ${MOVE_SPAM_TO_JUNK} -eq 1 ]]
then
_log 'debug' 'Spam messages will be moved to the Junk folder'
cp /etc/dovecot/sieve/before/60-spam.sieve /usr/lib/dovecot/sieve-global/before/
sievec /usr/lib/dovecot/sieve-global/before/60-spam.sieve
else
rm -f /usr/lib/dovecot/sieve-global/before/60-spam.sieve /usr/lib/dovecot/sieve-global/before/60-spam.svbin
fi
chown docker:docker -R /usr/lib/dovecot/sieve*
chmod 550 -R /usr/lib/dovecot/sieve*
chmod -f +x /usr/lib/dovecot/sieve-pipe/*
}
function _setup_dovecot_quota
{
_log 'debug' 'Setting up Dovecot quota'
# Dovecot quota is disabled when using LDAP or SMTP_ONLY or when explicitly disabled.
if [[ ${ENABLE_LDAP} -eq 1 ]] || [[ ${SMTP_ONLY} -eq 1 ]] || [[ ${ENABLE_QUOTAS} -eq 0 ]]
then
# disable dovecot quota in docevot confs
if [[ -f /etc/dovecot/conf.d/90-quota.conf ]]
then
mv /etc/dovecot/conf.d/90-quota.conf /etc/dovecot/conf.d/90-quota.conf.disab
sed -i \
"s|mail_plugins = \$mail_plugins quota|mail_plugins = \$mail_plugins|g" \
/etc/dovecot/conf.d/10-mail.conf
sed -i \
"s|mail_plugins = \$mail_plugins imap_quota|mail_plugins = \$mail_plugins|g" \
/etc/dovecot/conf.d/20-imap.conf
fi
# disable quota policy check in postfix
sed -i "s|check_policy_service inet:localhost:65265||g" /etc/postfix/main.cf
else
if [[ -f /etc/dovecot/conf.d/90-quota.conf.disab ]]
then
mv /etc/dovecot/conf.d/90-quota.conf.disab /etc/dovecot/conf.d/90-quota.conf
sed -i \
"s|mail_plugins = \$mail_plugins|mail_plugins = \$mail_plugins quota|g" \
/etc/dovecot/conf.d/10-mail.conf
sed -i \
"s|mail_plugins = \$mail_plugin|mail_plugins = \$mail_plugins imap_quota|g" \
/etc/dovecot/conf.d/20-imap.conf
fi
local MESSAGE_SIZE_LIMIT_MB=$((POSTFIX_MESSAGE_SIZE_LIMIT / 1000000))
local MAILBOX_LIMIT_MB=$((POSTFIX_MAILBOX_SIZE_LIMIT / 1000000))
sed -i \
"s|quota_max_mail_size =.*|quota_max_mail_size = ${MESSAGE_SIZE_LIMIT_MB}$([[ ${MESSAGE_SIZE_LIMIT_MB} -eq 0 ]] && echo "" || echo "M")|g" \
/etc/dovecot/conf.d/90-quota.conf
sed -i \
"s|quota_rule = \*:storage=.*|quota_rule = *:storage=${MAILBOX_LIMIT_MB}$([[ ${MAILBOX_LIMIT_MB} -eq 0 ]] && echo "" || echo "M")|g" \
/etc/dovecot/conf.d/90-quota.conf
if [[ -d /tmp/docker-mailserver ]] && [[ ! -f /tmp/docker-mailserver/dovecot-quotas.cf ]]
then
_log 'trace' "'/tmp/docker-mailserver/dovecot-quotas.cf' is not provided. Using default quotas."
: >/tmp/docker-mailserver/dovecot-quotas.cf
fi
# enable quota policy check in postfix
sed -i \
"s|reject_unknown_recipient_domain, reject_rbl_client zen.spamhaus.org|reject_unknown_recipient_domain, check_policy_service inet:localhost:65265, reject_rbl_client zen.spamhaus.org|g" \
/etc/postfix/main.cf
fi
}
function _setup_dovecot_local_user
{
_log 'debug' 'Setting up Dovecot Local User'
_create_accounts
[[ ${ENABLE_LDAP} -eq 1 ]] && return 0
if [[ ! -f /tmp/docker-mailserver/postfix-accounts.cf ]]
then
_log 'trace' "'/tmp/docker-mailserver/postfix-accounts.cf' not provided, no mail account created"
fi
local SLEEP_PERIOD='10'
for (( COUNTER = 11 ; COUNTER >= 0 ; COUNTER-- ))
do
if [[ $(grep -cE '.+@.+\|' /tmp/docker-mailserver/postfix-accounts.cf 2>/dev/null || printf '%s' '0') -ge 1 ]]
then
return 0
else
_log 'warn' "You need at least one email account to start Dovecot ($(( ( COUNTER + 1 ) * SLEEP_PERIOD ))s left for account creation before shutdown)"
sleep "${SLEEP_PERIOD}"
fi
done
_shutdown 'No accounts provided - Dovecot could not be started'
}
function _setup_ldap
{
_log 'debug' 'Setting up LDAP'
_log 'trace' 'Checking for custom configs'
for i in 'users' 'groups' 'aliases' 'domains'
do
local FPATH="/tmp/docker-mailserver/ldap-${i}.cf"
if [[ -f ${FPATH} ]]
then
cp "${FPATH}" "/etc/postfix/ldap-${i}.cf"
fi
done
_log 'trace' 'Starting to override configs'
local FILES=(
/etc/postfix/ldap-users.cf
/etc/postfix/ldap-groups.cf
/etc/postfix/ldap-aliases.cf
/etc/postfix/ldap-domains.cf
/etc/postfix/ldap-senders.cf
/etc/postfix/maps/sender_login_maps.ldap
)
for FILE in "${FILES[@]}"
do
[[ ${FILE} =~ ldap-user ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_USER}"
[[ ${FILE} =~ ldap-group ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_GROUP}"
[[ ${FILE} =~ ldap-aliases ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_ALIAS}"
[[ ${FILE} =~ ldap-domains ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_DOMAIN}"
[[ ${FILE} =~ ldap-senders ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_SENDERS}"
configomat.sh "LDAP_" "${FILE}"
done
_log 'trace' "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_URIS']="${DOVECOT_URIS:="${DOVECOT_HOSTS:="${LDAP_SERVER_HOST}"}"}"
# Add protocol to DOVECOT_URIS so that we can use dovecot's "uris" option:
# https://doc.dovecot.org/configuration_manual/authentication/ldap/
if [[ ${DOVECOT_LDAP_MAPPING["DOVECOT_URIS"]} != *'://'* ]]
then
DOVECOT_LDAP_MAPPING['DOVECOT_URIS']="ldap://${DOVECOT_LDAP_MAPPING["DOVECOT_URIS"]}"
fi
# Default DOVECOT_PASS_FILTER to the same value as DOVECOT_USER_FILTER
DOVECOT_LDAP_MAPPING['DOVECOT_PASS_FILTER']="${DOVECOT_PASS_FILTER:="${DOVECOT_USER_FILTER}"}"
for VAR in "${!DOVECOT_LDAP_MAPPING[@]}"
do
export "${VAR}=${DOVECOT_LDAP_MAPPING[${VAR}]}"
done
configomat.sh "DOVECOT_" "/etc/dovecot/dovecot-ldap.conf.ext"
# add domainname to vhost
echo "${DOMAINNAME}" >>/tmp/vhost.tmp
_log 'trace' 'Enabling Dovecot LDAP authentication'
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
_log 'trace' "Configuring LDAP"
if [[ -f /etc/postfix/ldap-users.cf ]]
then
postconf -e 'virtual_mailbox_maps = ldap:/etc/postfix/ldap-users.cf'
else
_log 'warn' "'/etc/postfix/ldap-users.cf' not found"
fi
if [[ -f /etc/postfix/ldap-domains.cf ]]
then
postconf -e 'virtual_mailbox_domains = /etc/postfix/vhost, ldap:/etc/postfix/ldap-domains.cf'
else
_log 'warn' "'/etc/postfix/ldap-domains.cf' not found"
fi
if [[ -f /etc/postfix/ldap-aliases.cf ]] && [[ -f /etc/postfix/ldap-groups.cf ]]
then
postconf -e 'virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf, ldap:/etc/postfix/ldap-groups.cf'
else
_log 'warn' "'/etc/postfix/ldap-aliases.cf' and / or '/etc/postfix/ldap-groups.cf' not found"
fi
# shellcheck disable=SC2016
sed -i 's|mydestination = \$myhostname, |mydestination = |' /etc/postfix/main.cf
return 0
}
function _setup_postgrey
{
_log 'debug' 'Configuring Postgrey'
sed -i -E \
's|, reject_rbl_client zen.spamhaus.org$|, reject_rbl_client zen.spamhaus.org, check_policy_service inet:127.0.0.1:10023|' \
/etc/postfix/main.cf
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
TEXT_FOUND=$(grep -c -i 'POSTGREY_TEXT' /etc/default/postgrey)
if [[ ${TEXT_FOUND} -eq 0 ]]
then
printf 'POSTGREY_TEXT=\"%s\"\n\n' "${POSTGREY_TEXT}" >>/etc/default/postgrey
fi
if [[ -f /tmp/docker-mailserver/whitelist_clients.local ]]
then
cp -f /tmp/docker-mailserver/whitelist_clients.local /etc/postgrey/whitelist_clients.local
fi
if [[ -f /tmp/docker-mailserver/whitelist_recipients ]]
then
cp -f /tmp/docker-mailserver/whitelist_recipients /etc/postgrey/whitelist_recipients
fi
}
function _setup_postfix_postscreen
{
_log 'debug' '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}|" \
-e "s|postscreen_bare_newline_action = enforce|postscreen_bare_newline_action = ${POSTSCREEN_ACTION}|" /etc/postfix/main.cf
}
function _setup_postfix_sizelimits
{
_log 'trace' "Configuring Postfix message size limit to '${POSTFIX_MESSAGE_SIZE_LIMIT}'"
postconf -e "message_size_limit = ${POSTFIX_MESSAGE_SIZE_LIMIT}"
_log 'trace' "Configuring Postfix mailbox size limit to '${POSTFIX_MAILBOX_SIZE_LIMIT}'"
postconf -e "mailbox_size_limit = ${POSTFIX_MAILBOX_SIZE_LIMIT}"
_log 'trace' "Configuring Postfix virtual mailbox size limit to '${POSTFIX_MAILBOX_SIZE_LIMIT}'"
postconf -e "virtual_mailbox_limit = ${POSTFIX_MAILBOX_SIZE_LIMIT}"
}
function _setup_clamav_sizelimit
{
_log 'trace' "Setting ClamAV message scan size limit to '${CLAMAV_MESSAGE_SIZE_LIMIT}'"
sedfile -i "s/^MaxFileSize.*/MaxFileSize ${CLAMAV_MESSAGE_SIZE_LIMIT}/" /etc/clamav/clamd.conf
}
function _setup_postfix_smtputf8
{
_log 'trace' "Disabling Postfix's smtputf8 support"
postconf -e "smtputf8_enable = no"
}
function _setup_spoof_protection
{
_log 'trace' 'Configuring spoof protection'
sed -i \
's|smtpd_sender_restrictions =|smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch,|' \
/etc/postfix/main.cf
if [[ ${ENABLE_LDAP} -eq 1 ]]
then
if [[ -z ${LDAP_QUERY_FILTER_SENDERS} ]]
then
postconf -e 'smtpd_sender_login_maps = ldap:/etc/postfix/ldap-users.cf ldap:/etc/postfix/ldap-aliases.cf ldap:/etc/postfix/ldap-groups.cf'
else
postconf -e 'smtpd_sender_login_maps = ldap:/etc/postfix/ldap-senders.cf'
fi
else
if [[ -f /etc/postfix/regexp ]]
then
postconf -e 'smtpd_sender_login_maps = unionmap:{ texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre, pcre:/etc/postfix/regexp }'
else
postconf -e 'smtpd_sender_login_maps = texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre'
fi
fi
}
function _setup_postfix_access_control
{
_log 'trace' 'Configuring user access'
if [[ -f /tmp/docker-mailserver/postfix-send-access.cf ]]
then
sed -i 's|smtpd_sender_restrictions =|smtpd_sender_restrictions = check_sender_access texthash:/tmp/docker-mailserver/postfix-send-access.cf,|' /etc/postfix/main.cf
fi
if [[ -f /tmp/docker-mailserver/postfix-receive-access.cf ]]
then
sed -i 's|smtpd_recipient_restrictions =|smtpd_recipient_restrictions = check_recipient_access texthash:/tmp/docker-mailserver/postfix-receive-access.cf,|' /etc/postfix/main.cf
fi
}
function _setup_postfix_sasl
{
if [[ ${ENABLE_SASLAUTHD} -eq 1 ]] && [[ ! -f /etc/postfix/sasl/smtpd.conf ]]
then
cat >/etc/postfix/sasl/smtpd.conf << EOF
pwcheck_method: saslauthd
mech_list: plain login
EOF
fi
if [[ ${ENABLE_SASLAUTHD} -eq 0 ]] && [[ ${SMTP_ONLY} -eq 1 ]]
then
sed -i -E \
's|^smtpd_sasl_auth_enable =.*|smtpd_sasl_auth_enable = no|g' \
/etc/postfix/main.cf
sed -i -E \
's|^ -o smtpd_sasl_auth_enable=.*| -o smtpd_sasl_auth_enable=no|g' \
/etc/postfix/master.cf
fi
}
function _setup_saslauthd
{
_log 'debug' 'Setting up SASLAUTHD'
if [[ ! -f /etc/saslauthd.conf ]]
then
_log 'trace' 'Creating /etc/saslauthd.conf'
cat > /etc/saslauthd.conf << EOF
ldap_servers: ${SASLAUTHD_LDAP_SERVER}
ldap_auth_method: ${SASLAUTHD_LDAP_AUTH_METHOD}
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_start_tls: ${SASLAUTHD_LDAP_START_TLS}
ldap_tls_check_peer: ${SASLAUTHD_LDAP_TLS_CHECK_PEER}
${SASLAUTHD_LDAP_TLS_CACERT_FILE}
${SASLAUTHD_LDAP_TLS_CACERT_DIR}
${SASLAUTHD_LDAP_PASSWORD_ATTR}
${SASLAUTHD_LDAP_MECH}
ldap_referrals: yes
log_level: 10
EOF
fi
sed -i \
-e "/^[^#].*smtpd_sasl_type.*/s/^/#/g" \
-e "/^[^#].*smtpd_sasl_path.*/s/^/#/g" \
/etc/postfix/master.cf
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
}
function _setup_postfix_aliases
{
_log 'debug' 'Setting up Postfix aliases'
_create_aliases
}
function _setup_SRS
{
_log 'debug' 'Setting up SRS'
postconf -e 'sender_canonical_maps = tcp:localhost:10001'
postconf -e "sender_canonical_classes = ${SRS_SENDER_CLASSES}"
postconf -e 'recipient_canonical_maps = tcp:localhost:10002'
postconf -e 'recipient_canonical_classes = envelope_recipient,header_recipient'
}
function _setup_dkim
{
_log 'debug' 'Setting up DKIM'
mkdir -p /etc/opendkim && touch /etc/opendkim/SigningTable
# check if any keys are available
if [[ -e "/tmp/docker-mailserver/opendkim/KeyTable" ]]
then
cp -a /tmp/docker-mailserver/opendkim/* /etc/opendkim/
_log 'trace' "DKIM keys added for: $(ls /etc/opendkim/keys/)"
_log 'trace' "Changing permissions on '/etc/opendkim'"
chown -R opendkim:opendkim /etc/opendkim/
chmod -R 0700 /etc/opendkim/keys/
else
_log 'debug' 'No DKIM key(s) provided - check the documentation on how to get your keys'
[[ ! -f /etc/opendkim/KeyTable ]] && touch /etc/opendkim/KeyTable
fi
# setup nameservers parameter 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}' | paste -sd ',' -)" >>/etc/opendkim.conf
_log 'trace' "Nameservers added to '/etc/opendkim.conf'"
fi
}
function _setup_postfix_vhost
{
_log 'debug' 'Setting up Postfix vhost'
_create_postfix_vhost
}
function _setup_postfix_inet_protocols
{
_log 'trace' 'Setting up POSTFIX_INET_PROTOCOLS option'
postconf -e "inet_protocols = ${POSTFIX_INET_PROTOCOLS}"
}
function _setup_dovecot_inet_protocols
{
local PROTOCOL
_log 'trace' 'Setting up DOVECOT_INET_PROTOCOLS option'
# https://dovecot.org/doc/dovecot-example.conf
if [[ ${DOVECOT_INET_PROTOCOLS} == "ipv4" ]]
then
PROTOCOL='*' # IPv4 only
elif [[ ${DOVECOT_INET_PROTOCOLS} == "ipv6" ]]
then
PROTOCOL='[::]' # IPv6 only
else
# Unknown value, panic.
dms_panic__invalid_value 'DOVECOT_INET_PROTOCOLS' "${DOVECOT_INET_PROTOCOLS}"
fi
sedfile -i "s|^#listen =.*|listen = ${PROTOCOL}|g" /etc/dovecot/dovecot.conf
}
function _setup_docker_permit
{
_log 'debug' 'Setting up PERMIT_DOCKER option'
local CONTAINER_IP CONTAINER_NETWORK
unset CONTAINER_NETWORKS
declare -a CONTAINER_NETWORKS
CONTAINER_IP=$(ip addr show "${NETWORK_INTERFACE}" | \
grep 'inet ' | sed 's|[^0-9\.\/]*||g' | cut -d '/' -f 1)
CONTAINER_NETWORK=$(echo "${CONTAINER_IP}" | cut -d '.' -f1-2).0.0
if [[ -z ${CONTAINER_IP} ]]
then
_log 'error' 'Detecting the container IP address failed'
dms_panic__misconfigured 'NETWORK_INTERFACE' 'Network Setup [docker_permit]'
fi
while read -r IP
do
CONTAINER_NETWORKS+=("${IP}")
done < <(ip -o -4 addr show type veth | grep -E -o '[0-9\.]+/[0-9]+')
case "${PERMIT_DOCKER}" in
( 'none' )
_log 'trace' "Clearing Postfix's 'mynetworks'"
postconf -e "mynetworks ="
;;
( 'connected-networks' )
for NETWORK in "${CONTAINER_NETWORKS[@]}"
do
NETWORK=$(_sanitize_ipv4_to_subnet_cidr "${NETWORK}")
_log 'trace' "Adding Docker network '${NETWORK}' to Postfix's 'mynetworks'"
postconf -e "$(postconf | grep '^mynetworks =') ${NETWORK}"
echo "${NETWORK}" >> /etc/opendmarc/ignore.hosts
echo "${NETWORK}" >> /etc/opendkim/TrustedHosts
done
;;
( 'container' )
_log 'trace' "Adding container IP address to Postfix's 'mynetworks'"
postconf -e "$(postconf | grep '^mynetworks =') ${CONTAINER_IP}/32"
echo "${CONTAINER_IP}/32" >> /etc/opendmarc/ignore.hosts
echo "${CONTAINER_IP}/32" >> /etc/opendkim/TrustedHosts
;;
( 'host' )
_log 'trace' "Adding '${CONTAINER_NETWORK}/16' to Postfix's 'mynetworks'"
postconf -e "$(postconf | grep '^mynetworks =') ${CONTAINER_NETWORK}/16"
echo "${CONTAINER_NETWORK}/16" >> /etc/opendmarc/ignore.hosts
echo "${CONTAINER_NETWORK}/16" >> /etc/opendkim/TrustedHosts
;;
( 'network' )
_log 'trace' "Adding Docker network to Postfix's 'mynetworks'"
postconf -e "$(postconf | grep '^mynetworks =') 172.16.0.0/12"
echo 172.16.0.0/12 >> /etc/opendmarc/ignore.hosts
echo 172.16.0.0/12 >> /etc/opendkim/TrustedHosts
;;
( * )
_log 'warn' "Invalid value for PERMIT_DOCKER: '${PERMIT_DOCKER}'"
_log 'warn' "Clearing Postfix's 'mynetworks'"
postconf -e "mynetworks ="
;;
esac
}
# Requires ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1
function _setup_postfix_virtual_transport
{
_log 'trace' 'Setting up Postfix virtual transport'
if [[ -z ${POSTFIX_DAGENT} ]]
then
dms_panic__no_env 'POSTFIX_DAGENT' 'Postfix Setup [virtual_transport]'
return 1
fi
postconf -e "virtual_transport = ${POSTFIX_DAGENT}"
}
function _setup_postfix_override_configuration
{
_log 'trace' 'Setting up Postfix Override configuration'
if [[ -f /tmp/docker-mailserver/postfix-main.cf ]]
then
while read -r LINE
do
# all valid postfix options start with a lower case letter
# http://www.postfix.org/postconf.5.html
if [[ ${LINE} =~ ^[a-z] ]]
then
postconf -e "${LINE}"
fi
done < /tmp/docker-mailserver/postfix-main.cf
_log 'trace' "Loaded '/tmp/docker-mailserver/postfix-main.cf'"
else
_log 'trace' "No extra Postfix settings loaded because optional '/tmp/docker-mailserver/postfix-main.cf' was not provided"
fi
if [[ -f /tmp/docker-mailserver/postfix-master.cf ]]
then
while read -r LINE
do
if [[ ${LINE} =~ ^[0-9a-z] ]]
then
postconf -P "${LINE}"
fi
done < /tmp/docker-mailserver/postfix-master.cf
_log 'trace' "Loaded '/tmp/docker-mailserver/postfix-master.cf'"
else
_log 'trace' "No extra Postfix settings loaded because optional '/tmp/docker-mailserver/postfix-master.cf' was not provided"
fi
}
function _setup_postfix_sasl_password
{
_log 'debug' 'Setting up Postfix SASL Password'
# support general SASL password
_sasl_passwd_create
if [[ -f /etc/postfix/sasl_passwd ]]
then
_log 'trace' 'Loaded SASL_PASSWD'
else
_log 'debug' "SASL_PASSWD was not provided - '/etc/postfix/sasl_passwd' not created"
fi
}
function _setup_postfix_relay_hosts
{
_setup_relayhost
}
function _setup_postfix_dhparam
{
_setup_dhparam 'Postfix' '/etc/postfix/dhparams.pem'
}
function _setup_dovecot_dhparam
{
_setup_dhparam 'Dovecot' '/etc/dovecot/dh.pem'
}
function _setup_dhparam
{
local DH_SERVICE=$1
local DH_DEST=$2
local DH_CUSTOM='/tmp/docker-mailserver/dhparams.pem'
_log 'debug' "Setting up ${DH_SERVICE} dhparam"
if [[ -f ${DH_CUSTOM} ]]
then # use custom supplied dh params (assumes they're probably insecure)
_log 'trace' "${DH_SERVICE} will use custom provided DH paramters"
_log 'warn' "Using self-generated dhparams is considered insecure - unless you know what you are doing, please remove '${DH_CUSTOM}'"
cp -f "${DH_CUSTOM}" "${DH_DEST}"
else # use official standardized dh params (provided via Dockerfile)
_log 'trace' "${DH_SERVICE} will use official standardized DH parameters (ffdhe4096)."
fi
}
function _setup_security_stack
{
_log 'debug' 'Setting up Security Stack'
# recreate auto-generated file
local DMS_AMAVIS_FILE=/etc/amavis/conf.d/61-dms_auto_generated
echo "# WARNING: this file is auto-generated." >"${DMS_AMAVIS_FILE}"
echo "use strict;" >>"${DMS_AMAVIS_FILE}"
# SpamAssassin
if [[ ${ENABLE_SPAMASSASSIN} -eq 0 ]]
then
_log 'debug' 'SpamAssassin is disabled'
echo "@bypass_spam_checks_maps = (1);" >>"${DMS_AMAVIS_FILE}"
elif [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]]
then
_log 'debug' 'Enabling and configuring SpamAssassin'
# shellcheck disable=SC2016
sed -i -r 's|^\$sa_tag_level_deflt (.*);|\$sa_tag_level_deflt = '"${SA_TAG}"';|g' /etc/amavis/conf.d/20-debian_defaults
# shellcheck disable=SC2016
sed -i -r 's|^\$sa_tag2_level_deflt (.*);|\$sa_tag2_level_deflt = '"${SA_TAG2}"';|g' /etc/amavis/conf.d/20-debian_defaults
# shellcheck disable=SC2016
sed -i -r 's|^\$sa_kill_level_deflt (.*);|\$sa_kill_level_deflt = '"${SA_KILL}"';|g' /etc/amavis/conf.d/20-debian_defaults
if [[ ${SA_SPAM_SUBJECT} == 'undef' ]]
then
# shellcheck disable=SC2016
sed -i -r 's|^\$sa_spam_subject_tag (.*);|\$sa_spam_subject_tag = undef;|g' /etc/amavis/conf.d/20-debian_defaults
else
# shellcheck disable=SC2016
sed -i -r 's|^\$sa_spam_subject_tag (.*);|\$sa_spam_subject_tag = '"'${SA_SPAM_SUBJECT}'"';|g' /etc/amavis/conf.d/20-debian_defaults
fi
# activate short circuits when SA BAYES is certain it has spam or ham.
if [[ ${SA_SHORTCIRCUIT_BAYES_SPAM} -eq 1 ]]
then
# automatically activate the Shortcircuit Plugin
sed -i -r 's|^# loadplugin Mail::SpamAssassin::Plugin::Shortcircuit|loadplugin Mail::SpamAssassin::Plugin::Shortcircuit|g' /etc/spamassassin/v320.pre
sed -i -r 's|^# shortcircuit BAYES_99|shortcircuit BAYES_99|g' /etc/spamassassin/local.cf
fi
if [[ ${SA_SHORTCIRCUIT_BAYES_HAM} -eq 1 ]]
then
# automatically activate the Shortcircuit Plugin
sed -i -r 's|^# loadplugin Mail::SpamAssassin::Plugin::Shortcircuit|loadplugin Mail::SpamAssassin::Plugin::Shortcircuit|g' /etc/spamassassin/v320.pre
sed -i -r 's|^# shortcircuit BAYES_00|shortcircuit BAYES_00|g' /etc/spamassassin/local.cf
fi
if [[ -e /tmp/docker-mailserver/spamassassin-rules.cf ]]
then
cp /tmp/docker-mailserver/spamassassin-rules.cf /etc/spamassassin/
fi
if [[ ${SPAMASSASSIN_SPAM_TO_INBOX} -eq 1 ]]
then
_log 'trace' 'Configuring Spamassassin/Amavis to send SPAM to inbox'
sed -i "s|\$final_spam_destiny.*=.*$|\$final_spam_destiny = D_PASS;|g" /etc/amavis/conf.d/49-docker-mailserver
sed -i "s|\$final_bad_header_destiny.*=.*$|\$final_bad_header_destiny = D_PASS;|g" /etc/amavis/conf.d/49-docker-mailserver
else
_log 'trace' 'Configuring Spamassassin/Amavis to bounce SPAM'
sed -i "s|\$final_spam_destiny.*=.*$|\$final_spam_destiny = D_BOUNCE;|g" /etc/amavis/conf.d/49-docker-mailserver
sed -i "s|\$final_bad_header_destiny.*=.*$|\$final_bad_header_destiny = D_BOUNCE;|g" /etc/amavis/conf.d/49-docker-mailserver
fi
if [[ ${ENABLE_SPAMASSASSIN_KAM} -eq 1 ]]
then
_log 'trace' 'Configuring Spamassassin KAM'
local SPAMASSASSIN_KAM_CRON_FILE=/etc/cron.daily/spamassassin_kam
sa-update --import /etc/spamassassin/kam/kam.sa-channels.mcgrail.com.key
cat >"${SPAMASSASSIN_KAM_CRON_FILE}" <<"EOM"
#! /bin/bash
RESULT=$(sa-update --gpgkey 24C063D8 --channel kam.sa-channels.mcgrail.com 2>&1)
EXIT_CODE=${?}
# see https://spamassassin.apache.org/full/3.1.x/doc/sa-update.html#exit_codes
if [[ ${EXIT_CODE} -ge 4 ]]
then
echo -e "Updating SpamAssassin KAM failed:\n${RESULT}\n" >&2
exit 1
fi
exit 0
EOM
chmod +x "${SPAMASSASSIN_KAM_CRON_FILE}"
fi
fi
# ClamAV
if [[ ${ENABLE_CLAMAV} -eq 0 ]]
then
_log 'debug' 'ClamAV is disabled'
echo '@bypass_virus_checks_maps = (1);' >>"${DMS_AMAVIS_FILE}"
elif [[ ${ENABLE_CLAMAV} -eq 1 ]]
then
_log 'debug' 'Enabling ClamAV'
fi
echo '1; # ensure a defined return' >>"${DMS_AMAVIS_FILE}"
chmod 444 "${DMS_AMAVIS_FILE}"
# Fail2ban
if [[ ${ENABLE_FAIL2BAN} -eq 1 ]]
then
_log 'debug' 'Enabling Fail2Ban'
if [[ -e /tmp/docker-mailserver/fail2ban-fail2ban.cf ]]
then
cp /tmp/docker-mailserver/fail2ban-fail2ban.cf /etc/fail2ban/fail2ban.local
fi
if [[ -e /tmp/docker-mailserver/fail2ban-jail.cf ]]
then
cp /tmp/docker-mailserver/fail2ban-jail.cf /etc/fail2ban/jail.d/user-jail.local
fi
else
# disable logrotate config for fail2ban if not enabled
rm -f /etc/logrotate.d/fail2ban
fi
# fix cron.daily for spamassassin
sed -i \
's|invoke-rc.d spamassassin reload|/etc/init\.d/spamassassin reload|g' \
/etc/cron.daily/spamassassin
# Amavis
if [[ ${ENABLE_AMAVIS} -eq 1 ]]
then
_log 'debug' 'Enabling Amavis'
if [[ -f /tmp/docker-mailserver/amavis.cf ]]
then
cp /tmp/docker-mailserver/amavis.cf /etc/amavis/conf.d/50-user
fi
sed -i -E \
"s|(log_level).*|\1 = ${AMAVIS_LOGLEVEL};|g" \
/etc/amavis/conf.d/49-docker-mailserver
fi
}
function _setup_logrotate
{
_log 'debug' 'Setting up logrotate'
LOGROTATE='/var/log/mail/mail.log\n{\n compress\n copytruncate\n delaycompress\n'
case "${LOGROTATE_INTERVAL}" in
( 'daily' )
_log 'trace' 'Setting postfix logrotate interval to daily'
LOGROTATE="${LOGROTATE} rotate 4\n daily\n"
;;
( 'weekly' )
_log 'trace' 'Setting postfix logrotate interval to weekly'
LOGROTATE="${LOGROTATE} rotate 4\n weekly\n"
;;
( 'monthly' )
_log 'trace' 'Setting postfix logrotate interval to monthly'
LOGROTATE="${LOGROTATE} rotate 4\n monthly\n"
;;
( * )
_log 'warn' 'LOGROTATE_INTERVAL not found in _setup_logrotate'
;;
esac
echo -e "${LOGROTATE}}" >/etc/logrotate.d/maillog
}
function _setup_mail_summary
{
local ENABLED_MESSAGE
ENABLED_MESSAGE="Enabling Postfix log summary reports with recipient '${PFLOGSUMM_RECIPIENT}'"
case "${PFLOGSUMM_TRIGGER}" in
( 'daily_cron' )
_log 'debug' "${ENABLED_MESSAGE}"
_log 'trace' 'Creating daily cron job for pflogsumm report'
cat >/etc/cron.daily/postfix-summary << EOM
#! /bin/bash
/usr/local/bin/report-pflogsumm-yesterday ${HOSTNAME} ${PFLOGSUMM_RECIPIENT} ${PFLOGSUMM_SENDER}
EOM
chmod +x /etc/cron.daily/postfix-summary
;;
( 'logrotate' )
_log 'debug' "${ENABLED_MESSAGE}"
_log 'trace' 'Add postrotate action for pflogsumm report'
sed -i \
"s|}| postrotate\n /usr/local/bin/postfix-summary ${HOSTNAME} ${PFLOGSUMM_RECIPIENT} ${PFLOGSUMM_SENDER}\n endscript\n}\n|" \
/etc/logrotate.d/maillog
;;
( 'none' )
_log 'debug' 'Postfix log summary reports disabled'
;;
( * )
_log 'warn' "Invalid value for PFLOGSUMM_TRIGGER: '${PFLOGSUMM_TRIGGER}'"
;;
esac
}
function _setup_logwatch
{
echo 'LogFile = /var/log/mail/freshclam.log' >>/etc/logwatch/conf/logfiles/clam-update.conf
echo "MailFrom = ${LOGWATCH_SENDER}" >>/etc/logwatch/conf/logwatch.conf
case "${LOGWATCH_INTERVAL}" in
( 'daily' | 'weekly' )
_log 'debug' "Enabling logwatch reports with recipient '${LOGWATCH_RECIPIENT}'"
_log 'trace' "Creating ${LOGWATCH_INTERVAL} cron job for logwatch reports"
local LOGWATCH_FILE INTERVAL
LOGWATCH_FILE="/etc/cron.${LOGWATCH_INTERVAL}/logwatch"
INTERVAL='--range Yesterday'
if [[ ${LOGWATCH_INTERVAL} == 'weekly' ]]
then
INTERVAL="--range 'between -7 days and -1 days'"
fi
cat >"${LOGWATCH_FILE}" << EOM
#! /bin/bash
/usr/sbin/logwatch ${INTERVAL} --hostname ${HOSTNAME} --mailto ${LOGWATCH_RECIPIENT}
EOM
chmod 744 "${LOGWATCH_FILE}"
;;
( 'none' )
_log 'debug' 'Logwatch reports disabled.'
;;
( * )
_log 'warn' "Invalid value for LOGWATCH_INTERVAL: '${LOGWATCH_INTERVAL}'"
;;
esac
}
function _setup_user_patches
{
local USER_PATCHES='/tmp/docker-mailserver/user-patches.sh'
if [[ -f ${USER_PATCHES} ]]
then
_log 'debug' 'Applying user patches'
/bin/bash "${USER_PATCHES}"
else
_log 'trace' "No optional '${USER_PATCHES}' provided"
fi
}
function _setup_fail2ban
{
_log 'debug' 'Setting up Fail2Ban'
if [[ ${FAIL2BAN_BLOCKTYPE} != 'reject' ]]
then
echo -e '[Init]\nblocktype = drop' >/etc/fail2ban/action.d/nftables-common.local
fi
echo '[Definition]' >/etc/fail2ban/filter.d/custom.conf
}
function _setup_dnsbl_disable
{
_log 'debug' 'Disabling postfix DNS block list (zen.spamhaus.org)'
sedfile -i \
'/^smtpd_recipient_restrictions = / s/, reject_rbl_client zen.spamhaus.org//' \
/etc/postfix/main.cf
_log 'debug' 'Disabling postscreen DNS block lists'
postconf -e "postscreen_dnsbl_action = ignore"
postconf -e "postscreen_dnsbl_sites = "
}
function _setup_fetchmail
{
_log 'trace' 'Preparing Fetchmail configuration'
local CONFIGURATION FETCHMAILRC
CONFIGURATION='/tmp/docker-mailserver/fetchmail.cf'
FETCHMAILRC='/etc/fetchmailrc'
if [[ -f ${CONFIGURATION} ]]
then
cat /etc/fetchmailrc_general "${CONFIGURATION}" >"${FETCHMAILRC}"
else
cat /etc/fetchmailrc_general >"${FETCHMAILRC}"
fi
chmod 700 "${FETCHMAILRC}"
chown fetchmail:root "${FETCHMAILRC}"
}
function _setup_fetchmail_parallel
{
_log 'trace' 'Setting up Fetchmail parallel'
mkdir /etc/fetchmailrc.d/
# Split the content of /etc/fetchmailrc into
# smaller fetchmailrc files per server [poll] entries. Each
# separate fetchmailrc file is stored in /etc/fetchmailrc.d
#
# The sole purpose for this is to work around what is known
# as the Fetchmail IMAP idle issue.
function _fetchmailrc_split
{
local FETCHMAILRC='/etc/fetchmailrc'
local FETCHMAILRCD='/etc/fetchmailrc.d'
local DEFAULT_FILE="${FETCHMAILRCD}/defaults"
if [[ ! -r ${FETCHMAILRC} ]]
then
_log 'warn' "File '${FETCHMAILRC}' not found"
return 1
fi
if [[ ! -d ${FETCHMAILRCD} ]]
then
if ! mkdir "${FETCHMAILRCD}"
then
_log 'warn' "Unable to create folder '${FETCHMAILRCD}'"
return 1
fi
fi
local COUNTER=0 SERVER=0
while read -r LINE
do
if [[ ${LINE} =~ poll ]]
then
# If we read "poll" then we reached a new server definition
# We need to create a new file with fetchmail defaults from
# /etc/fetcmailrc
COUNTER=$(( COUNTER + 1 ))
SERVER=1
cat "${DEFAULT_FILE}" >"${FETCHMAILRCD}/fetchmail-${COUNTER}.rc"
echo "${LINE}" >>"${FETCHMAILRCD}/fetchmail-${COUNTER}.rc"
elif [[ ${SERVER} -eq 0 ]]
then
# We have not yet found "poll". Let's assume we are still reading
# the default settings from /etc/fetchmailrc file
echo "${LINE}" >>"${DEFAULT_FILE}"
else
# Just the server settings that need to be added to the specific rc.d file
echo "${LINE}" >>"${FETCHMAILRCD}/fetchmail-${COUNTER}.rc"
fi
# delete commented lines before parsing
done < <(sed '/^[[:space:]]*#/d' "${FETCHMAILRC}")
rm "${DEFAULT_FILE}"
}
_fetchmailrc_split
local COUNTER=0
for RC in /etc/fetchmailrc.d/fetchmail-*.rc
do
COUNTER=$(( COUNTER + 1 ))
cat >"/etc/supervisor/conf.d/fetchmail-${COUNTER}.conf" << EOF
[program:fetchmail-${COUNTER}]
startsecs=0
autostart=false
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
user=fetchmail
command=/usr/bin/fetchmail -f ${RC} -v --nodetach --daemon %(ENV_FETCHMAIL_POLL)s -i /var/lib/fetchmail/.fetchmail-UIDL-cache --pidfile /var/run/fetchmail/%(program_name)s.pid
EOF
chmod 700 "${RC}"
chown fetchmail:root "${RC}"
done
supervisorctl reread
supervisorctl update
}
function _setup_timezone
{
_log 'debug' "Setting timezone to '${TZ}'"
local ZONEINFO_FILE="/usr/share/zoneinfo/${TZ}"
if [[ ! -e ${ZONEINFO_FILE} ]]
then
_log 'warn' "Cannot find timezone '${TZ}'"
return 1
fi
if ln -fs "${ZONEINFO_FILE}" /etc/localtime \
&& dpkg-reconfigure -f noninteractive tzdata &>/dev/null
then
_log 'trace' "Set time zone to '${TZ}'"
else
_log 'warn' "Setting timezone to '${TZ}' failed"
return 1
fi
}