mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2024-01-19 02:48:50 +00:00
c314c9c471
* chore: Remove requirement for `postfix-accounts.cf` This is an old requirement from when the change detector service was first introduced. It's no longer relevant. * chore: Do not needlessly create `postfix-aliases.cf` The config was created regardless to workaround early change detection support. No longer necessary to require the file to exist. * chore: Drop guards requiring `/tmp/docker-mailserver` to exist Legacy guards when this was the only location change detection location supported. There does not appear to be any need for changing into this directory at the start of `check-for-changes.sh` as we use absolute filepaths (originally monitored files were checked with relative paths to this config dir). * chore: Revise inline docs * chore: Add change detection monitoring for extra configs These are also handled at run-time in the current change detection support, so it makes sense to allows these config updates to also trigger change events.
135 lines
4.8 KiB
Bash
Executable file
135 lines
4.8 KiB
Bash
Executable file
#! /bin/bash
|
||
|
||
# TODO: Adapt for compatibility with LDAP
|
||
# Only the cert renewal change detection may be relevant for LDAP?
|
||
|
||
# CHKSUM_FILE global is imported from this file:
|
||
# shellcheck source=./helpers/index.sh
|
||
source /usr/local/bin/helpers/index.sh
|
||
|
||
# This script requires some environment variables to be properly set. This
|
||
# includes POSTMASTER_ADDRESS (for alias (re-)generation), HOSTNAME and
|
||
# DOMAINNAME (in ssl.sh).
|
||
# shellcheck source=/dev/null
|
||
source /etc/dms-settings
|
||
|
||
_log_with_date 'debug' 'Starting changedetector'
|
||
|
||
# TODO in the future, when we do not use HOSTNAME but DMS_HOSTNAME everywhere,
|
||
# TODO we can delete this call as we needn't calculate the names twice
|
||
# ATTENTION: Do not remove!
|
||
# This script requies HOSTNAME and DOMAINNAME
|
||
# to be properly set.
|
||
_obtain_hostname_and_domainname
|
||
|
||
# verify checksum file exists; must be prepared by start-mailserver.sh
|
||
if [[ ! -f ${CHKSUM_FILE} ]]
|
||
then
|
||
_exit_with_error "'${CHKSUM_FILE}' is missing" 0
|
||
fi
|
||
|
||
REGEX_NEVER_MATCH="(?\!)"
|
||
|
||
_log_with_date 'trace' "Using postmaster address '${POSTMASTER_ADDRESS}'"
|
||
|
||
# Change detection delayed during startup to avoid conflicting writes
|
||
sleep 10
|
||
|
||
_log_with_date 'debug' "Chagedetector is ready"
|
||
|
||
function _check_for_changes
|
||
{
|
||
# get chksum and check it, no need to lock config yet
|
||
_monitored_files_checksums >"${CHKSUM_FILE}.new"
|
||
cmp --silent -- "${CHKSUM_FILE}" "${CHKSUM_FILE}.new"
|
||
|
||
# cmp return codes
|
||
# 0 – files are identical
|
||
# 1 – files differ
|
||
# 2 – inaccessible or missing argument
|
||
if [[ ${?} -eq 1 ]]
|
||
then
|
||
_log_with_date 'info' 'Change detected'
|
||
_create_lock # Shared config safety lock
|
||
local CHANGED
|
||
CHANGED=$(grep -Fxvf "${CHKSUM_FILE}" "${CHKSUM_FILE}.new" | sed 's/^[^ ]\+ //')
|
||
|
||
# TODO Perform updates below conditionally too
|
||
# Also note that changes are performed in place and are not atomic
|
||
# We should fix that and write to temporary files, stop, swap and start
|
||
|
||
# _setup_ssl is required for:
|
||
# 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
|
||
# 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}} ]] \
|
||
|| [[ ${CHANGED} =~ ${SSL_ALT_CERT_PATH:-${REGEX_NEVER_MATCH}} ]] \
|
||
|| [[ ${CHANGED} =~ ${SSL_ALT_KEY_PATH:-${REGEX_NEVER_MATCH}} ]]
|
||
then
|
||
_log_with_date 'debug' 'Manual certificates have changed - extracting certificates'
|
||
_setup_ssl
|
||
fi
|
||
# `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
|
||
_log_with_date 'debug' "'/etc/letsencrypt/acme.json' has changed - extracting certificates"
|
||
_setup_ssl
|
||
|
||
# Prevent an unnecessary change detection from the newly extracted cert files by updating their hashes in advance:
|
||
local CERT_DOMAIN
|
||
CERT_DOMAIN=$(_find_letsencrypt_domain)
|
||
ACME_CERT_DIR="/etc/letsencrypt/live/${CERT_DOMAIN}"
|
||
|
||
sed -i "\|${ACME_CERT_DIR}|d" "${CHKSUM_FILE}.new"
|
||
sha512sum "${ACME_CERT_DIR}"/*.pem >> "${CHKSUM_FILE}.new"
|
||
fi
|
||
|
||
# If monitored certificate files in /etc/letsencrypt/live have changed and no `acme.json` is in use,
|
||
# They presently have no special handling other than to trigger a change that will restart Postfix/Dovecot.
|
||
|
||
# regenerate postfix accounts
|
||
[[ ${SMTP_ONLY} -ne 1 ]] && _create_accounts
|
||
|
||
_rebuild_relayhost
|
||
|
||
# regenerate postix aliases
|
||
_create_aliases
|
||
|
||
# regenerate /etc/postfix/vhost
|
||
# NOTE: If later adding support for LDAP with change detection and this method is called,
|
||
# be sure to mimic `setup-stack.sh:_setup_ldap` which appends to `/tmp/vhost.tmp`.
|
||
_create_postfix_vhost
|
||
|
||
# Legacy workaround handled here, only seems necessary for _create_accounts:
|
||
# - `helpers/accounts.sh` logic creates folders/files with wrong ownership.
|
||
_chown_var_mail_if_necessary
|
||
|
||
_log_with_date 'debug' 'Restarting services due to detected changes'
|
||
|
||
supervisorctl restart postfix
|
||
|
||
# prevent restart of dovecot when smtp_only=1
|
||
[[ ${SMTP_ONLY} -ne 1 ]] && supervisorctl restart dovecot
|
||
|
||
_remove_lock
|
||
_log_with_date 'debug' 'Completed handling of detected change'
|
||
fi
|
||
|
||
# mark changes as applied
|
||
mv "${CHKSUM_FILE}.new" "${CHKSUM_FILE}"
|
||
}
|
||
|
||
while true
|
||
do
|
||
_check_for_changes
|
||
sleep 2
|
||
done
|
||
|
||
exit 0
|