mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2024-01-19 02:48:50 +00:00
change if style (#3361)
This commit is contained in:
parent
0e592aa911
commit
cf74127f78
45
setup.sh
45
setup.sh
|
@ -71,11 +71,9 @@ function _show_local_usage
|
|||
|
||||
function _get_absolute_script_directory
|
||||
{
|
||||
if dirname "$(readlink -f "${0}")" &>/dev/null
|
||||
then
|
||||
if dirname "$(readlink -f "${0}")" &>/dev/null; then
|
||||
DIR=$(dirname "$(readlink -f "${0}")")
|
||||
elif realpath -e -L "${0}" &>/dev/null
|
||||
then
|
||||
elif realpath -e -L "${0}" &>/dev/null; then
|
||||
DIR=$(realpath -e -L "${0}")
|
||||
DIR="${DIR%/setup.sh}"
|
||||
fi
|
||||
|
@ -83,8 +81,7 @@ function _get_absolute_script_directory
|
|||
|
||||
function _set_default_config_path
|
||||
{
|
||||
if [[ -d "${DIR}/config" ]]
|
||||
then
|
||||
if [[ -d "${DIR}/config" ]]; then
|
||||
# legacy path (pre v10.2.0)
|
||||
DEFAULT_CONFIG_PATH="${DIR}/config"
|
||||
else
|
||||
|
@ -94,23 +91,19 @@ function _set_default_config_path
|
|||
|
||||
function _handle_config_path
|
||||
{
|
||||
if [[ -z ${DESIRED_CONFIG_PATH} ]]
|
||||
then
|
||||
if [[ -z ${DESIRED_CONFIG_PATH} ]]; then
|
||||
# no desired config path
|
||||
if [[ -n ${CONTAINER_NAME} ]]
|
||||
then
|
||||
if [[ -n ${CONTAINER_NAME} ]]; then
|
||||
VOLUME=$(${CRI} inspect "${CONTAINER_NAME}" \
|
||||
--format="{{range .Mounts}}{{ println .Source .Destination}}{{end}}" | \
|
||||
grep "${DMS_CONFIG}$" 2>/dev/null || :)
|
||||
fi
|
||||
|
||||
if [[ -n ${VOLUME} ]]
|
||||
then
|
||||
if [[ -n ${VOLUME} ]]; then
|
||||
CONFIG_PATH=$(echo "${VOLUME}" | awk '{print $1}')
|
||||
fi
|
||||
|
||||
if [[ -z ${CONFIG_PATH} ]]
|
||||
then
|
||||
if [[ -z ${CONFIG_PATH} ]]; then
|
||||
CONFIG_PATH=${DEFAULT_CONFIG_PATH}
|
||||
fi
|
||||
else
|
||||
|
@ -121,8 +114,7 @@ function _handle_config_path
|
|||
function _run_in_new_container
|
||||
{
|
||||
# start temporary container with specified image
|
||||
if ! ${CRI} history -q "${IMAGE_NAME}" &>/dev/null
|
||||
then
|
||||
if ! ${CRI} history -q "${IMAGE_NAME}" &>/dev/null; then
|
||||
echo "Image '${IMAGE_NAME}' not found. Pulling ..."
|
||||
${CRI} pull "${IMAGE_NAME}"
|
||||
fi
|
||||
|
@ -151,8 +143,7 @@ function _main
|
|||
( * ) DESIRED_CONFIG_PATH="${DIR}/${OPTARG}" ;;
|
||||
esac
|
||||
|
||||
if [[ ! -d ${DESIRED_CONFIG_PATH} ]]
|
||||
then
|
||||
if [[ ! -d ${DESIRED_CONFIG_PATH} ]]; then
|
||||
echo "Specified directory '${DESIRED_CONFIG_PATH}' doesn't exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
@ -169,14 +160,11 @@ function _main
|
|||
done
|
||||
shift $(( OPTIND - 1 ))
|
||||
|
||||
if command -v docker &>/dev/null
|
||||
then
|
||||
if command -v docker &>/dev/null; then
|
||||
CRI=docker
|
||||
elif command -v podman &>/dev/null
|
||||
then
|
||||
elif command -v podman &>/dev/null; then
|
||||
CRI=podman
|
||||
if ! ${PODMAN_ROOTLESS} && [[ ${EUID} -ne 0 ]]
|
||||
then
|
||||
if ! ${PODMAN_ROOTLESS} && [[ ${EUID} -ne 0 ]]; then
|
||||
read -r -p "You are running Podman in rootless mode. Continue? [Y/n] "
|
||||
[[ -n ${REPLY} ]] && [[ ${REPLY} =~ (n|N) ]] && exit 0
|
||||
fi
|
||||
|
@ -190,13 +178,11 @@ function _main
|
|||
|
||||
[[ -z ${CONTAINER_NAME} ]] && CONTAINER_NAME=${INFO#*;}
|
||||
[[ -z ${IMAGE_NAME} ]] && IMAGE_NAME=${INFO%;*}
|
||||
if [[ -z ${IMAGE_NAME} ]]
|
||||
then
|
||||
if [[ -z ${IMAGE_NAME} ]]; then
|
||||
IMAGE_NAME=${NAME:-${DEFAULT_IMAGE_NAME}}
|
||||
fi
|
||||
|
||||
if test -t 0
|
||||
then
|
||||
if test -t 0; then
|
||||
USE_TTY="-it"
|
||||
else
|
||||
# GitHub Actions will fail (or really anything else
|
||||
|
@ -207,8 +193,7 @@ function _main
|
|||
|
||||
_handle_config_path
|
||||
|
||||
if [[ -n ${CONTAINER_NAME} ]]
|
||||
then
|
||||
if [[ -n ${CONTAINER_NAME} ]]; then
|
||||
${CRI} exec "${USE_TTY}" "${CONTAINER_NAME}" setup "${@}"
|
||||
else
|
||||
_run_in_new_container setup "${@}"
|
||||
|
|
|
@ -7,8 +7,7 @@ source /usr/local/bin/setup.d/getmail.sh
|
|||
|
||||
_setup_getmail
|
||||
|
||||
if [[ -d /var/lib/getmail ]]
|
||||
then
|
||||
if [[ -d /var/lib/getmail ]]; then
|
||||
GETMAILDIR=/var/lib/getmail
|
||||
else
|
||||
mkdir -p /tmp/docker-mailserver/getmail
|
||||
|
|
|
@ -91,14 +91,12 @@ function _parse_options
|
|||
|
||||
function _maildel_request_if_missing
|
||||
{
|
||||
if [[ ${MAILDEL} -eq 0 ]]
|
||||
then
|
||||
if [[ ${MAILDEL} -eq 0 ]]; then
|
||||
local MAILDEL_CHOSEN
|
||||
read -r -p "Do you want to delete the mailbox as well (removing all mails)? [Y/n] " MAILDEL_CHOSEN
|
||||
|
||||
# TODO: Why would MAILDEL be set to true if MAILDEL_CHOSEN is empty?
|
||||
if [[ ${MAILDEL_CHOSEN} =~ (y|Y|yes|Yes) ]] || [[ -z ${MAILDEL_CHOSEN} ]]
|
||||
then
|
||||
if [[ ${MAILDEL_CHOSEN} =~ (y|Y|yes|Yes) ]] || [[ -z ${MAILDEL_CHOSEN} ]]; then
|
||||
MAILDEL=1
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -19,16 +19,14 @@ do
|
|||
JAILS+=("${LIST}")
|
||||
done
|
||||
|
||||
if [[ -z ${1} ]]
|
||||
then
|
||||
if [[ -z ${1} ]]; then
|
||||
IPS_BANNED=0
|
||||
|
||||
for JAIL in "${JAILS[@]}"
|
||||
do
|
||||
BANNED_IPS=$(fail2ban-client status "${JAIL}" | grep -oP '(?<=Banned IP list:\s).+')
|
||||
|
||||
if [[ -n ${BANNED_IPS} ]]
|
||||
then
|
||||
if [[ -n ${BANNED_IPS} ]]; then
|
||||
echo "Banned in ${JAIL}: ${BANNED_IPS}"
|
||||
IPS_BANNED=1
|
||||
fi
|
||||
|
@ -43,11 +41,9 @@ else
|
|||
|
||||
( 'ban' )
|
||||
shift
|
||||
if [[ -n ${1} ]]
|
||||
then
|
||||
if [[ -n ${1} ]]; then
|
||||
RESULT=$(fail2ban-client set custom banip "${@}")
|
||||
if [[ ${RESULT} -gt 0 ]]
|
||||
then
|
||||
if [[ ${RESULT} -gt 0 ]]; then
|
||||
echo "Banned custom IP: ${RESULT}"
|
||||
else
|
||||
_log 'error' "Banning '${*}' failed. Already banned?"
|
||||
|
@ -61,8 +57,7 @@ else
|
|||
|
||||
( 'unban' )
|
||||
shift
|
||||
if [[ -n ${1} ]]
|
||||
then
|
||||
if [[ -n ${1} ]]; then
|
||||
|
||||
for JAIL in "${JAILS[@]}"
|
||||
do
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
for FILE in /etc/getmailrc.d/getmailrc*
|
||||
do
|
||||
if ! pgrep -f "${FILE}$" &>/dev/null
|
||||
then
|
||||
if ! pgrep -f "${FILE}$" &>/dev/null; then
|
||||
/usr/local/bin/getmail --getmaildir /var/lib/getmail --rcfile "${FILE}"
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -71,12 +71,10 @@ function _quota_show_for
|
|||
function _bytes_to_human_readable_size
|
||||
{
|
||||
# `-` represents a non-applicable value (eg: Like when `SIZE_LIMIT` is not set):
|
||||
if [[ ${1:-} == '-' ]]
|
||||
then
|
||||
if [[ ${1:-} == '-' ]]; then
|
||||
echo '~'
|
||||
# Otherwise a value in KibiBytes (1024 bytes == 1k) is expected (Dovecots internal representation):
|
||||
elif [[ ${1:-} =~ ^[0-9]+$ ]]
|
||||
then
|
||||
elif [[ ${1:-} =~ ^[0-9]+$ ]]; then
|
||||
# kibibytes to bytes, converted to approproate IEC unit (eg: MiB):
|
||||
echo $(( 1024 * ${1} )) | numfmt --to=iec
|
||||
else
|
||||
|
@ -105,8 +103,7 @@ function _alias_list_for_account
|
|||
"${DATABASE_VIRTUAL}"
|
||||
)
|
||||
|
||||
if grep --quiet --no-messages "${GREP_OPTIONS[@]}"
|
||||
then
|
||||
if grep --quiet --no-messages "${GREP_OPTIONS[@]}"; then
|
||||
grep "${GREP_OPTIONS[@]}" | awk '{print $1;}' | sed ':a;N;$!ba;s/\n/, /g'
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
# shellcheck source=../scripts/helpers/index.sh
|
||||
source /usr/local/bin/helpers/index.sh
|
||||
|
||||
if [[ -f /etc/dms-settings ]] && [[ $(_get_dms_env_value 'ENABLE_RSPAMD') -eq 1 ]]
|
||||
then
|
||||
if [[ -f /etc/dms-settings ]] && [[ $(_get_dms_env_value 'ENABLE_RSPAMD') -eq 1 ]]; then
|
||||
/usr/local/bin/rspamd-dkim "${@}"
|
||||
exit
|
||||
fi
|
||||
|
@ -63,8 +62,7 @@ while [[ ${#} -gt 0 ]]
|
|||
do
|
||||
case "${1}" in
|
||||
( 'keysize' )
|
||||
if [[ -n ${2+set} ]]
|
||||
then
|
||||
if [[ -n ${2+set} ]]; then
|
||||
KEYSIZE="${2}"
|
||||
shift
|
||||
shift
|
||||
|
@ -74,8 +72,7 @@ do
|
|||
;;
|
||||
|
||||
( 'selector' )
|
||||
if [[ -n ${2+set} ]]
|
||||
then
|
||||
if [[ -n ${2+set} ]]; then
|
||||
# shellcheck disable=SC2034
|
||||
SELECTOR="${2}"
|
||||
shift
|
||||
|
@ -86,8 +83,7 @@ do
|
|||
;;
|
||||
|
||||
( 'domain' )
|
||||
if [[ -n ${2+set} ]]
|
||||
then
|
||||
if [[ -n ${2+set} ]]; then
|
||||
DOMAINS="${2}"
|
||||
shift
|
||||
shift
|
||||
|
@ -112,8 +108,7 @@ function _generate_domains_config
|
|||
|
||||
# Generate the default vhost (equivalent to /etc/postfix/vhost),
|
||||
# unless CLI arg DOMAINS provided an alternative list to use instead:
|
||||
if [[ -z ${DOMAINS} ]]
|
||||
then
|
||||
if [[ -z ${DOMAINS} ]]; then
|
||||
_obtain_hostname_and_domainname
|
||||
# uses TMP_VHOST:
|
||||
_vhost_collect_postfix_domains
|
||||
|
@ -126,8 +121,7 @@ function _generate_domains_config
|
|||
}
|
||||
|
||||
_generate_domains_config
|
||||
if [[ ! -s ${DATABASE_VHOST} ]]
|
||||
then
|
||||
if [[ ! -s ${DATABASE_VHOST} ]]; then
|
||||
_log 'warn' 'No entries found, no keys to make'
|
||||
exit 0
|
||||
fi
|
||||
|
@ -136,8 +130,7 @@ while read -r DKIM_DOMAIN
|
|||
do
|
||||
mkdir -p "/tmp/docker-mailserver/opendkim/keys/${DKIM_DOMAIN}"
|
||||
|
||||
if [[ ! -f "/tmp/docker-mailserver/opendkim/keys/${DKIM_DOMAIN}/${SELECTOR}.private" ]]
|
||||
then
|
||||
if [[ ! -f "/tmp/docker-mailserver/opendkim/keys/${DKIM_DOMAIN}/${SELECTOR}.private" ]]; then
|
||||
_log 'info' "Creating DKIM private key '/tmp/docker-mailserver/opendkim/keys/${DKIM_DOMAIN}/${SELECTOR}.private'"
|
||||
|
||||
opendkim-genkey \
|
||||
|
@ -150,34 +143,29 @@ do
|
|||
|
||||
# write to KeyTable if necessary
|
||||
KEYTABLEENTRY="${SELECTOR}._domainkey.${DKIM_DOMAIN} ${DKIM_DOMAIN}:${SELECTOR}:/etc/opendkim/keys/${DKIM_DOMAIN}/${SELECTOR}.private"
|
||||
if [[ ! -f "/tmp/docker-mailserver/opendkim/KeyTable" ]]
|
||||
then
|
||||
if [[ ! -f "/tmp/docker-mailserver/opendkim/KeyTable" ]]; then
|
||||
_log 'debug' 'Creating DKIM KeyTable'
|
||||
echo "${KEYTABLEENTRY}" >/tmp/docker-mailserver/opendkim/KeyTable
|
||||
else
|
||||
if ! grep -q "${KEYTABLEENTRY}" "/tmp/docker-mailserver/opendkim/KeyTable"
|
||||
then
|
||||
if ! grep -q "${KEYTABLEENTRY}" "/tmp/docker-mailserver/opendkim/KeyTable"; then
|
||||
echo "${KEYTABLEENTRY}" >>/tmp/docker-mailserver/opendkim/KeyTable
|
||||
fi
|
||||
fi
|
||||
|
||||
# write to SigningTable if necessary
|
||||
SIGNINGTABLEENTRY="*@${DKIM_DOMAIN} ${SELECTOR}._domainkey.${DKIM_DOMAIN}"
|
||||
if [[ ! -f /tmp/docker-mailserver/opendkim/SigningTable ]]
|
||||
then
|
||||
if [[ ! -f /tmp/docker-mailserver/opendkim/SigningTable ]]; then
|
||||
_log 'debug' 'Creating DKIM SigningTable'
|
||||
echo "*@${DKIM_DOMAIN} ${SELECTOR}._domainkey.${DKIM_DOMAIN}" >/tmp/docker-mailserver/opendkim/SigningTable
|
||||
else
|
||||
if ! grep -q "${SIGNINGTABLEENTRY}" /tmp/docker-mailserver/opendkim/SigningTable
|
||||
then
|
||||
if ! grep -q "${SIGNINGTABLEENTRY}" /tmp/docker-mailserver/opendkim/SigningTable; then
|
||||
echo "${SIGNINGTABLEENTRY}" >>/tmp/docker-mailserver/opendkim/SigningTable
|
||||
fi
|
||||
fi
|
||||
done < <(_get_valid_lines_from_file "${DATABASE_VHOST}")
|
||||
|
||||
# create TrustedHosts if missing
|
||||
if [[ -d /tmp/docker-mailserver/opendkim ]] && [[ ! -f /tmp/docker-mailserver/opendkim/TrustedHosts ]]
|
||||
then
|
||||
if [[ -d /tmp/docker-mailserver/opendkim ]] && [[ ! -f /tmp/docker-mailserver/opendkim/TrustedHosts ]]; then
|
||||
_log 'debug' 'Creating DKIM TrustedHosts'
|
||||
echo "127.0.0.1" >/tmp/docker-mailserver/opendkim/TrustedHosts
|
||||
echo "localhost" >>/tmp/docker-mailserver/opendkim/TrustedHosts
|
||||
|
|
|
@ -12,8 +12,7 @@ SENDER=${3}
|
|||
# The case that the mail.log.1 file isn't readable shouldn't
|
||||
# actually be possible with logrotate not rotating empty files..
|
||||
# But you never know!
|
||||
if [[ -r "/var/log/mail/mail.log.1" ]]
|
||||
then
|
||||
if [[ -r "/var/log/mail/mail.log.1" ]]; then
|
||||
BODY=$(/usr/sbin/pflogsumm /var/log/mail/mail.log.1 --problems-first)
|
||||
else
|
||||
BODY="Error: Mail log not readable or not found: /var/log/mail/mail.log.1
|
||||
|
|
|
@ -10,16 +10,14 @@ USER=${3:-}
|
|||
|
||||
function __usage { _log 'info' "Usage: ${0} <add|del|list> <send|receive> [<email@domain.com>]" ; }
|
||||
|
||||
if [[ ${DIRECTION} =~ ^(send|receive)$ ]]
|
||||
then
|
||||
if [[ ${DIRECTION} =~ ^(send|receive)$ ]]; then
|
||||
DATABASE="/tmp/docker-mailserver/postfix-${DIRECTION}-access.cf"
|
||||
else
|
||||
__usage
|
||||
_exit_with_error "Unknown or missing second parameter '${DIRECTION}' - specify 'send' or 'receive'"
|
||||
fi
|
||||
|
||||
if [[ -z ${USER} ]] && [[ ${COMMAND} != list ]]
|
||||
then
|
||||
if [[ -z ${USER} ]] && [[ ${COMMAND} != list ]]; then
|
||||
read -r -p 'Provide a username: ' USER
|
||||
[[ -z ${USER} ]] && _exit_with_error 'User must not be empty'
|
||||
fi
|
||||
|
@ -27,15 +25,13 @@ fi
|
|||
case "${COMMAND}" in
|
||||
|
||||
( 'add' )
|
||||
if [[ -f ${DATABASE} ]] && grep -q -F "${USER}" "${DATABASE}"
|
||||
then
|
||||
if [[ -f ${DATABASE} ]] && grep -q -F "${USER}" "${DATABASE}"; then
|
||||
_exit_with_error "User '${USER}' already denied to ${DIRECTION} mails"
|
||||
fi
|
||||
|
||||
echo -e "${USER} \t\t REJECT" >>"${DATABASE}"
|
||||
|
||||
if [[ ${DIRECTION} == 'send' ]]
|
||||
then
|
||||
if [[ ${DIRECTION} == 'send' ]]; then
|
||||
CHECK='check_sender_access'
|
||||
POSTFIX_OPTION='smtpd_sender_restrictions'
|
||||
else
|
||||
|
@ -45,16 +41,14 @@ case "${COMMAND}" in
|
|||
|
||||
# only adjust Postfix's `main.cf` if we haven't adjusted it before
|
||||
STRING_TO_BE_ADDED="${CHECK} texthash:/tmp/docker-mailserver/postfix-${DIRECTION}-access.cf"
|
||||
if ! grep -q "${STRING_TO_BE_ADDED}" /etc/postfix/main.cf
|
||||
then
|
||||
if ! grep -q "${STRING_TO_BE_ADDED}" /etc/postfix/main.cf; then
|
||||
sed -i -E "s|^(${POSTFIX_OPTION} =)(.*)|\1 ${STRING_TO_BE_ADDED},\2|" /etc/postfix/main.cf
|
||||
_reload_postfix
|
||||
fi
|
||||
;;
|
||||
|
||||
( 'del' )
|
||||
if ! sed -i "/^$(_escape "${USER}").*/d" "${DATABASE}" 2>/dev/null
|
||||
then
|
||||
if ! sed -i "/^$(_escape "${USER}").*/d" "${DATABASE}" 2>/dev/null; then
|
||||
_exit_with_error "User '${USER}' not found"
|
||||
fi
|
||||
;;
|
||||
|
|
|
@ -88,8 +88,7 @@ function _parse_arguments
|
|||
|
||||
( 'keytype' )
|
||||
[[ -n ${2:-} ]] || _exit_with_error "No keytype provided after 'keytype' argument"
|
||||
if [[ ${2} == 'rsa' ]] || [[ ${2} == 'ed25519' ]]
|
||||
then
|
||||
if [[ ${2} == 'rsa' ]] || [[ ${2} == 'ed25519' ]]; then
|
||||
KEYTYPE=${2}
|
||||
_log 'debug' "Keytype set to '${KEYTYPE}'"
|
||||
else
|
||||
|
@ -146,8 +145,7 @@ function _parse_arguments
|
|||
shift 2
|
||||
done
|
||||
|
||||
if [[ ${KEYTYPE} == 'ed25519' ]] && [[ ${KEYSIZE} -ne 2048 ]]
|
||||
then
|
||||
if [[ ${KEYTYPE} == 'ed25519' ]] && [[ ${KEYSIZE} -ne 2048 ]]; then
|
||||
_exit_with_error "Chosen keytype does not accept the 'keysize' argument"
|
||||
fi
|
||||
|
||||
|
@ -160,8 +158,7 @@ function _create_keys
|
|||
# in other functions (after this function was called).
|
||||
BASE_DIR='/tmp/docker-mailserver/rspamd/dkim'
|
||||
|
||||
if [[ ${KEYTYPE} == 'rsa' ]]
|
||||
then
|
||||
if [[ ${KEYTYPE} == 'rsa' ]]; then
|
||||
local BASE_FILE_NAME="${BASE_DIR}/${KEYTYPE}-${KEYSIZE}-${SELECTOR}-${DOMAIN}"
|
||||
KEYTYPE_OPTIONS=('-b' "${KEYSIZE}")
|
||||
_log 'info' "Creating DKIM keys of type '${KEYTYPE}' and lenght '${KEYSIZE}' with selector '${SELECTOR}' for domain '${DOMAIN}'"
|
||||
|
@ -198,11 +195,9 @@ function _create_keys
|
|||
function _check_permissions
|
||||
{
|
||||
# shellcheck disable=SC2310
|
||||
if ! __do_as_rspamd_user ls "${BASE_DIR}" >/dev/null
|
||||
then
|
||||
if ! __do_as_rspamd_user ls "${BASE_DIR}" >/dev/null; then
|
||||
_log 'warn' "The Rspamd user ('_rspamd') seems to be unable to list files in the keys directory ('${BASE_DIR}') - Rspamd may experience permission errors later"
|
||||
elif ! __do_as_rspamd_user cat "${PRIVATE_KEY_FILE}" >/dev/null
|
||||
then
|
||||
elif ! __do_as_rspamd_user cat "${PRIVATE_KEY_FILE}" >/dev/null; then
|
||||
_log 'warn' "The Rspamd user ('_rspamd') seems to be unable to read the private key file - Rspamd may experience permission errors later"
|
||||
else
|
||||
_log 'debug' 'Permissions on files and directories seem ok'
|
||||
|
@ -212,8 +207,7 @@ function _check_permissions
|
|||
function _setup_default_signing_conf
|
||||
{
|
||||
local DEFAULT_CONFIG_FILE='/etc/rspamd/override.d/dkim_signing.conf'
|
||||
if [[ -f ${DEFAULT_CONFIG_FILE} ]]
|
||||
then
|
||||
if [[ -f ${DEFAULT_CONFIG_FILE} ]]; then
|
||||
_log 'debug' "'${DEFAULT_CONFIG_FILE}' exists, not supplying a default"
|
||||
else
|
||||
_log 'info' "Supplying a default configuration ('${DEFAULT_CONFIG_FILE}')"
|
||||
|
@ -250,8 +244,7 @@ function _transform_public_key_file_to_dns_record_contents
|
|||
grep -o '".*"' "${PUBLIC_KEY_FILE}" | tr -d '"\n' >>"${PUBLIC_KEY_DNS_FILE}"
|
||||
echo '' >>"${PUBLIC_KEY_DNS_FILE}"
|
||||
|
||||
if ! _log_level_is '(warn|error)'
|
||||
then
|
||||
if ! _log_level_is '(warn|error)'; then
|
||||
_log 'info' "Here is the content of the TXT DNS record ${SELECTOR}._domainkey.${DOMAIN} that you need to create:\n"
|
||||
cat "${PUBLIC_KEY_DNS_FILE}"
|
||||
printf '\n'
|
||||
|
@ -261,8 +254,7 @@ function _transform_public_key_file_to_dns_record_contents
|
|||
function _final_steps
|
||||
{
|
||||
# We need to restart Rspamd so the changes take effect immediately.
|
||||
if ! supervisorctl restart rspamd
|
||||
then
|
||||
if ! supervisorctl restart rspamd; then
|
||||
_log 'warn' 'Could not restart Rspamd via Supervisord'
|
||||
fi
|
||||
|
||||
|
|
|
@ -19,16 +19,14 @@ function __usage { echo "Usage: ${0} -i <replace/delete operation> <file>" ; }
|
|||
HASHTOOL='sha1sum'
|
||||
SKIP_ERROR=0
|
||||
|
||||
if [[ ${#} -lt 3 ]]
|
||||
then
|
||||
if [[ ${#} -lt 3 ]]; then
|
||||
_log 'error' 'At least three parameters must be given'
|
||||
__usage
|
||||
exit 1
|
||||
fi >&2
|
||||
|
||||
[[ -f /CONTAINER_START ]] && SKIP_ERROR=1 # hide error if container was restarted
|
||||
if [[ ${1} == '--strict' ]] # show error every time
|
||||
then
|
||||
if [[ ${1} == '--strict' ]]; then # show error every time
|
||||
SKIP_ERROR=0
|
||||
shift
|
||||
fi
|
||||
|
@ -41,8 +39,7 @@ sed "${@}"
|
|||
NEW=$(${HASHTOOL} "${FILE}")
|
||||
|
||||
# fail if file was not modified
|
||||
if [[ ${OLD} == "${NEW}" ]] && [[ ${SKIP_ERROR} -eq 0 ]]
|
||||
then
|
||||
if [[ ${OLD} == "${NEW}" ]] && [[ ${SKIP_ERROR} -eq 0 ]]; then
|
||||
_log 'error' "No difference after call to 'sed' in 'sedfile' (sed ${*})" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
@ -56,8 +56,7 @@ function _validate_parameters
|
|||
|
||||
function _quota_request_if_missing
|
||||
{
|
||||
if [[ -z ${QUOTA} ]]
|
||||
then
|
||||
if [[ -z ${QUOTA} ]]; then
|
||||
read -r -p 'Enter quota (e.g. 10M): ' QUOTA
|
||||
echo
|
||||
[[ -z "${QUOTA}" ]] && _exit_with_error 'Quota must not be empty (use 0 for unlimited quota)'
|
||||
|
@ -66,8 +65,7 @@ function _quota_request_if_missing
|
|||
|
||||
function _quota_unit_is_valid
|
||||
{
|
||||
if ! grep -qE "^([0-9]+(B|k|M|G|T)|0)\$" <<< "${QUOTA}"
|
||||
then
|
||||
if ! grep -qE "^([0-9]+(B|k|M|G|T)|0)\$" <<< "${QUOTA}"; then
|
||||
__usage
|
||||
_exit_with_error 'Invalid quota format. e.g. 302M (B (byte), k (kilobyte), M (megabyte), G (gigabyte) or T (terabyte))'
|
||||
fi
|
||||
|
|
|
@ -155,8 +155,7 @@ function _main
|
|||
( show-mail-logs ) cat /var/log/mail/mail.log ;;
|
||||
( login )
|
||||
shift 2
|
||||
if [[ -z ${1:-} ]]
|
||||
then
|
||||
if [[ -z ${1:-} ]]; then
|
||||
/bin/bash
|
||||
else
|
||||
/bin/bash -c "${@}"
|
||||
|
@ -171,8 +170,7 @@ function _main
|
|||
esac
|
||||
}
|
||||
|
||||
if [[ -z ${1:-} ]]
|
||||
then
|
||||
if [[ -z ${1:-} ]]; then
|
||||
_usage
|
||||
else
|
||||
_main "${@}"
|
||||
|
|
|
@ -42,8 +42,7 @@ SCRIPTNAME="/etc/init.d/${DAEMON_NAME}"
|
|||
|
||||
POSTGREY_OPTS="--pidfile=${PIDFILE} --daemonize ${POSTGREY_OPTS}"
|
||||
|
||||
if [ -z "${POSTGREY_TEXT}" ]
|
||||
then
|
||||
if [ -z "${POSTGREY_TEXT}" ]; then
|
||||
POSTGREY_TEXT_OPT=""
|
||||
else
|
||||
POSTGREY_TEXT_OPT="--greylist-text=${POSTGREY_TEXT}"
|
||||
|
|
|
@ -103,8 +103,7 @@ function _install_dovecot
|
|||
dovecot-pop3d dovecot-sieve dovecot-solr
|
||||
)
|
||||
|
||||
if [[ ${DOVECOT_COMMUNITY_REPO} -eq 1 ]]
|
||||
then
|
||||
if [[ ${DOVECOT_COMMUNITY_REPO} -eq 1 ]]; then
|
||||
# The package dovecot-fts-xapian is installed from the debian repository.
|
||||
# Starting with version 1.4.9a-1+deb11u1, a new dependency was added: dovecot-abi-2.3.abiv13
|
||||
# dovecot-abi-2.3.abiv13 is a virtual package provided by dovecot-core (from the debian repository).
|
||||
|
@ -144,8 +143,7 @@ function _install_rspamd
|
|||
#
|
||||
# Not removing it later is fine as you have to explicitly opt into installing a backports package
|
||||
# which is not something you could be doing by accident.
|
||||
if [[ $(uname --machine) == 'aarch64' ]]
|
||||
then
|
||||
if [[ $(uname --machine) == 'aarch64' ]]; then
|
||||
echo '# Official Rspamd PPA does not support aarch64, so we use the Bullseye backports' >"${DEB_FILE}"
|
||||
echo 'deb [arch=arm64] http://deb.debian.org/debian bullseye-backports main' >>"${DEB_FILE}"
|
||||
RSPAMD_PACKAGE_NAME='rspamd/bullseye-backports'
|
||||
|
@ -180,14 +178,12 @@ function _install_fail2ban
|
|||
|
||||
FINGERPRINT=$(LANG=C gpg --verify fail2ban.deb.asc fail2ban.deb |& sed -n 's#Primary key fingerprint: \(.*\)#\1#p')
|
||||
|
||||
if [[ -z ${FINGERPRINT} ]]
|
||||
then
|
||||
if [[ -z ${FINGERPRINT} ]]; then
|
||||
echo 'ERROR: Invalid GPG signature!' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${FINGERPRINT} != "${FAIL2BAN_GPG_FINGERPRINT}" ]]
|
||||
then
|
||||
if [[ ${FINGERPRINT} != "${FAIL2BAN_GPG_FINGERPRINT}" ]]; then
|
||||
echo "ERROR: Wrong GPG fingerprint!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
@ -22,8 +22,7 @@ source /etc/dms-settings
|
|||
_obtain_hostname_and_domainname
|
||||
|
||||
# verify checksum file exists; must be prepared by start-mailserver.sh
|
||||
if [[ ! -f ${CHKSUM_FILE} ]]
|
||||
then
|
||||
if [[ ! -f ${CHKSUM_FILE} ]]; then
|
||||
_exit_with_error "'${CHKSUM_FILE}' is missing" 0
|
||||
fi
|
||||
|
||||
|
@ -41,8 +40,7 @@ function _check_for_changes
|
|||
# 0 – files are identical
|
||||
# 1 – files differ
|
||||
# 2 – inaccessible or missing argument
|
||||
if [[ ${?} -eq 1 ]]
|
||||
then
|
||||
if [[ ${?} -eq 1 ]]; then
|
||||
_log_with_date 'info' 'Change detected'
|
||||
_create_lock # Shared config safety lock
|
||||
|
||||
|
@ -85,8 +83,7 @@ function _get_changed_files
|
|||
|
||||
function _reload_amavis
|
||||
{
|
||||
if [[ ${CHANGED} =~ ${DMS_DIR}/postfix-accounts.cf ]] || [[ ${CHANGED} =~ ${DMS_DIR}/postfix-virtual.cf ]]
|
||||
then
|
||||
if [[ ${CHANGED} =~ ${DMS_DIR}/postfix-accounts.cf ]] || [[ ${CHANGED} =~ ${DMS_DIR}/postfix-virtual.cf ]]; then
|
||||
# /etc/postfix/vhost was updated, amavis must refresh it's config by
|
||||
# reading this file again in case of new domains, otherwise they will be ignored.
|
||||
amavisd-new reload
|
||||
|
@ -152,8 +149,7 @@ function _ssl_changes
|
|||
# manual - copy to internal DMS_TLS_PATH (/etc/dms/tls) that Postfix and Dovecot are configured to use.
|
||||
# acme.json - presently uses /etc/letsencrypt/live/<FQDN> instead of DMS_TLS_PATH,
|
||||
# path may change requiring Postfix/Dovecot config update.
|
||||
if [[ ${SSL_TYPE} == 'manual' ]]
|
||||
then
|
||||
if [[ ${SSL_TYPE} == 'manual' ]]; then
|
||||
# only run the SSL setup again if certificates have really changed.
|
||||
if [[ ${CHANGED} =~ ${SSL_CERT_PATH:-${REGEX_NEVER_MATCH}} ]] \
|
||||
|| [[ ${CHANGED} =~ ${SSL_KEY_PATH:-${REGEX_NEVER_MATCH}} ]] \
|
||||
|
@ -166,8 +162,7 @@ function _ssl_changes
|
|||
# `acme.json` is only relevant to Traefik, and is where it stores the certificates it manages.
|
||||
# When a change is detected it's assumed to be a possible cert renewal that needs to be
|
||||
# extracted for `docker-mailserver` services to adjust to.
|
||||
elif [[ ${CHANGED} =~ /etc/letsencrypt/acme.json ]]
|
||||
then
|
||||
elif [[ ${CHANGED} =~ /etc/letsencrypt/acme.json ]]; then
|
||||
_log_with_date 'debug' "'/etc/letsencrypt/acme.json' has changed - extracting certificates"
|
||||
_setup_ssl
|
||||
|
||||
|
|
|
@ -19,8 +19,7 @@ function _create_accounts
|
|||
local DATABASE_ACCOUNTS='/tmp/docker-mailserver/postfix-accounts.cf'
|
||||
_create_masters
|
||||
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]]; then
|
||||
_log 'trace' "Checking file line endings"
|
||||
sed -i 's|\r||g' "${DATABASE_ACCOUNTS}"
|
||||
|
||||
|
@ -47,19 +46,16 @@ function _create_accounts
|
|||
DOMAIN=$(echo "${LOGIN}" | cut -d @ -f2)
|
||||
|
||||
# test if user has a defined quota
|
||||
if [[ -f /tmp/docker-mailserver/dovecot-quotas.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/dovecot-quotas.cf ]]; then
|
||||
declare -a USER_QUOTA
|
||||
IFS=':' read -r -a USER_QUOTA < <(grep "${USER}@${DOMAIN}:" -i /tmp/docker-mailserver/dovecot-quotas.cf)
|
||||
|
||||
if [[ ${#USER_QUOTA[@]} -eq 2 ]]
|
||||
then
|
||||
if [[ ${#USER_QUOTA[@]} -eq 2 ]]; then
|
||||
USER_ATTRIBUTES="${USER_ATTRIBUTES:+${USER_ATTRIBUTES} }userdb_quota_rule=*:bytes=${USER_QUOTA[1]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z ${USER_ATTRIBUTES} ]]
|
||||
then
|
||||
if [[ -z ${USER_ATTRIBUTES} ]]; then
|
||||
_log 'debug' "Creating user '${USER}' for domain '${DOMAIN}'"
|
||||
else
|
||||
_log 'debug' "Creating user '${USER}' for domain '${DOMAIN}' with attributes '${USER_ATTRIBUTES}'"
|
||||
|
@ -68,8 +64,7 @@ function _create_accounts
|
|||
local POSTFIX_VMAILBOX_LINE DOVECOT_USERDB_LINE
|
||||
|
||||
POSTFIX_VMAILBOX_LINE="${LOGIN} ${DOMAIN}/${USER}/"
|
||||
if grep -qF "${POSTFIX_VMAILBOX_LINE}" /etc/postfix/vmailbox
|
||||
then
|
||||
if grep -qF "${POSTFIX_VMAILBOX_LINE}" /etc/postfix/vmailbox; then
|
||||
_log 'warn' "User '${USER}@${DOMAIN}' will not be added to '/etc/postfix/vmailbox' twice"
|
||||
else
|
||||
echo "${POSTFIX_VMAILBOX_LINE}" >>/etc/postfix/vmailbox
|
||||
|
@ -78,8 +73,7 @@ function _create_accounts
|
|||
# Dovecot's userdb has the following format
|
||||
# user:password:uid:gid:(gecos):home:(shell):extra_fields
|
||||
DOVECOT_USERDB_LINE="${LOGIN}:${PASS}:5000:5000::/var/mail/${DOMAIN}/${USER}/home::${USER_ATTRIBUTES}"
|
||||
if grep -qF "${DOVECOT_USERDB_LINE}" "${DOVECOT_USERDB_FILE}"
|
||||
then
|
||||
if grep -qF "${DOVECOT_USERDB_LINE}" "${DOVECOT_USERDB_FILE}"; then
|
||||
_log 'warn' "Login '${LOGIN}' will not be added to '${DOVECOT_USERDB_FILE}' twice"
|
||||
else
|
||||
echo "${DOVECOT_USERDB_LINE}" >>"${DOVECOT_USERDB_FILE}"
|
||||
|
@ -88,8 +82,7 @@ function _create_accounts
|
|||
mkdir -p "/var/mail/${DOMAIN}/${USER}/home"
|
||||
|
||||
# copy user provided sieve file, if present
|
||||
if [[ -e "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" ]]
|
||||
then
|
||||
if [[ -e "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" ]]; then
|
||||
cp "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" "/var/mail/${DOMAIN}/${USER}/home/.dovecot.sieve"
|
||||
fi
|
||||
done < <(_get_valid_lines_from_file "${DATABASE_ACCOUNTS}")
|
||||
|
@ -109,8 +102,7 @@ function _create_dovecot_alias_dummy_accounts
|
|||
{
|
||||
local DATABASE_VIRTUAL='/tmp/docker-mailserver/postfix-virtual.cf'
|
||||
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]] && [[ ${ENABLE_QUOTAS} -eq 1 ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]] && [[ ${ENABLE_QUOTAS} -eq 1 ]]; then
|
||||
# adding aliases to Dovecot's userdb
|
||||
# ${REAL_FQUN} is a user's fully-qualified username
|
||||
local ALIAS REAL_FQUN DOVECOT_USERDB_LINE
|
||||
|
@ -129,8 +121,7 @@ function _create_dovecot_alias_dummy_accounts
|
|||
REAL_USERNAME=$(cut -d '@' -f 1 <<< "${REAL_FQUN}")
|
||||
REAL_DOMAINNAME=$(cut -d '@' -f 2 <<< "${REAL_FQUN}")
|
||||
|
||||
if ! grep -q "${REAL_FQUN}" "${DATABASE_ACCOUNTS}"
|
||||
then
|
||||
if ! grep -q "${REAL_FQUN}" "${DATABASE_ACCOUNTS}"; then
|
||||
_log 'debug' "Alias '${ALIAS}' is non-local (or mapped to a non-existing account) and will not be added to Dovecot's userdb"
|
||||
continue
|
||||
fi
|
||||
|
@ -142,24 +133,20 @@ function _create_dovecot_alias_dummy_accounts
|
|||
# ${REAL_ACC[2]} => optional user attributes
|
||||
IFS='|' read -r -a REAL_ACC < <(grep "${REAL_FQUN}" "${DATABASE_ACCOUNTS}")
|
||||
|
||||
if [[ -z ${REAL_ACC[1]} ]]
|
||||
then
|
||||
if [[ -z ${REAL_ACC[1]} ]]; then
|
||||
_dms_panic__misconfigured 'postfix-accounts.cf' 'alias configuration'
|
||||
fi
|
||||
|
||||
# test if user has a defined quota
|
||||
if [[ -f /tmp/docker-mailserver/dovecot-quotas.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/dovecot-quotas.cf ]]; then
|
||||
IFS=':' read -r -a USER_QUOTA < <(grep "${REAL_FQUN}:" -i /tmp/docker-mailserver/dovecot-quotas.cf)
|
||||
if [[ ${#USER_QUOTA[@]} -eq 2 ]]
|
||||
then
|
||||
if [[ ${#USER_QUOTA[@]} -eq 2 ]]; then
|
||||
REAL_ACC[2]="${REAL_ACC[2]:+${REAL_ACC[2]} }userdb_quota_rule=*:bytes=${USER_QUOTA[1]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
DOVECOT_USERDB_LINE="${ALIAS}:${REAL_ACC[1]}:5000:5000::/var/mail/${REAL_DOMAINNAME}/${REAL_USERNAME}::${REAL_ACC[2]:-}"
|
||||
if grep -qi "^${ALIAS}:" "${DOVECOT_USERDB_FILE}"
|
||||
then
|
||||
if grep -qi "^${ALIAS}:" "${DOVECOT_USERDB_FILE}"; then
|
||||
_log 'warn' "Alias '${ALIAS}' will not be added to '${DOVECOT_USERDB_FILE}' twice"
|
||||
else
|
||||
echo "${DOVECOT_USERDB_LINE}" >>"${DOVECOT_USERDB_FILE}"
|
||||
|
@ -175,8 +162,7 @@ function _create_masters
|
|||
: >"${DOVECOT_MASTERDB_FILE}"
|
||||
|
||||
local DATABASE_DOVECOT_MASTERS='/tmp/docker-mailserver/dovecot-masters.cf'
|
||||
if [[ -f ${DATABASE_DOVECOT_MASTERS} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_DOVECOT_MASTERS} ]]; then
|
||||
_log 'trace' "Checking file line endings"
|
||||
sed -i 's|\r||g' "${DATABASE_DOVECOT_MASTERS}"
|
||||
|
||||
|
@ -203,8 +189,7 @@ function _create_masters
|
|||
# Dovecot's masterdb has the following format
|
||||
# user:password
|
||||
DOVECOT_MASTERDB_LINE="${LOGIN}:${PASS}"
|
||||
if grep -qF "${DOVECOT_MASTERDB_LINE}" "${DOVECOT_MASTERDB_FILE}"
|
||||
then
|
||||
if grep -qF "${DOVECOT_MASTERDB_LINE}" "${DOVECOT_MASTERDB_FILE}"; then
|
||||
_log 'warn' "Login '${LOGIN}' will not be added to '${DOVECOT_MASTERDB_FILE}' twice"
|
||||
else
|
||||
echo "${DOVECOT_MASTERDB_LINE}" >>"${DOVECOT_MASTERDB_FILE}"
|
||||
|
|
|
@ -12,11 +12,9 @@ function _handle_postfix_virtual_config
|
|||
|
||||
local DATABASE_VIRTUAL=/tmp/docker-mailserver/postfix-virtual.cf
|
||||
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]]; then
|
||||
# fixing old virtual user file
|
||||
if grep -q ",$" "${DATABASE_VIRTUAL}"
|
||||
then
|
||||
if grep -q ",$" "${DATABASE_VIRTUAL}"; then
|
||||
sed -i -e "s|, |,|g" -e "s|,$||g" "${DATABASE_VIRTUAL}"
|
||||
fi
|
||||
|
||||
|
@ -30,14 +28,12 @@ function _handle_postfix_regexp_config
|
|||
{
|
||||
: >/etc/postfix/regexp
|
||||
|
||||
if [[ -f /tmp/docker-mailserver/postfix-regexp.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/postfix-regexp.cf ]]; then
|
||||
_log 'trace' "Adding regexp alias file postfix-regexp.cf"
|
||||
|
||||
cp -f /tmp/docker-mailserver/postfix-regexp.cf /etc/postfix/regexp
|
||||
|
||||
if ! grep 'virtual_alias_maps.*pcre:/etc/postfix/regexp' /etc/postfix/main.cf
|
||||
then
|
||||
if ! grep 'virtual_alias_maps.*pcre:/etc/postfix/regexp' /etc/postfix/main.cf; then
|
||||
sed -i -E \
|
||||
's|virtual_alias_maps(.*)|virtual_alias_maps\1 pcre:/etc/postfix/regexp|g' \
|
||||
/etc/postfix/main.cf
|
||||
|
|
|
@ -31,8 +31,7 @@ function _monitored_files_checksums
|
|||
|
||||
# Supported user provided configs:
|
||||
local DMS_DIR=/tmp/docker-mailserver
|
||||
if [[ -d ${DMS_DIR} ]]
|
||||
then
|
||||
if [[ -d ${DMS_DIR} ]]; then
|
||||
STAGING_FILES+=(
|
||||
"${DMS_DIR}/postfix-accounts.cf"
|
||||
"${DMS_DIR}/postfix-virtual.cf"
|
||||
|
@ -46,8 +45,7 @@ function _monitored_files_checksums
|
|||
fi
|
||||
|
||||
# SSL certs:
|
||||
if [[ ${SSL_TYPE:-} == 'manual' ]]
|
||||
then
|
||||
if [[ ${SSL_TYPE:-} == 'manual' ]]; then
|
||||
# When using "manual" as the SSL type,
|
||||
# the following variables may contain the certificate files
|
||||
STAGING_FILES+=(
|
||||
|
@ -56,8 +54,7 @@ function _monitored_files_checksums
|
|||
"${SSL_ALT_CERT_PATH:-}"
|
||||
"${SSL_ALT_KEY_PATH:-}"
|
||||
)
|
||||
elif [[ ${SSL_TYPE:-} == 'letsencrypt' ]]
|
||||
then
|
||||
elif [[ ${SSL_TYPE:-} == 'letsencrypt' ]]; then
|
||||
# React to any cert changes within the following LetsEncrypt locations:
|
||||
STAGING_FILES+=(
|
||||
/etc/letsencrypt/acme.json
|
||||
|
@ -74,8 +71,7 @@ function _monitored_files_checksums
|
|||
[[ -f "${FILE}" ]] && CHANGED_FILES+=("${FILE}")
|
||||
done
|
||||
|
||||
if [[ -n ${CHANGED_FILES:-} ]]
|
||||
then
|
||||
if [[ -n ${CHANGED_FILES:-} ]]; then
|
||||
sha512sum -- "${CHANGED_FILES[@]}"
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -63,8 +63,7 @@ function _db_operation
|
|||
[[ ${DATABASE} == "${DATABASE_VIRTUAL}" ]] && V_DELIMITER=','
|
||||
|
||||
# Perform requested operation:
|
||||
if _db_has_entry_with_key "${KEY}" "${DATABASE}"
|
||||
then
|
||||
if _db_has_entry_with_key "${KEY}" "${DATABASE}"; then
|
||||
# Find entry for key and return status code:
|
||||
case "${DB_ACTION}" in
|
||||
( 'append' )
|
||||
|
@ -79,8 +78,7 @@ function _db_operation
|
|||
;;
|
||||
|
||||
( 'remove' )
|
||||
if [[ -z ${VALUE} ]]
|
||||
then # Remove entry for KEY:
|
||||
if [[ -z ${VALUE} ]]; then # Remove entry for KEY:
|
||||
sedfile --strict -i "/^${KEY_LOOKUP}/d" "${DATABASE}"
|
||||
else # Remove target VALUE from entry:
|
||||
__db_list_already_contains_value || return 0
|
||||
|
|
|
@ -74,8 +74,7 @@ function _arg_expect_mail_account
|
|||
function _account_should_not_exist_yet
|
||||
{
|
||||
__account_already_exists && _exit_with_error "'${MAIL_ACCOUNT}' already exists"
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]] && grep -q "^${MAIL_ACCOUNT}" "${DATABASE_VIRTUAL}"
|
||||
then
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]] && grep -q "^${MAIL_ACCOUNT}" "${DATABASE_VIRTUAL}"; then
|
||||
_exit_with_error "'${MAIL_ACCOUNT}' is already defined as an alias"
|
||||
fi
|
||||
}
|
||||
|
@ -95,8 +94,7 @@ function __account_already_exists
|
|||
# Also used by addsaslpassword
|
||||
function _password_request_if_missing
|
||||
{
|
||||
if [[ -z ${PASSWD} ]]
|
||||
then
|
||||
if [[ -z ${PASSWD} ]]; then
|
||||
read -r -s -p 'Enter Password: ' PASSWD
|
||||
echo
|
||||
[[ -z ${PASSWD} ]] && _exit_with_error 'Password must not be empty'
|
||||
|
|
|
@ -25,8 +25,7 @@ function _manage_virtual_aliases
|
|||
case "${ACTION}" in
|
||||
# Associate RECIPIENT to MAIL_ALIAS:
|
||||
( 'update' )
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]] && grep -q "^${MAIL_ALIAS}" "${DATABASE_ACCOUNTS}"
|
||||
then
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]] && grep -q "^${MAIL_ALIAS}" "${DATABASE_ACCOUNTS}"; then
|
||||
_exit_with_error "'${MAIL_ALIAS}' is already defined as an account"
|
||||
fi
|
||||
_db_entry_add_or_append "${DATABASE_VIRTUAL}" "${MAIL_ALIAS}" "${RECIPIENT}"
|
||||
|
|
|
@ -27,8 +27,7 @@ function _obtain_hostname_and_domainname
|
|||
|
||||
# If the container is misconfigured.. `hostname -f` (which derives it's return value from `/etc/hosts` or DNS query),
|
||||
# will result in an error that returns an empty value. This warrants a panic.
|
||||
if [[ -z ${HOSTNAME} ]]
|
||||
then
|
||||
if [[ -z ${HOSTNAME} ]]; then
|
||||
_dms_panic__misconfigured 'obtain_hostname' '/etc/hosts'
|
||||
fi
|
||||
|
||||
|
@ -39,10 +38,8 @@ function _obtain_hostname_and_domainname
|
|||
# `hostname -d` was probably not the correct command for this intention either.
|
||||
# Needs further investigation for relevance, and if `/etc/hosts` is important for consumers
|
||||
# of this variable or if a more deterministic approach with `cut` should be relied on.
|
||||
if [[ $(_get_label_count "${HOSTNAME}") -gt 2 ]]
|
||||
then
|
||||
if [[ -n ${OVERRIDE_HOSTNAME:-} ]]
|
||||
then
|
||||
if [[ $(_get_label_count "${HOSTNAME}") -gt 2 ]]; then
|
||||
if [[ -n ${OVERRIDE_HOSTNAME:-} ]]; then
|
||||
# Emulates the intended behaviour of `hostname -d`:
|
||||
# Assign the HOSTNAME value minus everything up to and including the first `.`
|
||||
DOMAINNAME=${HOSTNAME#*.}
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
function _exit_with_error
|
||||
{
|
||||
if [[ -n ${1+set} ]]
|
||||
then
|
||||
if [[ -n ${1+set} ]]; then
|
||||
_log 'error' "${1}"
|
||||
else
|
||||
_log 'error' "Call to '_exit_with_error' is missing a message to log"
|
||||
|
@ -58,8 +57,7 @@ function dms_panic
|
|||
;;
|
||||
esac
|
||||
|
||||
if [[ -n ${PANIC_SCOPE:-} ]]
|
||||
then
|
||||
if [[ -n ${PANIC_SCOPE:-} ]]; then
|
||||
_shutdown "${PANIC_SCOPE} | ${SHUTDOWN_MESSAGE}"
|
||||
else
|
||||
_shutdown "${SHUTDOWN_MESSAGE}"
|
||||
|
|
|
@ -14,8 +14,7 @@ function _create_lock
|
|||
do
|
||||
# Handle stale lock files left behind on crashes
|
||||
# or premature/non-graceful exits of containers while they're making changes
|
||||
if [[ -n "$(find "${LOCK_FILE}" -mmin +1 2>/dev/null)" ]]
|
||||
then
|
||||
if [[ -n "$(find "${LOCK_FILE}" -mmin +1 2>/dev/null)" ]]; then
|
||||
_log 'warn' 'Lock file older than 1 minute - removing stale lock file'
|
||||
rm -f "${LOCK_FILE}"
|
||||
else
|
||||
|
@ -33,8 +32,7 @@ function _remove_lock
|
|||
{
|
||||
LOCK_FILE="${LOCK_FILE:-"/tmp/docker-mailserver/${SCRIPT_NAME}.lock"}"
|
||||
[[ -z "${LOCK_ID}" ]] && _exit_with_error "Cannot remove '${LOCK_FILE}' as there is no LOCK_ID set"
|
||||
if [[ -e "${LOCK_FILE}" ]] && grep -q "${LOCK_ID}" "${LOCK_FILE}" # Ensure we don't delete a lock that's not ours
|
||||
then
|
||||
if [[ -e "${LOCK_FILE}" ]] && grep -q "${LOCK_ID}" "${LOCK_FILE}"; then # Ensure we don't delete a lock that's not ours
|
||||
rm -f "${LOCK_FILE}"
|
||||
_log 'trace' "Removed lock '${LOCK_FILE}'"
|
||||
fi
|
||||
|
|
|
@ -44,14 +44,12 @@ RESET=$(echo -ne '\e[0m')
|
|||
# is missing. Both failures will return with exit code '1'.
|
||||
function _log
|
||||
{
|
||||
if [[ -z ${1+set} ]]
|
||||
then
|
||||
if [[ -z ${1+set} ]]; then
|
||||
_log 'error' "Call to '_log' is missing a valid log level"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -z ${2+set} ]]
|
||||
then
|
||||
if [[ -z ${2+set} ]]; then
|
||||
_log 'error' "Call to '_log' is missing a message to log"
|
||||
return 1
|
||||
fi
|
||||
|
@ -100,8 +98,7 @@ function _log
|
|||
|
||||
MESSAGE+="${RESET}] ${2}"
|
||||
|
||||
if [[ ${1} =~ ^(warn|error)$ ]]
|
||||
then
|
||||
if [[ ${1} =~ ^(warn|error)$ ]]; then
|
||||
echo -e "${MESSAGE}" >&2
|
||||
else
|
||||
echo -e "${MESSAGE}"
|
||||
|
@ -120,11 +117,9 @@ function _log_with_date
|
|||
# use the default log level.
|
||||
function _get_log_level_or_default
|
||||
{
|
||||
if [[ -n ${LOG_LEVEL+set} ]]
|
||||
then
|
||||
if [[ -n ${LOG_LEVEL+set} ]]; then
|
||||
echo "${LOG_LEVEL}"
|
||||
elif [[ -e /etc/dms-settings ]] && grep -q -E "^LOG_LEVEL='[a-z]+'" /etc/dms-settings
|
||||
then
|
||||
elif [[ -e /etc/dms-settings ]] && grep -q -E "^LOG_LEVEL='[a-z]+'" /etc/dms-settings; then
|
||||
grep '^LOG_LEVEL=' /etc/dms-settings | cut -d "'" -f 2
|
||||
else
|
||||
echo 'info'
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
|
||||
function _mask_ip_digit
|
||||
{
|
||||
if [[ ${1} -ge 8 ]]
|
||||
then
|
||||
if [[ ${1} -ge 8 ]]; then
|
||||
MASK=255
|
||||
elif [[ ${1} -le 0 ]]
|
||||
then
|
||||
elif [[ ${1} -le 0 ]]; then
|
||||
MASK=0
|
||||
else
|
||||
VALUES=(0 128 192 224 240 248 252 254 255)
|
||||
|
|
|
@ -33,8 +33,7 @@ function _create_vhost
|
|||
{
|
||||
: >"${DATABASE_VHOST}"
|
||||
|
||||
if [[ -f ${TMP_VHOST} ]]
|
||||
then
|
||||
if [[ -f ${TMP_VHOST} ]]; then
|
||||
sort < "${TMP_VHOST}" | uniq >>"${DATABASE_VHOST}"
|
||||
rm "${TMP_VHOST}"
|
||||
fi
|
||||
|
@ -48,8 +47,7 @@ function _vhost_collect_postfix_domains
|
|||
local DOMAIN UNAME
|
||||
|
||||
# getting domains FROM mail accounts
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]]; then
|
||||
while IFS=$'|' read -r LOGIN _
|
||||
do
|
||||
DOMAIN=$(echo "${LOGIN}" | cut -d @ -f2)
|
||||
|
@ -58,8 +56,7 @@ function _vhost_collect_postfix_domains
|
|||
fi
|
||||
|
||||
# getting domains FROM mail aliases
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]]; then
|
||||
while read -r FROM _
|
||||
do
|
||||
UNAME=$(echo "${FROM}" | cut -d @ -f1)
|
||||
|
|
|
@ -77,8 +77,7 @@ function _relayhost_sasl
|
|||
chmod 0600 /etc/postfix/sasl_passwd
|
||||
|
||||
local DATABASE_SASL_PASSWD='/tmp/docker-mailserver/postfix-sasl-password.cf'
|
||||
if [[ -f ${DATABASE_SASL_PASSWD} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_SASL_PASSWD} ]]; then
|
||||
# Add domain-specific auth from config file:
|
||||
_get_valid_lines_from_file "${DATABASE_SASL_PASSWD}" >> /etc/postfix/sasl_passwd
|
||||
|
||||
|
@ -87,8 +86,7 @@ function _relayhost_sasl
|
|||
fi
|
||||
|
||||
# Add an authenticated relay host defined via ENV config:
|
||||
if [[ -n ${RELAY_USER} ]] && [[ -n ${RELAY_PASSWORD} ]]
|
||||
then
|
||||
if [[ -n ${RELAY_USER} ]] && [[ -n ${RELAY_PASSWORD} ]]; then
|
||||
echo "$(_env_relay_host) ${RELAY_USER}:${RELAY_PASSWORD}" >> /etc/postfix/sasl_passwd
|
||||
fi
|
||||
|
||||
|
@ -122,8 +120,7 @@ function _populate_relayhost_map
|
|||
|
||||
# This config is mostly compatible with `/etc/postfix/relayhost_map`, but additionally supports
|
||||
# not providing a relay host for a sender domain to opt-out of RELAY_HOST? (2nd half of function)
|
||||
if [[ -f /tmp/docker-mailserver/postfix-relaymap.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/postfix-relaymap.cf ]]; then
|
||||
_log 'trace' "Adding relay mappings from postfix-relaymap.cf"
|
||||
|
||||
# Match two values with some white-space between them (eg: `@example.test [relay.service.test]:465`):
|
||||
|
@ -161,8 +158,7 @@ function _populate_relayhost_map
|
|||
# DOMAIN_PART not already present in `/etc/postfix/relayhost_map`, and not listed as a relay opt-out domain in `postfix-relaymap.cf`
|
||||
# `^@${DOMAIN_PART}\b` - To check for existing entry, the `\b` avoids accidental partial matches on similar domain parts.
|
||||
# `^\s*@${DOMAIN_PART}\s*$` - Matches line with only a domain part (eg: @example.test) to avoid including a mapping for those domains to the RELAY_HOST.
|
||||
if ! grep -q -e "^@${DOMAIN_PART}\b" /etc/postfix/relayhost_map && ! grep -qs -e "^\s*@${DOMAIN_PART}\s*$" /tmp/docker-mailserver/postfix-relaymap.cf
|
||||
then
|
||||
if ! grep -q -e "^@${DOMAIN_PART}\b" /etc/postfix/relayhost_map && ! grep -qs -e "^\s*@${DOMAIN_PART}\s*$" /tmp/docker-mailserver/postfix-relaymap.cf; then
|
||||
_log 'trace' "Adding relay mapping for ${DOMAIN_PART}"
|
||||
echo "@${DOMAIN_PART} $(_env_relay_host)" >> /etc/postfix/relayhost_map
|
||||
fi
|
||||
|
@ -183,14 +179,12 @@ function _setup_relayhost
|
|||
{
|
||||
_log 'debug' 'Setting up Postfix Relay Hosts'
|
||||
|
||||
if [[ -n ${DEFAULT_RELAY_HOST} ]]
|
||||
then
|
||||
if [[ -n ${DEFAULT_RELAY_HOST} ]]; then
|
||||
_log 'trace' "Setting default relay host ${DEFAULT_RELAY_HOST} to /etc/postfix/main.cf"
|
||||
postconf "relayhost = ${DEFAULT_RELAY_HOST}"
|
||||
fi
|
||||
|
||||
if [[ -n ${RELAY_HOST} ]]
|
||||
then
|
||||
if [[ -n ${RELAY_HOST} ]]; then
|
||||
_log 'trace' "Setting up relay hosts (default: ${RELAY_HOST})"
|
||||
|
||||
_relayhost_sasl
|
||||
|
@ -202,8 +196,7 @@ function _setup_relayhost
|
|||
|
||||
function _rebuild_relayhost
|
||||
{
|
||||
if [[ -n ${RELAY_HOST} ]]
|
||||
then
|
||||
if [[ -n ${RELAY_HOST} ]]; then
|
||||
_relayhost_sasl
|
||||
_populate_relayhost_map
|
||||
fi
|
||||
|
|
|
@ -8,8 +8,7 @@ function _setup_dhparam
|
|||
|
||||
_log 'debug' "Setting up ${DH_SERVICE} dhparam"
|
||||
|
||||
if [[ -f ${DH_CUSTOM} ]]
|
||||
then # use custom supplied dh params (assumes they're probably insecure)
|
||||
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}'"
|
||||
|
||||
|
@ -39,8 +38,7 @@ function _setup_ssl
|
|||
local DOVECOT_CERT=${1}
|
||||
|
||||
# If a 2nd param is provided, a separate key and cert was received instead of a fullkeychain
|
||||
if [[ -n ${2} ]]
|
||||
then
|
||||
if [[ -n ${2} ]]; then
|
||||
local PRIVATE_KEY=$1
|
||||
local CERT_CHAIN=$2
|
||||
|
||||
|
@ -117,22 +115,18 @@ function _setup_ssl
|
|||
# NOTE: See the `SSL_TYPE=letsencrypt` case below for more details.
|
||||
function _traefik_support
|
||||
{
|
||||
if [[ -f /etc/letsencrypt/acme.json ]]
|
||||
then
|
||||
if [[ -f /etc/letsencrypt/acme.json ]]; then
|
||||
# Variable only intended for troubleshooting via debug output
|
||||
local EXTRACTED_DOMAIN
|
||||
|
||||
# Conditional handling depends on the success of `_extract_certs_from_acme`,
|
||||
# Failure tries the next fallback FQDN to try extract a certificate from.
|
||||
# Subshell not used in conditional to ensure extraction log output is still captured
|
||||
if [[ -n ${SSL_DOMAIN} ]] && _extract_certs_from_acme "${SSL_DOMAIN}"
|
||||
then
|
||||
if [[ -n ${SSL_DOMAIN} ]] && _extract_certs_from_acme "${SSL_DOMAIN}"; then
|
||||
EXTRACTED_DOMAIN=('SSL_DOMAIN' "${SSL_DOMAIN}")
|
||||
elif _extract_certs_from_acme "${HOSTNAME}"
|
||||
then
|
||||
elif _extract_certs_from_acme "${HOSTNAME}"; then
|
||||
EXTRACTED_DOMAIN=('HOSTNAME' "${HOSTNAME}")
|
||||
elif _extract_certs_from_acme "${DOMAINNAME}"
|
||||
then
|
||||
elif _extract_certs_from_acme "${DOMAINNAME}"; then
|
||||
EXTRACTED_DOMAIN=('DOMAINNAME' "${DOMAINNAME}")
|
||||
else
|
||||
_log 'warn' "letsencrypt (acme.json) failed to identify a certificate to extract"
|
||||
|
@ -220,8 +214,7 @@ function _setup_ssl
|
|||
local TMP_KEY_WITH_FULLCHAIN="${TMP_DMS_TLS_PATH}/${COMBINED_PEM_NAME}"
|
||||
local KEY_WITH_FULLCHAIN="${DMS_TLS_PATH}/${COMBINED_PEM_NAME}"
|
||||
|
||||
if [[ -f ${TMP_KEY_WITH_FULLCHAIN} ]]
|
||||
then
|
||||
if [[ -f ${TMP_KEY_WITH_FULLCHAIN} ]]; then
|
||||
cp "${TMP_KEY_WITH_FULLCHAIN}" "${KEY_WITH_FULLCHAIN}"
|
||||
chmod 600 "${KEY_WITH_FULLCHAIN}"
|
||||
|
||||
|
@ -241,8 +234,7 @@ function _setup_ssl
|
|||
local CERT_CHAIN="${DMS_TLS_PATH}/cert"
|
||||
|
||||
# Fail early:
|
||||
if [[ -z ${SSL_KEY_PATH} ]] && [[ -z ${SSL_CERT_PATH} ]]
|
||||
then
|
||||
if [[ -z ${SSL_KEY_PATH} ]] && [[ -z ${SSL_CERT_PATH} ]]; then
|
||||
_dms_panic__no_env 'SSL_KEY_PATH or SSL_CERT_PATH' "${SCOPE_SSL_TYPE}"
|
||||
fi
|
||||
|
||||
|
@ -254,8 +246,7 @@ function _setup_ssl
|
|||
_dms_panic__no_file "(ALT) ${SSL_ALT_KEY_PATH} or ${SSL_ALT_CERT_PATH}" "${SCOPE_SSL_TYPE}"
|
||||
fi
|
||||
|
||||
if [[ -f ${SSL_KEY_PATH} ]] && [[ -f ${SSL_CERT_PATH} ]]
|
||||
then
|
||||
if [[ -f ${SSL_KEY_PATH} ]] && [[ -f ${SSL_CERT_PATH} ]]; then
|
||||
cp "${SSL_KEY_PATH}" "${PRIVATE_KEY}"
|
||||
cp "${SSL_CERT_PATH}" "${CERT_CHAIN}"
|
||||
chmod 600 "${PRIVATE_KEY}"
|
||||
|
@ -264,8 +255,7 @@ function _setup_ssl
|
|||
_set_certificate "${PRIVATE_KEY}" "${CERT_CHAIN}"
|
||||
|
||||
# Support for a fallback certificate, useful for hybrid/dual ECDSA + RSA certs
|
||||
if [[ -n ${SSL_ALT_KEY_PATH} ]] && [[ -n ${SSL_ALT_CERT_PATH} ]]
|
||||
then
|
||||
if [[ -n ${SSL_ALT_KEY_PATH} ]] && [[ -n ${SSL_ALT_CERT_PATH} ]]; then
|
||||
_log 'trace' "Configuring fallback certificates using key ${SSL_ALT_KEY_PATH} and cert ${SSL_ALT_CERT_PATH}"
|
||||
|
||||
_set_alt_certificate "${SSL_ALT_KEY_PATH}" "${SSL_ALT_CERT_PATH}"
|
||||
|
@ -393,14 +383,11 @@ function _find_letsencrypt_domain
|
|||
{
|
||||
local LETSENCRYPT_DOMAIN
|
||||
|
||||
if [[ -n ${SSL_DOMAIN} ]] && [[ -e /etc/letsencrypt/live/$(_strip_wildcard_prefix "${SSL_DOMAIN}")/fullchain.pem ]]
|
||||
then
|
||||
if [[ -n ${SSL_DOMAIN} ]] && [[ -e /etc/letsencrypt/live/$(_strip_wildcard_prefix "${SSL_DOMAIN}")/fullchain.pem ]]; then
|
||||
LETSENCRYPT_DOMAIN=$(_strip_wildcard_prefix "${SSL_DOMAIN}")
|
||||
elif [[ -e /etc/letsencrypt/live/${HOSTNAME}/fullchain.pem ]]
|
||||
then
|
||||
elif [[ -e /etc/letsencrypt/live/${HOSTNAME}/fullchain.pem ]]; then
|
||||
LETSENCRYPT_DOMAIN=${HOSTNAME}
|
||||
elif [[ -e /etc/letsencrypt/live/${DOMAINNAME}/fullchain.pem ]]
|
||||
then
|
||||
elif [[ -e /etc/letsencrypt/live/${DOMAINNAME}/fullchain.pem ]]; then
|
||||
LETSENCRYPT_DOMAIN=${DOMAINNAME}
|
||||
else
|
||||
_log 'error' "Cannot find a valid DOMAIN for '/etc/letsencrypt/live/<DOMAIN>/', tried: '${SSL_DOMAIN}', '${HOSTNAME}', '${DOMAINNAME}'"
|
||||
|
@ -416,16 +403,13 @@ function _find_letsencrypt_key
|
|||
local LETSENCRYPT_KEY
|
||||
|
||||
local LETSENCRYPT_DOMAIN=${1}
|
||||
if [[ -z ${LETSENCRYPT_DOMAIN} ]]
|
||||
then
|
||||
if [[ -z ${LETSENCRYPT_DOMAIN} ]]; then
|
||||
_dms_panic__misconfigured 'LETSENCRYPT_DOMAIN' '_find_letsencrypt_key'
|
||||
fi
|
||||
|
||||
if [[ -e /etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/privkey.pem ]]
|
||||
then
|
||||
if [[ -e /etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/privkey.pem ]]; then
|
||||
LETSENCRYPT_KEY='privkey'
|
||||
elif [[ -e /etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/key.pem ]]
|
||||
then
|
||||
elif [[ -e /etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/key.pem ]]; then
|
||||
LETSENCRYPT_KEY='key'
|
||||
else
|
||||
_log 'error' "Cannot find key file ('privkey.pem' or 'key.pem') in '/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/'"
|
||||
|
@ -438,8 +422,7 @@ function _find_letsencrypt_key
|
|||
function _extract_certs_from_acme
|
||||
{
|
||||
local CERT_DOMAIN=${1}
|
||||
if [[ -z ${CERT_DOMAIN} ]]
|
||||
then
|
||||
if [[ -z ${CERT_DOMAIN} ]]; then
|
||||
_log 'warn' "_extract_certs_from_acme | CERT_DOMAIN is empty"
|
||||
return 1
|
||||
fi
|
||||
|
@ -448,16 +431,14 @@ function _extract_certs_from_acme
|
|||
KEY=$(acme_extract.py /etc/letsencrypt/acme.json "${CERT_DOMAIN}" --key)
|
||||
CERT=$(acme_extract.py /etc/letsencrypt/acme.json "${CERT_DOMAIN}" --cert)
|
||||
|
||||
if [[ -z ${KEY} ]] || [[ -z ${CERT} ]]
|
||||
then
|
||||
if [[ -z ${KEY} ]] || [[ -z ${CERT} ]]; then
|
||||
_log 'warn' "_extract_certs_from_acme | Unable to find key and/or cert for '${CERT_DOMAIN}' in '/etc/letsencrypt/acme.json'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Currently we advise SSL_DOMAIN for wildcard support using a `*.example.com` value,
|
||||
# The filepath however should be `example.com`, avoiding the wildcard part:
|
||||
if [[ ${SSL_DOMAIN} == "${CERT_DOMAIN}" ]]
|
||||
then
|
||||
if [[ ${SSL_DOMAIN} == "${CERT_DOMAIN}" ]]; then
|
||||
CERT_DOMAIN=$(_strip_wildcard_prefix "${SSL_DOMAIN}")
|
||||
fi
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@ function _get_valid_lines_from_file
|
|||
# and it will return its value stored in /etc/dms-settings
|
||||
function _get_dms_env_value
|
||||
{
|
||||
if [[ -f /etc/dms-settings ]]
|
||||
then
|
||||
if [[ -f /etc/dms-settings ]]; then
|
||||
grep "^${1}=" /etc/dms-settings | cut -d "'" -f 2
|
||||
else
|
||||
_log 'warn' "Call to '_get_dms_env_value' but '/etc/dms-settings' is not present"
|
||||
|
@ -34,8 +33,7 @@ function _get_dms_env_value
|
|||
function _chown_var_mail_if_necessary
|
||||
{
|
||||
# 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 \) | read -r
|
||||
then
|
||||
if find /var/mail -maxdepth 3 -a \( \! -user 5000 -o \! -group 5000 \) | read -r; then
|
||||
_log 'trace' 'Fixing /var/mail permissions'
|
||||
chown -R 5000:5000 /var/mail || return 1
|
||||
fi
|
||||
|
@ -59,8 +57,7 @@ function _require_n_parameters_or_print_usage
|
|||
# https://github.com/docker-mailserver/docker-mailserver/issues/2985
|
||||
function _adjust_mtime_for_postfix_maincf
|
||||
{
|
||||
if [[ $(( $(date '+%s') - $(stat -c '%Y' '/etc/postfix/main.cf') )) -lt 2 ]]
|
||||
then
|
||||
if [[ $(( $(date '+%s') - $(stat -c '%Y' '/etc/postfix/main.cf') )) -lt 2 ]]; then
|
||||
touch -d '2 seconds ago' /etc/postfix/main.cf
|
||||
fi
|
||||
}
|
||||
|
@ -97,14 +94,11 @@ function _reload_postfix
|
|||
# 2. The second argument is a path to a file that does not exist
|
||||
function _replace_by_env_in_file
|
||||
{
|
||||
if [[ -z ${1+set} ]]
|
||||
then
|
||||
if [[ -z ${1+set} ]]; then
|
||||
_dms_panic__invalid_value 'first argument unset' 'utils.sh:_replace_by_env_in_file'
|
||||
elif [[ -z ${2+set} ]]
|
||||
then
|
||||
elif [[ -z ${2+set} ]]; then
|
||||
_dms_panic__invalid_value 'second argument unset' 'utils.sh:_replace_by_env_in_file'
|
||||
elif [[ ! -f ${2} ]]
|
||||
then
|
||||
elif [[ ! -f ${2} ]]; then
|
||||
_dms_panic__invalid_value "file '${2}' does not exist" 'utils.sh:_replace_by_env_in_file'
|
||||
fi
|
||||
|
||||
|
|
|
@ -42,8 +42,7 @@ function _register_functions
|
|||
_register_setup_function '_setup_logs_general'
|
||||
_register_setup_function '_setup_timezone'
|
||||
|
||||
if [[ ${SMTP_ONLY} -ne 1 ]]
|
||||
then
|
||||
if [[ ${SMTP_ONLY} -ne 1 ]]; then
|
||||
_register_setup_function '_setup_dovecot'
|
||||
_register_setup_function '_setup_dovecot_sieve'
|
||||
_register_setup_function '_setup_dovecot_dhparam'
|
||||
|
@ -69,8 +68,7 @@ function _register_functions
|
|||
;;
|
||||
esac
|
||||
|
||||
if [[ ${ENABLE_SASLAUTHD} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_SASLAUTHD} -eq 1 ]]; then
|
||||
_environment_variables_saslauthd
|
||||
_register_setup_function '_setup_saslauthd'
|
||||
fi
|
||||
|
@ -99,8 +97,7 @@ function _register_functions
|
|||
|
||||
_register_setup_function '_setup_getmail'
|
||||
|
||||
if [[ ${ENABLE_SRS} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_SRS} -eq 1 ]]; then
|
||||
_register_setup_function '_setup_SRS'
|
||||
_register_start_daemon '_start_daemon_postsrsd'
|
||||
fi
|
||||
|
|
|
@ -21,8 +21,7 @@ function _check_improper_restart
|
|||
{
|
||||
_log 'debug' 'Checking for improper restart'
|
||||
|
||||
if [[ -f /CONTAINER_START ]]
|
||||
then
|
||||
if [[ -f /CONTAINER_START ]]; then
|
||||
_log 'warn' 'This container was (likely) improperly restarted which can result in undefined behavior'
|
||||
_log 'warn' 'Please destroy the container properly and then start DMS again'
|
||||
fi
|
||||
|
@ -36,8 +35,7 @@ function _check_hostname
|
|||
_log 'debug' "Hostname has been set to ${HOSTNAME}"
|
||||
|
||||
# HOSTNAME should be an FQDN (eg: hostname.domain)
|
||||
if ! grep -q -E '^(\S+[.]\S+)$' <<< "${HOSTNAME}"
|
||||
then
|
||||
if ! grep -q -E '^(\S+[.]\S+)$' <<< "${HOSTNAME}"; then
|
||||
_dms_panic__general 'Setting hostname/domainname is required'
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -26,8 +26,7 @@ function _default_start_daemon
|
|||
RESULT=$(supervisorctl start "${1}" 2>&1)
|
||||
|
||||
# shellcheck disable=SC2181
|
||||
if [[ ${?} -ne 0 ]]
|
||||
then
|
||||
if [[ ${?} -ne 0 ]]; then
|
||||
_log 'error' "${RESULT}"
|
||||
_dms_panic__fail_init "${1}"
|
||||
fi
|
||||
|
@ -61,8 +60,7 @@ function _start_daemon_postfix
|
|||
|
||||
function _start_daemon_fetchmail
|
||||
{
|
||||
if [[ ${FETCHMAIL_PARALLEL} -eq 1 ]]
|
||||
then
|
||||
if [[ ${FETCHMAIL_PARALLEL} -eq 1 ]]; then
|
||||
local COUNTER=0
|
||||
for _ in /etc/fetchmailrc.d/fetchmail-*.rc
|
||||
do
|
||||
|
|
|
@ -32,8 +32,7 @@ function _early_supervisor_setup
|
|||
{
|
||||
SUPERVISOR_LOGLEVEL="${SUPERVISOR_LOGLEVEL:-warn}"
|
||||
|
||||
if ! grep -q "loglevel = ${SUPERVISOR_LOGLEVEL}" /etc/supervisor/supervisord.conf
|
||||
then
|
||||
if ! grep -q "loglevel = ${SUPERVISOR_LOGLEVEL}" /etc/supervisor/supervisord.conf; then
|
||||
case "${SUPERVISOR_LOGLEVEL}" in
|
||||
( 'critical' | 'error' | 'info' | 'debug' )
|
||||
sed -i -E \
|
||||
|
@ -64,8 +63,7 @@ function _setup_timezone
|
|||
|
||||
local ZONEINFO_FILE="/usr/share/zoneinfo/${TZ}"
|
||||
|
||||
if [[ ! -e ${ZONEINFO_FILE} ]]
|
||||
then
|
||||
if [[ ! -e ${ZONEINFO_FILE} ]]; then
|
||||
_log 'warn' "Cannot find timezone '${TZ}'"
|
||||
return 1
|
||||
fi
|
||||
|
@ -87,8 +85,7 @@ function _setup_apply_fixes_after_configuration
|
|||
touch /dev/shm/supervisor.sock
|
||||
|
||||
_log 'debug' 'Checking /var/mail permissions'
|
||||
if ! _chown_var_mail_if_necessary
|
||||
then
|
||||
if ! _chown_var_mail_if_necessary; then
|
||||
_dms_panic__general 'Failed to fix /var/mail permissions'
|
||||
fi
|
||||
|
||||
|
@ -100,8 +97,7 @@ function _run_user_patches
|
|||
{
|
||||
local USER_PATCHES='/tmp/docker-mailserver/user-patches.sh'
|
||||
|
||||
if [[ -f ${USER_PATCHES} ]]
|
||||
then
|
||||
if [[ -f ${USER_PATCHES} ]]; then
|
||||
_log 'debug' 'Applying user patches'
|
||||
/bin/bash "${USER_PATCHES}"
|
||||
else
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
# `smtpd_milters` milters options.
|
||||
function _setup_opendkim
|
||||
{
|
||||
if [[ ${ENABLE_OPENDKIM} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_OPENDKIM} -eq 1 ]]; then
|
||||
_log 'debug' 'Configuring DKIM'
|
||||
|
||||
mkdir -p /etc/opendkim/keys/
|
||||
|
@ -24,8 +23,7 @@ function _setup_opendkim
|
|||
/etc/postfix/main.cf
|
||||
|
||||
# check if any keys are available
|
||||
if [[ -e /tmp/docker-mailserver/opendkim/KeyTable ]]
|
||||
then
|
||||
if [[ -e /tmp/docker-mailserver/opendkim/KeyTable ]]; then
|
||||
cp -a /tmp/docker-mailserver/opendkim/* /etc/opendkim/
|
||||
_log 'trace' "DKIM keys added for: $(find /etc/opendkim/keys/ -maxdepth 1 -type f -printf '%f ')"
|
||||
chown -R opendkim:opendkim /etc/opendkim/
|
||||
|
@ -35,8 +33,7 @@ function _setup_opendkim
|
|||
fi
|
||||
|
||||
# setup nameservers parameter from /etc/resolv.conf if not defined
|
||||
if ! grep -q '^Nameservers' /etc/opendkim.conf
|
||||
then
|
||||
if ! grep -q '^Nameservers' /etc/opendkim.conf; then
|
||||
local NAMESERVER_IPS
|
||||
NAMESERVER_IPS=$(grep '^nameserver' /etc/resolv.conf | awk -F " " '{print $2}' | paste -sd ',' -)
|
||||
echo "Nameservers ${NAMESERVER_IPS}" >>/etc/opendkim.conf
|
||||
|
@ -59,8 +56,7 @@ function _setup_opendkim
|
|||
# `smtpd_milters` milters options.
|
||||
function _setup_opendmarc
|
||||
{
|
||||
if [[ ${ENABLE_OPENDMARC} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_OPENDMARC} -eq 1 ]]; then
|
||||
# TODO When disabling SPF is possible, add a check whether DKIM and SPF is disabled
|
||||
# for DMARC to work, you should have at least one enabled
|
||||
# (see RFC 7489 https://www.rfc-editor.org/rfc/rfc7489#page-24)
|
||||
|
@ -89,8 +85,7 @@ function _setup_opendmarc
|
|||
# using Rspamd, you will likely want to turn that off.
|
||||
function _setup_policyd_spf
|
||||
{
|
||||
if [[ ${ENABLE_POLICYD_SPF} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_POLICYD_SPF} -eq 1 ]]; then
|
||||
_log 'debug' 'Configuring policyd-spf'
|
||||
cat >>/etc/postfix/master.cf <<EOF
|
||||
|
||||
|
|
|
@ -14,8 +14,7 @@ function _setup_dovecot
|
|||
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
|
||||
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
|
||||
|
||||
|
@ -39,8 +38,7 @@ function _setup_dovecot
|
|||
|
||||
esac
|
||||
|
||||
if [[ ${ENABLE_POP3} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_POP3} -eq 1 ]]; then
|
||||
_log 'debug' 'Enabling POP3 services'
|
||||
mv /etc/dovecot/protocols.d/pop3d.protocol.disab /etc/dovecot/protocols.d/pop3d.protocol
|
||||
fi
|
||||
|
@ -55,30 +53,25 @@ function _setup_dovecot_sieve
|
|||
|
||||
# enable Managesieve service by setting the symlink
|
||||
# to the configuration file Dovecot will actually find
|
||||
if [[ ${ENABLE_MANAGESIEVE} -eq 1 ]]
|
||||
then
|
||||
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
|
||||
|
||||
if [[ -d /tmp/docker-mailserver/sieve-filter ]]
|
||||
then
|
||||
if [[ -d /tmp/docker-mailserver/sieve-filter ]]; then
|
||||
cp /tmp/docker-mailserver/sieve-filter/* /usr/lib/dovecot/sieve-filter/
|
||||
fi
|
||||
if [[ -d /tmp/docker-mailserver/sieve-pipe ]]
|
||||
then
|
||||
if [[ -d /tmp/docker-mailserver/sieve-pipe ]]; then
|
||||
cp /tmp/docker-mailserver/sieve-pipe/* /usr/lib/dovecot/sieve-pipe/
|
||||
fi
|
||||
|
||||
if [[ -f /tmp/docker-mailserver/before.dovecot.sieve ]]
|
||||
then
|
||||
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
|
||||
fi
|
||||
if [[ -f /tmp/docker-mailserver/after.dovecot.sieve ]]
|
||||
then
|
||||
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
|
||||
|
@ -95,11 +88,9 @@ 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 [[ ${ACCOUNT_PROVISIONER} != 'FILE' ]] || [[ ${SMTP_ONLY} -eq 1 ]] || [[ ${ENABLE_QUOTAS} -eq 0 ]]
|
||||
then
|
||||
if [[ ${ACCOUNT_PROVISIONER} != 'FILE' ]] || [[ ${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
|
||||
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" \
|
||||
|
@ -112,8 +103,7 @@ function _setup_dovecot_quota
|
|||
# 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
|
||||
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" \
|
||||
|
@ -134,8 +124,7 @@ function _setup_dovecot_quota
|
|||
"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
|
||||
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
|
||||
|
@ -154,8 +143,7 @@ function _setup_dovecot_local_user
|
|||
|
||||
_log 'debug' 'Setting up Dovecot Local User'
|
||||
|
||||
if [[ ! -f /tmp/docker-mailserver/postfix-accounts.cf ]]
|
||||
then
|
||||
if [[ ! -f /tmp/docker-mailserver/postfix-accounts.cf ]]; then
|
||||
_log 'trace' "No mail accounts to create - '/tmp/docker-mailserver/postfix-accounts.cf' is missing"
|
||||
fi
|
||||
|
||||
|
@ -165,8 +153,7 @@ function _setup_dovecot_local_user
|
|||
|
||||
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
|
||||
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 mail account to start Dovecot ($(( ( COUNTER + 1 ) * SLEEP_PERIOD ))s left for account creation before shutdown)"
|
||||
|
@ -190,11 +177,9 @@ function _setup_dovecot_inet_protocols
|
|||
|
||||
local PROTOCOL
|
||||
# https://dovecot.org/doc/dovecot-example.conf
|
||||
if [[ ${DOVECOT_INET_PROTOCOLS} == "ipv4" ]]
|
||||
then
|
||||
if [[ ${DOVECOT_INET_PROTOCOLS} == "ipv4" ]]; then
|
||||
PROTOCOL='*' # IPv4 only
|
||||
elif [[ ${DOVECOT_INET_PROTOCOLS} == "ipv6" ]]
|
||||
then
|
||||
elif [[ ${DOVECOT_INET_PROTOCOLS} == "ipv6" ]]; then
|
||||
PROTOCOL='[::]' # IPv6 only
|
||||
else
|
||||
# Unknown value, panic.
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
function _setup_fetchmail
|
||||
{
|
||||
if [[ ${ENABLE_FETCHMAIL} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_FETCHMAIL} -eq 1 ]]; then
|
||||
_log 'trace' 'Enabling and configuring Fetchmail'
|
||||
|
||||
local CONFIGURATION FETCHMAILRC
|
||||
|
@ -11,8 +10,7 @@ function _setup_fetchmail
|
|||
CONFIGURATION='/tmp/docker-mailserver/fetchmail.cf'
|
||||
FETCHMAILRC='/etc/fetchmailrc'
|
||||
|
||||
if [[ -f ${CONFIGURATION} ]]
|
||||
then
|
||||
if [[ -f ${CONFIGURATION} ]]; then
|
||||
cat /etc/fetchmailrc_general "${CONFIGURATION}" >"${FETCHMAILRC}"
|
||||
else
|
||||
cat /etc/fetchmailrc_general >"${FETCHMAILRC}"
|
||||
|
@ -27,8 +25,7 @@ function _setup_fetchmail
|
|||
|
||||
function _setup_fetchmail_parallel
|
||||
{
|
||||
if [[ ${FETCHMAIL_PARALLEL} -eq 1 ]]
|
||||
then
|
||||
if [[ ${FETCHMAIL_PARALLEL} -eq 1 ]]; then
|
||||
_log 'trace' 'Enabling and configuring Fetchmail parallel'
|
||||
mkdir /etc/fetchmailrc.d/
|
||||
|
||||
|
@ -44,16 +41,13 @@ function _setup_fetchmail_parallel
|
|||
local FETCHMAILRCD='/etc/fetchmailrc.d'
|
||||
local DEFAULT_FILE="${FETCHMAILRCD}/defaults"
|
||||
|
||||
if [[ ! -r ${FETCHMAILRC} ]]
|
||||
then
|
||||
if [[ ! -r ${FETCHMAILRC} ]]; then
|
||||
_log 'warn' "File '${FETCHMAILRC}' not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -d ${FETCHMAILRCD} ]]
|
||||
then
|
||||
if ! mkdir "${FETCHMAILRCD}"
|
||||
then
|
||||
if [[ ! -d ${FETCHMAILRCD} ]]; then
|
||||
if ! mkdir "${FETCHMAILRCD}"; then
|
||||
_log 'warn' "Unable to create folder '${FETCHMAILRCD}'"
|
||||
return 1
|
||||
fi
|
||||
|
@ -62,8 +56,7 @@ function _setup_fetchmail_parallel
|
|||
local COUNTER=0 SERVER=0
|
||||
while read -r LINE
|
||||
do
|
||||
if [[ ${LINE} =~ poll ]]
|
||||
then
|
||||
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
|
||||
|
@ -71,8 +64,7 @@ function _setup_fetchmail_parallel
|
|||
SERVER=1
|
||||
cat "${DEFAULT_FILE}" >"${FETCHMAILRCD}/fetchmail-${COUNTER}.rc"
|
||||
echo "${LINE}" >>"${FETCHMAILRCD}/fetchmail-${COUNTER}.rc"
|
||||
elif [[ ${SERVER} -eq 0 ]]
|
||||
then
|
||||
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}"
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
function _setup_getmail
|
||||
{
|
||||
if [[ ${ENABLE_GETMAIL} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_GETMAIL} -eq 1 ]]; then
|
||||
_log 'trace' 'Preparing Getmail configuration'
|
||||
|
||||
local GETMAILRC ID CONFIGS
|
||||
|
@ -17,8 +16,7 @@ function _setup_getmail
|
|||
# Add a unique `message_log` config, then append users own config to the end.
|
||||
for FILE in /tmp/docker-mailserver/getmail-*.cf
|
||||
do
|
||||
if [[ -f ${FILE} ]]
|
||||
then
|
||||
if [[ -f ${FILE} ]]; then
|
||||
CONFIGS=1
|
||||
ID=$(cut -d '-' -f 3 <<< "${FILE}" | cut -d '.' -f 1)
|
||||
local GETMAIL_CONFIG="${GETMAILRC}/getmailrc-${ID}"
|
||||
|
@ -29,8 +27,7 @@ function _setup_getmail
|
|||
fi
|
||||
done
|
||||
|
||||
if [[ ${CONFIGS} -eq 1 ]]
|
||||
then
|
||||
if [[ ${CONFIGS} -eq 1 ]]; then
|
||||
cat >/etc/cron.d/getmail << EOF
|
||||
*/${GETMAIL_POLL} * * * * root /usr/local/bin/getmail-cron
|
||||
EOF
|
||||
|
|
|
@ -8,8 +8,7 @@ function _setup_ldap
|
|||
for i in 'users' 'groups' 'aliases' 'domains'
|
||||
do
|
||||
local FPATH="/tmp/docker-mailserver/ldap-${i}.cf"
|
||||
if [[ -f ${FPATH} ]]
|
||||
then
|
||||
if [[ -f ${FPATH} ]]; then
|
||||
cp "${FPATH}" "/etc/postfix/ldap-${i}.cf"
|
||||
fi
|
||||
done
|
||||
|
@ -46,8 +45,7 @@ function _setup_ldap
|
|||
|
||||
# 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
|
||||
if [[ ${DOVECOT_LDAP_MAPPING["DOVECOT_URIS"]} != *'://'* ]]; then
|
||||
DOVECOT_LDAP_MAPPING['DOVECOT_URIS']="ldap://${DOVECOT_LDAP_MAPPING["DOVECOT_URIS"]}"
|
||||
fi
|
||||
|
||||
|
@ -68,22 +66,19 @@ function _setup_ldap
|
|||
|
||||
_log 'trace' "Configuring LDAP"
|
||||
|
||||
if [[ -f /etc/postfix/ldap-users.cf ]]
|
||||
then
|
||||
if [[ -f /etc/postfix/ldap-users.cf ]]; then
|
||||
postconf '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
|
||||
if [[ -f /etc/postfix/ldap-domains.cf ]]; then
|
||||
postconf '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
|
||||
if [[ -f /etc/postfix/ldap-aliases.cf ]] && [[ -f /etc/postfix/ldap-groups.cf ]]; then
|
||||
postconf '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"
|
||||
|
|
|
@ -96,8 +96,7 @@ function _setup_logwatch
|
|||
LOGWATCH_FILE="/etc/cron.${LOGWATCH_INTERVAL}/logwatch"
|
||||
INTERVAL='--range Yesterday'
|
||||
|
||||
if [[ ${LOGWATCH_INTERVAL} == 'weekly' ]]
|
||||
then
|
||||
if [[ ${LOGWATCH_INTERVAL} == 'weekly' ]]; then
|
||||
INTERVAL="--range 'between -7 days and -1 days'"
|
||||
fi
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@ function _setup_save_states
|
|||
|
||||
STATEDIR='/var/mail-state'
|
||||
|
||||
if [[ ${ONE_DIR} -eq 1 ]] && [[ -d ${STATEDIR} ]]
|
||||
then
|
||||
if [[ ${ONE_DIR} -eq 1 ]] && [[ -d ${STATEDIR} ]]; then
|
||||
_log 'debug' "Consolidating all state onto ${STATEDIR}"
|
||||
|
||||
# Always enabled features:
|
||||
|
@ -42,13 +41,11 @@ function _setup_save_states
|
|||
DESTDIR="${DEST%/*}"
|
||||
|
||||
mkdir -p "${DESTDIR}"
|
||||
if [[ -f ${DEST} ]]
|
||||
then
|
||||
if [[ -f ${DEST} ]]; then
|
||||
_log 'trace' "Destination ${DEST} exists, linking ${SERVICEFILE} to it"
|
||||
# Original content from image no longer relevant, remove it:
|
||||
rm -f "${SERVICEFILE}"
|
||||
elif [[ -f "${SERVICEFILE}" ]]
|
||||
then
|
||||
elif [[ -f "${SERVICEFILE}" ]]; then
|
||||
_log 'trace' "Moving ${SERVICEFILE} to ${DEST}"
|
||||
# Empty volume was mounted, or new content from enabling a feature ENV:
|
||||
mv "${SERVICEFILE}" "${DEST}"
|
||||
|
@ -66,13 +63,11 @@ function _setup_save_states
|
|||
|
||||
# If relevant content is found in /var/mail-state (presumably a volume mount),
|
||||
# use it instead. Otherwise copy over any missing directories checked.
|
||||
if [[ -d ${DEST} ]]
|
||||
then
|
||||
if [[ -d ${DEST} ]]; then
|
||||
_log 'trace' "Destination ${DEST} exists, linking ${SERVICEDIR} to it"
|
||||
# Original content from image no longer relevant, remove it:
|
||||
rm -rf "${SERVICEDIR}"
|
||||
elif [[ -d ${SERVICEDIR} ]]
|
||||
then
|
||||
elif [[ -d ${SERVICEDIR} ]]; then
|
||||
_log 'trace' "Moving contents of ${SERVICEDIR} to ${DEST}"
|
||||
# Empty volume was mounted, or new content from enabling a feature ENV:
|
||||
mv "${SERVICEDIR}" "${DEST}"
|
||||
|
@ -117,8 +112,7 @@ function _setup_save_states
|
|||
# Ref: https://github.com/docker-mailserver/docker-mailserver/pull/3149#issuecomment-1454981309
|
||||
chmod 1730 "${STATEDIR}/spool-postfix/maildrop"
|
||||
chmod 2710 "${STATEDIR}/spool-postfix/public"
|
||||
elif [[ ${ONE_DIR} -eq 1 ]]
|
||||
then
|
||||
elif [[ ${ONE_DIR} -eq 1 ]]; then
|
||||
_log 'warn' "'ONE_DIR=1' but no volume was mounted to '${STATEDIR}'"
|
||||
else
|
||||
_log 'debug' 'Not consolidating state (because it has been disabled)'
|
||||
|
|
|
@ -19,8 +19,7 @@ function _setup_docker_permit
|
|||
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
|
||||
if [[ -z ${CONTAINER_IP} ]]; then
|
||||
_log 'error' 'Detecting the container IP address failed'
|
||||
_dms_panic__misconfigured 'NETWORK_INTERFACE' 'Network Setup [docker_permit]'
|
||||
fi
|
||||
|
|
|
@ -15,8 +15,7 @@ function _setup_postfix_early
|
|||
postconf "myhostname = ${HOSTNAME}"
|
||||
postconf "mydomain = ${DOMAINNAME}"
|
||||
|
||||
if [[ ${POSTFIX_INET_PROTOCOLS} != 'all' ]]
|
||||
then
|
||||
if [[ ${POSTFIX_INET_PROTOCOLS} != 'all' ]]; then
|
||||
__postfix__log 'trace' 'Setting up POSTFIX_INET_PROTOCOLS option'
|
||||
postconf "inet_protocols = ${POSTFIX_INET_PROTOCOLS}"
|
||||
fi
|
||||
|
@ -25,16 +24,14 @@ function _setup_postfix_early
|
|||
postconf 'smtputf8_enable = no'
|
||||
|
||||
__postfix__log 'trace' "Configuring SASLauthd"
|
||||
if [[ ${ENABLE_SASLAUTHD} -eq 1 ]] && [[ ! -f /etc/postfix/sasl/smtpd.conf ]]
|
||||
then
|
||||
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
|
||||
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
|
||||
|
@ -61,8 +58,7 @@ EOF
|
|||
__postfix__log 'trace' "Configuring virtual mailbox size limit to '${POSTFIX_MAILBOX_SIZE_LIMIT}'"
|
||||
postconf "virtual_mailbox_limit = ${POSTFIX_MAILBOX_SIZE_LIMIT}"
|
||||
|
||||
if [[ ${POSTFIX_REJECT_UNKNOWN_CLIENT_HOSTNAME} -eq 1 ]]
|
||||
then
|
||||
if [[ ${POSTFIX_REJECT_UNKNOWN_CLIENT_HOSTNAME} -eq 1 ]]; then
|
||||
__postfix__log 'trace' 'Enabling reject_unknown_client_hostname to dms_smtpd_sender_restrictions'
|
||||
sedfile -i -E \
|
||||
's|^(dms_smtpd_sender_restrictions = .*)|\1, reject_unknown_client_hostname|' \
|
||||
|
@ -75,21 +71,18 @@ function _setup_postfix_late
|
|||
_log 'debug' 'Configuring Postfix (late setup)'
|
||||
|
||||
__postfix__log 'trace' 'Configuring user access'
|
||||
if [[ -f /tmp/docker-mailserver/postfix-send-access.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/postfix-send-access.cf ]]; then
|
||||
sed -i -E 's|(smtpd_sender_restrictions =)|\1 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
|
||||
if [[ -f /tmp/docker-mailserver/postfix-receive-access.cf ]]; then
|
||||
sed -i -E 's|(smtpd_recipient_restrictions =)|\1 check_recipient_access texthash:/tmp/docker-mailserver/postfix-receive-access.cf,|' /etc/postfix/main.cf
|
||||
fi
|
||||
|
||||
__postfix__log 'trace' 'Configuring relay host'
|
||||
_setup_relayhost
|
||||
|
||||
if [[ -n ${POSTFIX_DAGENT} ]]
|
||||
then
|
||||
if [[ -n ${POSTFIX_DAGENT} ]]; then
|
||||
__postfix__log 'trace' "Changing virtual transport to '${POSTFIX_DAGENT}'"
|
||||
# Default value in main.cf should be 'lmtp:unix:/var/run/dovecot/lmtp'
|
||||
postconf "virtual_transport = ${POSTFIX_DAGENT}"
|
||||
|
@ -102,8 +95,7 @@ function __postfix__setup_override_configuration
|
|||
{
|
||||
__postfix__log 'debug' 'Overriding / adjusting configuration with user-supplied values'
|
||||
|
||||
if [[ -f /tmp/docker-mailserver/postfix-main.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/postfix-main.cf ]]; then
|
||||
cat /tmp/docker-mailserver/postfix-main.cf >>/etc/postfix/main.cf
|
||||
_adjust_mtime_for_postfix_maincf
|
||||
|
||||
|
@ -117,12 +109,10 @@ function __postfix__setup_override_configuration
|
|||
__postfix__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
|
||||
if [[ -f /tmp/docker-mailserver/postfix-master.cf ]]; then
|
||||
while read -r LINE
|
||||
do
|
||||
if [[ ${LINE} =~ ^[0-9a-z] ]]
|
||||
then
|
||||
if [[ ${LINE} =~ ^[0-9a-z] ]]; then
|
||||
postconf -P "${LINE}"
|
||||
fi
|
||||
done < /tmp/docker-mailserver/postfix-master.cf
|
||||
|
@ -155,21 +145,18 @@ function _setup_SRS
|
|||
|
||||
POSTSRSD_SECRET_FILE='/etc/postsrsd.secret'
|
||||
|
||||
if [[ -n ${SRS_SECRET} ]]
|
||||
then
|
||||
if [[ -n ${SRS_SECRET} ]]; then
|
||||
(
|
||||
umask 0077
|
||||
echo "${SRS_SECRET}" | tr ',' '\n' >"${POSTSRSD_SECRET_FILE}"
|
||||
)
|
||||
else
|
||||
if [[ ! -f ${POSTSRSD_SECRET_FILE} ]]
|
||||
then
|
||||
if [[ ! -f ${POSTSRSD_SECRET_FILE} ]]; then
|
||||
__generate_secret "${POSTSRSD_SECRET_FILE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n ${SRS_EXCLUDE_DOMAINS} ]]
|
||||
then
|
||||
if [[ -n ${SRS_EXCLUDE_DOMAINS} ]]; then
|
||||
sedfile -i -E \
|
||||
"s|^#?(SRS_EXCLUDE_DOMAINS=).*|\1${SRS_EXCLUDE_DOMAINS}|" \
|
||||
/etc/default/postsrsd
|
||||
|
|
|
@ -5,8 +5,7 @@ function _setup_saslauthd
|
|||
{
|
||||
_log 'debug' 'Setting up SASLAUTHD'
|
||||
|
||||
if [[ ! -f /etc/saslauthd.conf ]]
|
||||
then
|
||||
if [[ ! -f /etc/saslauthd.conf ]]; then
|
||||
_log 'trace' 'Creating /etc/saslauthd.conf'
|
||||
cat > /etc/saslauthd.conf << EOF
|
||||
ldap_servers: ${SASLAUTHD_LDAP_SERVER}
|
||||
|
|
|
@ -25,8 +25,7 @@ function _setup_security_stack
|
|||
|
||||
function __setup__security__postgrey
|
||||
{
|
||||
if [[ ${ENABLE_POSTGREY} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_POSTGREY} -eq 1 ]]; then
|
||||
_log 'debug' 'Enabling and configuring Postgrey'
|
||||
|
||||
sedfile -i -E \
|
||||
|
@ -37,18 +36,15 @@ function __setup__security__postgrey
|
|||
"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
|
||||
|
||||
if ! grep -i 'POSTGREY_TEXT' /etc/default/postgrey
|
||||
then
|
||||
if ! grep -i 'POSTGREY_TEXT' /etc/default/postgrey; then
|
||||
printf 'POSTGREY_TEXT=\"%s\"\n\n' "${POSTGREY_TEXT}" >>/etc/default/postgrey
|
||||
fi
|
||||
|
||||
if [[ -f /tmp/docker-mailserver/whitelist_clients.local ]]
|
||||
then
|
||||
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
|
||||
if [[ -f /tmp/docker-mailserver/whitelist_recipients ]]; then
|
||||
cp -f /tmp/docker-mailserver/whitelist_recipients /etc/postgrey/whitelist_recipients
|
||||
fi
|
||||
else
|
||||
|
@ -64,8 +60,7 @@ function __setup__security__postscreen
|
|||
-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
|
||||
|
||||
if [[ ${ENABLE_DNSBL} -eq 0 ]]
|
||||
then
|
||||
if [[ ${ENABLE_DNSBL} -eq 0 ]]; then
|
||||
_log 'debug' 'Disabling Postscreen DNSBLs'
|
||||
postconf 'postscreen_dnsbl_action = ignore'
|
||||
postconf 'postscreen_dnsbl_sites = '
|
||||
|
@ -76,8 +71,7 @@ function __setup__security__postscreen
|
|||
|
||||
function __setup__security__spamassassin
|
||||
{
|
||||
if [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]]; then
|
||||
_log 'debug' 'Enabling and configuring SpamAssassin'
|
||||
|
||||
# shellcheck disable=SC2016
|
||||
|
@ -94,8 +88,7 @@ function __setup__security__spamassassin
|
|||
's|invoke-rc.d spamassassin reload|/etc/init\.d/spamassassin reload|g' \
|
||||
/etc/cron.daily/spamassassin
|
||||
|
||||
if [[ ${SA_SPAM_SUBJECT} == 'undef' ]]
|
||||
then
|
||||
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
|
||||
|
@ -104,27 +97,23 @@ function __setup__security__spamassassin
|
|||
fi
|
||||
|
||||
# activate short circuits when SA BAYES is certain it has spam or ham.
|
||||
if [[ ${SA_SHORTCIRCUIT_BAYES_SPAM} -eq 1 ]]
|
||||
then
|
||||
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
|
||||
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
|
||||
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
|
||||
if [[ ${SPAMASSASSIN_SPAM_TO_INBOX} -eq 1 ]]; then
|
||||
_log 'trace' 'Configuring Spamassassin/Amavis to send SPAM to inbox'
|
||||
_log 'debug' 'SPAM_TO_INBOX=1 is set. SA_KILL will be ignored.'
|
||||
|
||||
|
@ -137,8 +126,7 @@ function __setup__security__spamassassin
|
|||
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
|
||||
if [[ ${ENABLE_SPAMASSASSIN_KAM} -eq 1 ]]; then
|
||||
_log 'trace' 'Configuring Spamassassin KAM'
|
||||
local SPAMASSASSIN_KAM_CRON_FILE=/etc/cron.daily/spamassassin_kam
|
||||
|
||||
|
@ -151,8 +139,7 @@ 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
|
||||
if [[ ${EXIT_CODE} -ge 4 ]]; then
|
||||
echo -e "Updating SpamAssassin KAM failed:\n${RESULT}\n" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
@ -172,8 +159,7 @@ EOF
|
|||
|
||||
function __setup__security__clamav
|
||||
{
|
||||
if [[ ${ENABLE_CLAMAV} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_CLAMAV} -eq 1 ]]; then
|
||||
_log 'debug' 'Enabling and configuring ClamAV'
|
||||
|
||||
local FILE
|
||||
|
@ -184,19 +170,16 @@ function __setup__security__clamav
|
|||
chmod 640 "${FILE}"
|
||||
done
|
||||
|
||||
if [[ ${CLAMAV_MESSAGE_SIZE_LIMIT} != '25M' ]]
|
||||
then
|
||||
if [[ ${CLAMAV_MESSAGE_SIZE_LIMIT} != '25M' ]]; then
|
||||
_log 'trace' "Setting ClamAV message scan size limit to '${CLAMAV_MESSAGE_SIZE_LIMIT}'"
|
||||
|
||||
# do a short sanity check: ClamAV does not support setting a maximum size greater than 4000M (at all)
|
||||
if [[ $(numfmt --from=si "${CLAMAV_MESSAGE_SIZE_LIMIT}") -gt $(numfmt --from=si 4000M) ]]
|
||||
then
|
||||
if [[ $(numfmt --from=si "${CLAMAV_MESSAGE_SIZE_LIMIT}") -gt $(numfmt --from=si 4000M) ]]; then
|
||||
_log 'warn' "You set 'CLAMAV_MESSAGE_SIZE_LIMIT' to a value larger than 4 Gigabyte, but the maximum value is 4000M for this value - you should correct your configuration"
|
||||
fi
|
||||
# For more details, see
|
||||
# https://github.com/docker-mailserver/docker-mailserver/pull/3341
|
||||
if [[ $(numfmt --from=si "${CLAMAV_MESSAGE_SIZE_LIMIT}") -ge $(numfmt --from=iec 2G) ]]
|
||||
then
|
||||
if [[ $(numfmt --from=si "${CLAMAV_MESSAGE_SIZE_LIMIT}") -ge $(numfmt --from=iec 2G) ]]; then
|
||||
_log 'warn' "You set 'CLAMAV_MESSAGE_SIZE_LIMIT' to a value larger than 2 Gibibyte but ClamAV does not scan files larger or equal to 2 Gibibyte"
|
||||
fi
|
||||
|
||||
|
@ -216,22 +199,18 @@ function __setup__security__clamav
|
|||
|
||||
function __setup__security__fail2ban
|
||||
{
|
||||
if [[ ${ENABLE_FAIL2BAN} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_FAIL2BAN} -eq 1 ]]; then
|
||||
_log 'debug' 'Enabling and configuring Fail2Ban'
|
||||
|
||||
if [[ -e /tmp/docker-mailserver/fail2ban-fail2ban.cf ]]
|
||||
then
|
||||
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
|
||||
if [[ -e /tmp/docker-mailserver/fail2ban-jail.cf ]]; then
|
||||
cp /tmp/docker-mailserver/fail2ban-jail.cf /etc/fail2ban/jail.d/user-jail.local
|
||||
fi
|
||||
|
||||
if [[ ${FAIL2BAN_BLOCKTYPE} != 'reject' ]]
|
||||
then
|
||||
if [[ ${FAIL2BAN_BLOCKTYPE} != 'reject' ]]; then
|
||||
echo -e '[Init]\nblocktype = drop' >/etc/fail2ban/action.d/nftables-common.local
|
||||
fi
|
||||
|
||||
|
@ -244,11 +223,9 @@ function __setup__security__fail2ban
|
|||
|
||||
function __setup__security__amavis
|
||||
{
|
||||
if [[ ${ENABLE_AMAVIS} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_AMAVIS} -eq 1 ]]; then
|
||||
_log 'debug' 'Configuring Amavis'
|
||||
if [[ -f /tmp/docker-mailserver/amavis.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/amavis.cf ]]; then
|
||||
cp /tmp/docker-mailserver/amavis.cf /etc/amavis/conf.d/50-user
|
||||
fi
|
||||
|
||||
|
@ -269,13 +246,11 @@ function __setup__security__amavis
|
|||
mv /etc/cron.d/amavisd-new /etc/cron.d/amavisd-new.disabled
|
||||
chmod 0 /etc/cron.d/amavisd-new.disabled
|
||||
|
||||
if [[ ${ENABLE_CLAMAV} -eq 1 ]] && [[ ${ENABLE_RSPAMD} -eq 0 ]]
|
||||
then
|
||||
if [[ ${ENABLE_CLAMAV} -eq 1 ]] && [[ ${ENABLE_RSPAMD} -eq 0 ]]; then
|
||||
_log 'warn' 'ClamAV will not work when Amavis & rspamd are disabled. Enable either Amavis or rspamd to fix it.'
|
||||
fi
|
||||
|
||||
if [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]]; then
|
||||
_log 'warn' 'Spamassassin will not work when Amavis is disabled. Enable Amavis to fix it.'
|
||||
fi
|
||||
fi
|
||||
|
@ -284,8 +259,7 @@ function __setup__security__amavis
|
|||
# We can use Sieve to move spam emails to the "Junk" folder.
|
||||
function _setup_spam_to_junk
|
||||
{
|
||||
if [[ ${MOVE_SPAM_TO_JUNK} -eq 1 ]]
|
||||
then
|
||||
if [[ ${MOVE_SPAM_TO_JUNK} -eq 1 ]]; then
|
||||
_log 'debug' 'Spam emails will be moved to the Junk folder'
|
||||
cat >/usr/lib/dovecot/sieve-global/after/spam_to_junk.sieve << EOF
|
||||
require ["fileinto","mailbox"];
|
||||
|
@ -298,8 +272,7 @@ EOF
|
|||
sievec /usr/lib/dovecot/sieve-global/after/spam_to_junk.sieve
|
||||
chown dovecot:root /usr/lib/dovecot/sieve-global/after/spam_to_junk.{sieve,svbin}
|
||||
|
||||
if [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]] && [[ ${SPAMASSASSIN_SPAM_TO_INBOX} -eq 0 ]]
|
||||
then
|
||||
if [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]] && [[ ${SPAMASSASSIN_SPAM_TO_INBOX} -eq 0 ]]; then
|
||||
_log 'warning' "'SPAMASSASSIN_SPAM_TO_INBOX=0' but it is required to be 1 for 'MOVE_SPAM_TO_JUNK=1' to work"
|
||||
fi
|
||||
else
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
# Function called during global setup to handle the complete setup of Rspamd.
|
||||
function _setup_rspamd
|
||||
{
|
||||
if _env_var_expect_zero_or_one 'ENABLE_RSPAMD' && [[ ${ENABLE_RSPAMD} -eq 1 ]]
|
||||
then
|
||||
if _env_var_expect_zero_or_one 'ENABLE_RSPAMD' && [[ ${ENABLE_RSPAMD} -eq 1 ]]; then
|
||||
_log 'debug' 'Enabling and configuring Rspamd'
|
||||
__rspamd__log 'trace' '---------- Setup started ----------'
|
||||
|
||||
|
@ -44,8 +43,7 @@ function __rspamd__helper__enable_disable_module
|
|||
local LOCAL_OR_OVERRIDE=${3:-local}
|
||||
local MESSAGE='Enabling'
|
||||
|
||||
if [[ ! ${ENABLE_MODULE} =~ ^(true|false)$ ]]
|
||||
then
|
||||
if [[ ! ${ENABLE_MODULE} =~ ^(true|false)$ ]]; then
|
||||
__rspamd__log 'warn' "__rspamd__helper__enable_disable_module got non-boolean argument for deciding whether module should be enabled or not"
|
||||
return 1
|
||||
fi
|
||||
|
@ -75,39 +73,32 @@ function __rspamd__run_early_setup_and_checks
|
|||
mkdir -p /var/lib/rspamd/
|
||||
: >/var/lib/rspamd/stats.ucl
|
||||
|
||||
if [[ -d ${RSPAMD_DMS_OVERRIDE_D} ]]
|
||||
then
|
||||
if [[ -d ${RSPAMD_DMS_OVERRIDE_D} ]]; then
|
||||
__rspamd__log 'debug' "Found directory '${RSPAMD_DMS_OVERRIDE_D}' - linking it to '${RSPAMD_OVERRIDE_D}'"
|
||||
if rmdir "${RSPAMD_OVERRIDE_D}" 2>/dev/null
|
||||
then
|
||||
if rmdir "${RSPAMD_OVERRIDE_D}" 2>/dev/null; then
|
||||
ln -s "${RSPAMD_DMS_OVERRIDE_D}" "${RSPAMD_OVERRIDE_D}"
|
||||
else
|
||||
__rspamd__log 'warn' "Could not remove '${RSPAMD_OVERRIDE_D}' (not empty? not a directory?; did you restart properly?) - not linking '${RSPAMD_DMS_OVERRIDE_D}'"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${ENABLE_AMAVIS} -eq 1 ]] || [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_AMAVIS} -eq 1 ]] || [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]]; then
|
||||
__rspamd__log 'warn' 'Running Amavis/SA & Rspamd at the same time is discouraged'
|
||||
fi
|
||||
|
||||
if [[ ${ENABLE_OPENDKIM} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_OPENDKIM} -eq 1 ]]; then
|
||||
__rspamd__log 'warn' 'Running OpenDKIM & Rspamd at the same time is discouraged - we recommend Rspamd for DKIM checks (enabled with Rspamd by default) & signing'
|
||||
fi
|
||||
|
||||
if [[ ${ENABLE_OPENDMARC} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_OPENDMARC} -eq 1 ]]; then
|
||||
__rspamd__log 'warn' 'Running OpenDMARC & Rspamd at the same time is discouraged - we recommend Rspamd for DMARC checks (enabled with Rspamd by default)'
|
||||
fi
|
||||
|
||||
if [[ ${ENABLE_POLICYD_SPF} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_POLICYD_SPF} -eq 1 ]]; then
|
||||
__rspamd__log 'warn' 'Running policyd-spf & Rspamd at the same time is discouraged - we recommend Rspamd for SPF checks (enabled with Rspamd by default)'
|
||||
fi
|
||||
|
||||
if [[ ${ENABLE_POSTGREY} -eq 1 ]] && [[ ${RSPAMD_GREYLISTING} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_POSTGREY} -eq 1 ]] && [[ ${RSPAMD_GREYLISTING} -eq 1 ]]; then
|
||||
__rspamd__log 'warn' 'Running Postgrey & Rspamd at the same time is discouraged - we recommend Rspamd for greylisting'
|
||||
fi
|
||||
}
|
||||
|
@ -116,8 +107,7 @@ function __rspamd__run_early_setup_and_checks
|
|||
# supply a configuration for our local Redis instance which is started later.
|
||||
function __rspamd__setup_redis
|
||||
{
|
||||
if _env_var_expect_zero_or_one 'ENABLE_RSPAMD_REDIS' && [[ ${ENABLE_RSPAMD_REDIS} -eq 1 ]]
|
||||
then
|
||||
if _env_var_expect_zero_or_one 'ENABLE_RSPAMD_REDIS' && [[ ${ENABLE_RSPAMD_REDIS} -eq 1 ]]; then
|
||||
__rspamd__log 'debug' 'Internal Redis is enabled, adding configuration'
|
||||
cat >"${RSPAMD_LOCAL_D}/redis.conf" << "EOF"
|
||||
# documentation: https://rspamd.com/doc/configuration/redis.html
|
||||
|
@ -158,15 +148,13 @@ function __rspamd__setup_postfix
|
|||
# If ClamAV is enabled, we will integrate it into Rspamd.
|
||||
function __rspamd__setup_clamav
|
||||
{
|
||||
if _env_var_expect_zero_or_one 'ENABLE_CLAMAV' && [[ ${ENABLE_CLAMAV} -eq 1 ]]
|
||||
then
|
||||
if _env_var_expect_zero_or_one 'ENABLE_CLAMAV' && [[ ${ENABLE_CLAMAV} -eq 1 ]]; then
|
||||
__rspamd__log 'debug' 'Enabling ClamAV integration'
|
||||
sedfile -i -E 's|^(enabled).*|\1 = true;|g' "${RSPAMD_LOCAL_D}/antivirus.conf"
|
||||
# Rspamd uses ClamAV's UNIX socket, and to be able to read it, it must be in the same group
|
||||
usermod -a -G clamav _rspamd
|
||||
|
||||
if [[ ${CLAMAV_MESSAGE_SIZE_LIMIT} != '25M' ]]
|
||||
then
|
||||
if [[ ${CLAMAV_MESSAGE_SIZE_LIMIT} != '25M' ]]; then
|
||||
local SIZE_IN_BYTES
|
||||
SIZE_IN_BYTES=$(numfmt --from=si "${CLAMAV_MESSAGE_SIZE_LIMIT}")
|
||||
__rspamd__log 'trace' "Adjusting maximum size for ClamAV to ${SIZE_IN_BYTES} bytes (${CLAMAV_MESSAGE_SIZE_LIMIT})"
|
||||
|
@ -211,8 +199,7 @@ function __rspamd__setup_default_modules
|
|||
# from or to the "Junk" folder, and learning them as ham or spam.
|
||||
function __rspamd__setup_learning
|
||||
{
|
||||
if _env_var_expect_zero_or_one 'RSPAMD_LEARN' && [[ ${RSPAMD_LEARN} -eq 1 ]]
|
||||
then
|
||||
if _env_var_expect_zero_or_one 'RSPAMD_LEARN' && [[ ${RSPAMD_LEARN} -eq 1 ]]; then
|
||||
__rspamd__log 'debug' 'Setting up intelligent learning of spam and ham'
|
||||
|
||||
local SIEVE_PIPE_BIN_DIR='/usr/lib/dovecot/sieve-pipe'
|
||||
|
@ -256,8 +243,7 @@ EOF
|
|||
# https://rspamd.com/doc/modules/greylisting.html).
|
||||
function __rspamd__setup_greylisting
|
||||
{
|
||||
if _env_var_expect_zero_or_one 'RSPAMD_GREYLISTING' && [[ ${RSPAMD_GREYLISTING} -eq 1 ]]
|
||||
then
|
||||
if _env_var_expect_zero_or_one 'RSPAMD_GREYLISTING' && [[ ${RSPAMD_GREYLISTING} -eq 1 ]]; then
|
||||
__rspamd__log 'debug' 'Enabling greylisting'
|
||||
sedfile -i -E "s|(enabled =).*|\1 true;|g" "${RSPAMD_LOCAL_D}/greylist.conf"
|
||||
else
|
||||
|
@ -272,12 +258,10 @@ function __rspamd__setup_greylisting
|
|||
function __rspamd__setup_hfilter_group
|
||||
{
|
||||
local MODULE_FILE="${RSPAMD_LOCAL_D}/hfilter_group.conf"
|
||||
if _env_var_expect_zero_or_one 'RSPAMD_HFILTER' && [[ ${RSPAMD_HFILTER} -eq 1 ]]
|
||||
then
|
||||
if _env_var_expect_zero_or_one 'RSPAMD_HFILTER' && [[ ${RSPAMD_HFILTER} -eq 1 ]]; then
|
||||
__rspamd__log 'debug' 'Hfilter (group) module is enabled'
|
||||
# Check if we received a number first
|
||||
if _env_var_expect_integer 'RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE' && [[ ${RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE} -ne 6 ]]
|
||||
then
|
||||
if _env_var_expect_integer 'RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE' && [[ ${RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE} -ne 6 ]]; then
|
||||
__rspamd__log 'trace' "Adjusting score for 'HFILTER_HOSTNAME_UNKNOWN' in Hfilter group module to ${RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE}"
|
||||
sed -i -E \
|
||||
"s|(.*score =).*(# __TAG__HFILTER_HOSTNAME_UNKNOWN)|\1 ${RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE}; \2|g" \
|
||||
|
@ -321,8 +305,7 @@ function __rspamd__handle_user_modules_adjustments
|
|||
local FILE="${RSPAMD_OVERRIDE_D}/${MODULE_FILE}"
|
||||
[[ -f ${FILE} ]] || touch "${FILE}"
|
||||
|
||||
if grep -q -E "${OPTION}.*=.*" "${FILE}"
|
||||
then
|
||||
if grep -q -E "${OPTION}.*=.*" "${FILE}"; then
|
||||
__rspamd__log 'trace' "Overwriting option '${OPTION}' with value '${VALUE}' for ${MODULE_LOG_NAME}"
|
||||
sed -i -E "s|([[:space:]]*${OPTION}).*|\1 = ${VALUE};|g" "${FILE}"
|
||||
else
|
||||
|
@ -336,15 +319,13 @@ function __rspamd__handle_user_modules_adjustments
|
|||
|
||||
# We check for usage of the previous location of the commands file.
|
||||
# This can be removed after the release of v14.0.0.
|
||||
if [[ -f ${RSPAMD_CUSTOM_COMMANDS_FILE_OLD} ]]
|
||||
then
|
||||
if [[ -f ${RSPAMD_CUSTOM_COMMANDS_FILE_OLD} ]]; then
|
||||
__rspamd__log 'warn' "Detected usage of old file location for modules adjustment ('${RSPAMD_CUSTOM_COMMANDS_FILE_OLD}') - please use the new location ('${RSPAMD_CUSTOM_COMMANDS_FILE}')"
|
||||
__rspamd__log 'warn' "Using old file location now (deprecated) - this will prevent startup in v13.0.0"
|
||||
RSPAMD_CUSTOM_COMMANDS_FILE=${RSPAMD_CUSTOM_COMMANDS_FILE_OLD}
|
||||
fi
|
||||
|
||||
if [[ -f "${RSPAMD_CUSTOM_COMMANDS_FILE}" ]]
|
||||
then
|
||||
if [[ -f "${RSPAMD_CUSTOM_COMMANDS_FILE}" ]]; then
|
||||
__rspamd__log 'debug' "Found file '${RSPAMD_CUSTOM_COMMANDS_FILE}' - parsing and applying it"
|
||||
|
||||
while read -r COMMAND ARGUMENT1 ARGUMENT2 ARGUMENT3
|
||||
|
|
|
@ -2,21 +2,17 @@
|
|||
|
||||
function _setup_spoof_protection
|
||||
{
|
||||
if [[ ${SPOOF_PROTECTION} -eq 1 ]]
|
||||
then
|
||||
if [[ ${SPOOF_PROTECTION} -eq 1 ]]; then
|
||||
_log 'trace' 'Enabling and configuring spoof protection'
|
||||
|
||||
if [[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]]
|
||||
then
|
||||
if [[ -z ${LDAP_QUERY_FILTER_SENDERS} ]]
|
||||
then
|
||||
if [[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]]; then
|
||||
if [[ -z ${LDAP_QUERY_FILTER_SENDERS} ]]; then
|
||||
postconf 'smtpd_sender_login_maps = ldap:/etc/postfix/ldap-users.cf ldap:/etc/postfix/ldap-aliases.cf ldap:/etc/postfix/ldap-groups.cf'
|
||||
else
|
||||
postconf 'smtpd_sender_login_maps = ldap:/etc/postfix/ldap-senders.cf'
|
||||
fi
|
||||
else
|
||||
if [[ -f /etc/postfix/regexp ]]
|
||||
then
|
||||
if [[ -f /etc/postfix/regexp ]]; then
|
||||
postconf '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 'smtpd_sender_login_maps = texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre'
|
||||
|
|
|
@ -15,8 +15,7 @@ function _early_variables_setup
|
|||
# completely with a single version.
|
||||
function __environment_variables_backwards_compatibility
|
||||
{
|
||||
if [[ ${ENABLE_LDAP:-0} -eq 1 ]]
|
||||
then
|
||||
if [[ ${ENABLE_LDAP:-0} -eq 1 ]]; then
|
||||
_log 'warn' "'ENABLE_LDAP=1' is deprecated (and will be removed in v13.0.0) => use 'ACCOUNT_PROVISIONER=LDAP' instead"
|
||||
ACCOUNT_PROVISIONER='LDAP'
|
||||
fi
|
||||
|
@ -165,8 +164,7 @@ function _environment_variables_saslauthd
|
|||
|
||||
# SASL ENV for configuring an LDAP specific
|
||||
# `saslauthd.conf` via `setup-stack.sh:_setup_sasulauthd()`
|
||||
if [[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]]
|
||||
then
|
||||
if [[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]]; then
|
||||
_log 'trace' 'Setting SASLSAUTH-LDAP variables nnow'
|
||||
|
||||
VARS[SASLAUTHD_LDAP_AUTH_METHOD]="${SASLAUTHD_LDAP_AUTH_METHOD:=bind}"
|
||||
|
@ -179,32 +177,28 @@ function _environment_variables_saslauthd
|
|||
VARS[SASLAUTHD_LDAP_START_TLS]="${SASLAUTHD_LDAP_START_TLS:=no}"
|
||||
VARS[SASLAUTHD_LDAP_TLS_CHECK_PEER]="${SASLAUTHD_LDAP_TLS_CHECK_PEER:=no}"
|
||||
|
||||
if [[ -z ${SASLAUTHD_LDAP_TLS_CACERT_FILE} ]]
|
||||
then
|
||||
if [[ -z ${SASLAUTHD_LDAP_TLS_CACERT_FILE} ]]; then
|
||||
SASLAUTHD_LDAP_TLS_CACERT_FILE=''
|
||||
else
|
||||
SASLAUTHD_LDAP_TLS_CACERT_FILE="ldap_tls_cacert_file: ${SASLAUTHD_LDAP_TLS_CACERT_FILE}"
|
||||
fi
|
||||
VARS[SASLAUTHD_LDAP_TLS_CACERT_FILE]="${SASLAUTHD_LDAP_TLS_CACERT_FILE}"
|
||||
|
||||
if [[ -z ${SASLAUTHD_LDAP_TLS_CACERT_DIR} ]]
|
||||
then
|
||||
if [[ -z ${SASLAUTHD_LDAP_TLS_CACERT_DIR} ]]; then
|
||||
SASLAUTHD_LDAP_TLS_CACERT_DIR=''
|
||||
else
|
||||
SASLAUTHD_LDAP_TLS_CACERT_DIR="ldap_tls_cacert_dir: ${SASLAUTHD_LDAP_TLS_CACERT_DIR}"
|
||||
fi
|
||||
VARS[SASLAUTHD_LDAP_TLS_CACERT_DIR]="${SASLAUTHD_LDAP_TLS_CACERT_DIR}"
|
||||
|
||||
if [[ -z ${SASLAUTHD_LDAP_PASSWORD_ATTR} ]]
|
||||
then
|
||||
if [[ -z ${SASLAUTHD_LDAP_PASSWORD_ATTR} ]]; then
|
||||
SASLAUTHD_LDAP_PASSWORD_ATTR=''
|
||||
else
|
||||
SASLAUTHD_LDAP_PASSWORD_ATTR="ldap_password_attr: ${SASLAUTHD_LDAP_PASSWORD_ATTR}"
|
||||
fi
|
||||
VARS[SASLAUTHD_LDAP_PASSWORD_ATTR]="${SASLAUTHD_LDAP_PASSWORD_ATTR}"
|
||||
|
||||
if [[ -z ${SASLAUTHD_LDAP_MECH} ]]
|
||||
then
|
||||
if [[ -z ${SASLAUTHD_LDAP_MECH} ]]; then
|
||||
SASLAUTHD_LDAP_MECH=''
|
||||
else
|
||||
SASLAUTHD_LDAP_MECH="ldap_mech: ${SASLAUTHD_LDAP_MECH}"
|
||||
|
|
|
@ -9,8 +9,7 @@ CHANGELOG_URL='https://github.com/docker-mailserver/docker-mailserver/blob/maste
|
|||
|
||||
# check for correct syntax
|
||||
# number + suffix. suffix must be 's' for seconds, 'm' for minutes, 'h' for hours or 'd' for days.
|
||||
if [[ ! ${UPDATE_CHECK_INTERVAL} =~ ^[0-9]+[smhd]{1}$ ]]
|
||||
then
|
||||
if [[ ! ${UPDATE_CHECK_INTERVAL} =~ ^[0-9]+[smhd]{1}$ ]]; then
|
||||
_log_with_date 'warn' "Invalid 'UPDATE_CHECK_INTERVAL' value '${UPDATE_CHECK_INTERVAL}'"
|
||||
_log_with_date 'warn' 'Falling back to daily update checks'
|
||||
UPDATE_CHECK_INTERVAL='1d'
|
||||
|
@ -22,13 +21,11 @@ do
|
|||
LATEST=$(curl -Lsf "${VERSION_URL}")
|
||||
|
||||
# did we get a valid response?
|
||||
if [[ ${LATEST} =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]
|
||||
then
|
||||
if [[ ${LATEST} =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
_log_with_date 'debug' 'Remote version information fetched'
|
||||
|
||||
# compare versions
|
||||
if dpkg --compare-versions "${VERSION}" lt "${LATEST}"
|
||||
then
|
||||
if dpkg --compare-versions "${VERSION}" lt "${LATEST}"; then
|
||||
# send mail notification to postmaster
|
||||
read -r -d '' MAIL << EOF
|
||||
Hello ${POSTMASTER_ADDRESS}!
|
||||
|
|
|
@ -52,12 +52,10 @@ __load_bats_helper
|
|||
#
|
||||
# This function is internal and should not be used in tests.
|
||||
function __handle_container_name() {
|
||||
if [[ -n ${1:-} ]] && [[ ${1:-} =~ ^dms-test_ ]]
|
||||
then
|
||||
if [[ -n ${1:-} ]] && [[ ${1:-} =~ ^dms-test_ ]]; then
|
||||
printf '%s' "${1}"
|
||||
return 0
|
||||
elif [[ -n ${CONTAINER_NAME+set} ]]
|
||||
then
|
||||
elif [[ -n ${CONTAINER_NAME+set} ]]; then
|
||||
printf '%s' "${CONTAINER_NAME}"
|
||||
return 0
|
||||
else
|
||||
|
@ -169,8 +167,7 @@ function _repeat_in_container_until_success_or_timeout() {
|
|||
function _repeat_until_success_or_timeout() {
|
||||
local FATAL_FAILURE_TEST_COMMAND
|
||||
|
||||
if [[ "${1:-}" == "--fatal-test" ]]
|
||||
then
|
||||
if [[ "${1:-}" == "--fatal-test" ]]; then
|
||||
FATAL_FAILURE_TEST_COMMAND="${2:?Provided --fatal-test but no command}"
|
||||
shift 2
|
||||
fi
|
||||
|
@ -178,8 +175,7 @@ function _repeat_until_success_or_timeout() {
|
|||
local TIMEOUT=${1:?Timeout duration must be provided}
|
||||
shift 1
|
||||
|
||||
if ! [[ "${TIMEOUT}" =~ ^[0-9]+$ ]]
|
||||
then
|
||||
if ! [[ "${TIMEOUT}" =~ ^[0-9]+$ ]]; then
|
||||
echo "First parameter for timeout must be an integer, received \"${TIMEOUT}\""
|
||||
return 1
|
||||
fi
|
||||
|
@ -188,16 +184,14 @@ function _repeat_until_success_or_timeout() {
|
|||
|
||||
until "${@}"
|
||||
do
|
||||
if [[ -n ${FATAL_FAILURE_TEST_COMMAND} ]] && ! eval "${FATAL_FAILURE_TEST_COMMAND}"
|
||||
then
|
||||
if [[ -n ${FATAL_FAILURE_TEST_COMMAND} ]] && ! eval "${FATAL_FAILURE_TEST_COMMAND}"; then
|
||||
echo "\`${FATAL_FAILURE_TEST_COMMAND}\` failed, early aborting repeat_until_success of \`${*}\`" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
||||
if [[ $(( SECONDS - STARTTIME )) -gt ${TIMEOUT} ]]
|
||||
then
|
||||
if [[ $(( SECONDS - STARTTIME )) -gt ${TIMEOUT} ]]; then
|
||||
echo "Timed out on command: ${*}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
@ -213,8 +207,7 @@ function _run_until_success_or_timeout() {
|
|||
local TIMEOUT=${1:?Timeout duration must be provided}
|
||||
shift 1
|
||||
|
||||
if [[ ! ${TIMEOUT} =~ ^[0-9]+$ ]]
|
||||
then
|
||||
if [[ ! ${TIMEOUT} =~ ^[0-9]+$ ]]; then
|
||||
echo "First parameter for timeout must be an integer, received \"${TIMEOUT}\""
|
||||
return 1
|
||||
fi
|
||||
|
@ -226,8 +219,7 @@ function _run_until_success_or_timeout() {
|
|||
do
|
||||
sleep 1
|
||||
|
||||
if (( SECONDS - STARTTIME > TIMEOUT ))
|
||||
then
|
||||
if (( SECONDS - STARTTIME > TIMEOUT )); then
|
||||
echo "Timed out on command: ${*}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
@ -270,8 +262,7 @@ function _wait_for_smtp_port_in_container_to_respond() {
|
|||
local COUNT=0
|
||||
until [[ $(_exec_in_container timeout 10 /bin/bash -c 'echo QUIT | nc localhost 25') == *'221 2.0.0 Bye'* ]]
|
||||
do
|
||||
if [[ ${COUNT} -eq 20 ]]
|
||||
then
|
||||
if [[ ${COUNT} -eq 20 ]]; then
|
||||
echo "Unable to receive a valid response from 'nc localhost 25' within 20 seconds"
|
||||
return 1
|
||||
fi
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
# This function is internal and should not be used in tests.
|
||||
function __initialize_variables() {
|
||||
function __check_if_set() {
|
||||
if [[ ${!1+set} != 'set' ]]
|
||||
then
|
||||
if [[ ${!1+set} != 'set' ]]; then
|
||||
echo "ERROR: (helper/setup.sh) '${1:?No variable name given to __check_if_set}' is not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
@ -64,8 +63,7 @@ function _duplicate_config_for_container() {
|
|||
local OUTPUT_FOLDER
|
||||
OUTPUT_FOLDER=$(_print_private_config_path "${2}")
|
||||
|
||||
if [[ -z ${OUTPUT_FOLDER} ]]
|
||||
then
|
||||
if [[ -z ${OUTPUT_FOLDER} ]]; then
|
||||
echo "'OUTPUT_FOLDER' in '_duplicate_config_for_container' is empty" >&2
|
||||
return 1
|
||||
fi
|
||||
|
|
|
@ -71,14 +71,11 @@ function _generate_openssl_cmd() {
|
|||
local CMD_OPENSSL="timeout 1 openssl s_client -connect ${HOST}:${PORT}"
|
||||
|
||||
# STARTTLS ports need to add a hint:
|
||||
if [[ ${PORT} =~ ^(25|587)$ ]]
|
||||
then
|
||||
if [[ ${PORT} =~ ^(25|587)$ ]]; then
|
||||
CMD_OPENSSL="${CMD_OPENSSL} -starttls smtp"
|
||||
elif [[ ${PORT} == 143 ]]
|
||||
then
|
||||
elif [[ ${PORT} == 143 ]]; then
|
||||
CMD_OPENSSL="${CMD_OPENSSL} -starttls imap"
|
||||
elif [[ ${PORT} == 110 ]]
|
||||
then
|
||||
elif [[ ${PORT} == 110 ]]; then
|
||||
CMD_OPENSSL="${CMD_OPENSSL} -starttls pop3"
|
||||
fi
|
||||
|
||||
|
|
|
@ -111,8 +111,7 @@ function _shellcheck
|
|||
"koalaman/shellcheck-alpine:v${SHELLCHECK_VERSION}" "${CMD_SHELLCHECK[@]}" \
|
||||
"${BATS_EXTRA_ARGS[@]}" "${F_BATS[@]}" || ERROR=1
|
||||
|
||||
if [[ ${ERROR} -eq 0 ]]
|
||||
then
|
||||
if [[ ${ERROR} -eq 0 ]]; then
|
||||
_log 'info' 'ShellCheck succeeded'
|
||||
else
|
||||
_log 'error' 'ShellCheck failed'
|
||||
|
|
|
@ -107,8 +107,7 @@ function wait_for_smtp_port_in_container() {
|
|||
function wait_for_smtp_port_in_container_to_respond() {
|
||||
local COUNT=0
|
||||
until [[ $(docker exec "${1}" timeout 10 /bin/sh -c "echo QUIT | nc localhost 25") == *"221 2.0.0 Bye"* ]]; do
|
||||
if [[ $COUNT -eq 20 ]]
|
||||
then
|
||||
if [[ $COUNT -eq 20 ]]; then
|
||||
echo "Unable to receive a valid response from 'nc localhost 25' within 20 seconds"
|
||||
return 1
|
||||
fi
|
||||
|
|
|
@ -240,8 +240,7 @@ function _copy_to_letsencrypt_storage() {
|
|||
FQDN_DIR=$(echo "${DEST}" | cut -d '/' -f1)
|
||||
mkdir -p "${TEST_TMP_CONFIG}/letsencrypt/${FQDN_DIR}"
|
||||
|
||||
if ! cp "${PWD}/test/test-files/ssl/${SRC}" "${TEST_TMP_CONFIG}/letsencrypt/${DEST}"
|
||||
then
|
||||
if ! cp "${PWD}/test/test-files/ssl/${SRC}" "${TEST_TMP_CONFIG}/letsencrypt/${DEST}"; then
|
||||
echo "Could not copy cert file '${SRC}'' to '${DEST}'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
@ -76,8 +76,7 @@ function _configure_and_run_dms_container() {
|
|||
local ALT_KEY_TYPE=$3 # Optional parameter
|
||||
|
||||
export TEST_VARIANT="${TLS_LEVEL}-${KEY_TYPE}"
|
||||
if [[ -n ${ALT_KEY_TYPE} ]]
|
||||
then
|
||||
if [[ -n ${ALT_KEY_TYPE} ]]; then
|
||||
TEST_VARIANT+="-${ALT_KEY_TYPE}"
|
||||
fi
|
||||
|
||||
|
@ -98,8 +97,7 @@ function _configure_and_run_dms_container() {
|
|||
--env SSL_KEY_PATH="/config/ssl/with_ca/ecdsa/key.${KEY_TYPE}.pem"
|
||||
)
|
||||
|
||||
if [[ -n ${ALT_KEY_TYPE} ]]
|
||||
then
|
||||
if [[ -n ${ALT_KEY_TYPE} ]]; then
|
||||
CUSTOM_SETUP_ARGUMENTS+=(
|
||||
--env SSL_ALT_CERT_PATH="/config/ssl/with_ca/ecdsa/cert.${ALT_KEY_TYPE}.pem"
|
||||
--env SSL_ALT_KEY_PATH="/config/ssl/with_ca/ecdsa/key.${ALT_KEY_TYPE}.pem"
|
||||
|
@ -199,8 +197,7 @@ function compare_cipherlist() {
|
|||
function get_cipherlist() {
|
||||
local TLS_VERSION=$1
|
||||
|
||||
if [[ ${TLS_VERSION} == "TLSv1_3" ]]
|
||||
then
|
||||
if [[ ${TLS_VERSION} == "TLSv1_3" ]]; then
|
||||
# TLS v1.3 cipher suites are not user defineable and not unique to the available certificate(s).
|
||||
# They do not support server enforced order either.
|
||||
echo '"TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256"'
|
||||
|
|
|
@ -184,8 +184,7 @@ function _check_if_process_is_running() {
|
|||
local IS_RUNNING=$(docker exec "${CONTAINER_NAME}" pgrep --list-full "${MIN_SECS_RUNNING[@]}" "${PROCESS}")
|
||||
|
||||
# When no matches are found, nothing is returned. Provide something we can assert on (helpful for debugging):
|
||||
if [[ ! ${IS_RUNNING} =~ ${PROCESS} ]]
|
||||
then
|
||||
if [[ ! ${IS_RUNNING} =~ ${PROCESS} ]]; then
|
||||
echo "'${PROCESS}' is not running"
|
||||
return 1
|
||||
fi
|
||||
|
|
Loading…
Reference in a new issue