refactor: Generate `saslauthd.conf` via Config Template feature
From a inline config via HereDoc to using a `.tmpl` file that has of all supported keys for SASLAuthd LDAP config. This additionally supports layering the ENV `.tmpl` generated config over a user-provided config. With a utility method that will ensure earlier duplicate keys are removed. The two new utilities are documented well enough to grok. `Dockerfile` and `packages.sh` updated to bring in new dependencies and provide the `.tmpl` file. `log_level` is not documented as a LDAP config key. Original PR did not explain why this key and value chosen were added.
This commit is contained in:
parent
25c7024cc4
commit
a699c03ba9
|
@ -120,6 +120,9 @@ COPY \
|
||||||
target/postfix/ldap-senders.cf \
|
target/postfix/ldap-senders.cf \
|
||||||
/etc/postfix/
|
/etc/postfix/
|
||||||
|
|
||||||
|
# LDAP config support:
|
||||||
|
COPY --link target/features/ldap/ /etc/dms/ldap/
|
||||||
|
|
||||||
# hadolint ignore=SC2016
|
# hadolint ignore=SC2016
|
||||||
RUN <<EOF
|
RUN <<EOF
|
||||||
sedfile -i -r 's/^(CRON)=0/\1=1/g' /etc/default/spamassassin
|
sedfile -i -r 's/^(CRON)=0/\1=1/g' /etc/default/spamassassin
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Parameter docs: https://github.com/cyrusimap/cyrus-sasl/blob/3959d45aa187d906d5fb3e8edf7e3661780967a5/saslauthd/LDAP_SASLAUTHD#L85-L242
|
||||||
|
ldap_auth_method: ${LDAP_AUTH_METHOD}
|
||||||
|
ldap_bind_dn: ${LDAP_BIND_DN}
|
||||||
|
ldap_bind_pw: ${LDAP_BIND_PW}
|
||||||
|
ldap_default_domain: ${LDAP_DEFAULT_DOMAIN}
|
||||||
|
ldap_default_realm: ${LDAP_DEFAULT_REALM}
|
||||||
|
ldap_deref: ${LDAP_DEREF}
|
||||||
|
ldap_filter: ${LDAP_FILTER}
|
||||||
|
ldap_group_attr: ${LDAP_GROUP_ATTR}
|
||||||
|
ldap_group_dn: ${LDAP_GROUP_DN}
|
||||||
|
ldap_group_filter: ${LDAP_GROUP_FILTER}
|
||||||
|
ldap_group_match_method: ${LDAP_GROUP_MATCH_METHOD}
|
||||||
|
ldap_group_search_base: ${LDAP_GROUP_SEARCH_BASE}
|
||||||
|
ldap_group_scope: ${LDAP_GROUP_SCOPE}
|
||||||
|
ldap_password: ${LDAP_PASSWORD}
|
||||||
|
ldap_password_attr: ${LDAP_PASSWORD_ATTR}
|
||||||
|
ldap_referrals: ${LDAP_REFERRALS}
|
||||||
|
ldap_restart: ${LDAP_RESTART}
|
||||||
|
ldap_id: ${LDAP_ID}
|
||||||
|
ldap_authz_id: ${LDAP_AUTHZ_ID}
|
||||||
|
ldap_mech: ${LDAP_MECH}
|
||||||
|
ldap_realm: ${LDAP_REALM}
|
||||||
|
ldap_scope: ${LDAP_SCOPE}
|
||||||
|
ldap_search_base: ${LDAP_SEARCH_BASE}
|
||||||
|
ldap_servers: ${LDAP_SERVERS}
|
||||||
|
ldap_start_tls: ${LDAP_START_TLS}
|
||||||
|
ldap_time_limit: ${LDAP_TIME_LIMIT}
|
||||||
|
ldap_timeout: ${LDAP_TIMEOUT}
|
||||||
|
ldap_tls_check_peer: ${LDAP_TLS_CHECK_PEER}
|
||||||
|
ldap_tls_cacert_file: ${LDAP_TLS_CACERT_FILE}
|
||||||
|
ldap_tls_cacert_dir: ${LDAP_TLS_CACERT_DIR}
|
||||||
|
ldap_tls_ciphers: ${LDAP_TLS_CIPHERS}
|
||||||
|
ldap_tls_cert: ${LDAP_TLS_CERT}
|
||||||
|
ldap_tls_key: ${LDAP_TLS_KEY}
|
||||||
|
ldap_use_sasl: ${LDAP_USE_SASL}
|
||||||
|
ldap_version: ${LDAP_VERSION}
|
|
@ -92,6 +92,18 @@ function _install_packages() {
|
||||||
"${DEBUG_PACKAGES[@]}"
|
"${DEBUG_PACKAGES[@]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _install_feature_config_templates() {
|
||||||
|
_log 'debug' 'Installing support for feature - Config Templates'
|
||||||
|
|
||||||
|
# envsubst:
|
||||||
|
apt-get "${QUIET}" --no-install-recommends install gettext-base
|
||||||
|
|
||||||
|
# zenv:
|
||||||
|
local URL_ZENV="https://github.com/numToStr/zenv/releases/download/0.8.0/zenv-0.8.0-$(uname --machine)-unknown-linux-gnu.tar.gz"
|
||||||
|
# Download from GH releases to stdout, then extract the zenv file to make available via PATH:
|
||||||
|
curl -L "${URL_ZENV}" -o - | tar --gzip --extract --directory /usr/local/bin --file - zenv
|
||||||
|
}
|
||||||
|
|
||||||
function _install_dovecot() {
|
function _install_dovecot() {
|
||||||
declare -a DOVECOT_PACKAGES
|
declare -a DOVECOT_PACKAGES
|
||||||
|
|
||||||
|
@ -219,5 +231,6 @@ _install_rspamd
|
||||||
_install_fail2ban
|
_install_fail2ban
|
||||||
_install_getmail
|
_install_getmail
|
||||||
_install_utils
|
_install_utils
|
||||||
|
_install_feature_config_templates
|
||||||
_remove_data_after_package_installations
|
_remove_data_after_package_installations
|
||||||
_post_installation_steps
|
_post_installation_steps
|
||||||
|
|
|
@ -153,3 +153,39 @@ function _env_var_expect_integer() {
|
||||||
_log 'warn' "The value of '${ENV_VAR_NAME}' is not an integer ('${!ENV_VAR_NAME}'), but was expected to be"
|
_log 'warn' "The value of '${ENV_VAR_NAME}' is not an integer ('${!ENV_VAR_NAME}'), but was expected to be"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ensures that zenv only runs envsubst with ENV filtered from the provided prefix.
|
||||||
|
# Those ENV are loaded by zenv in the format of an `.env` file (with prefix dropped by sed)
|
||||||
|
# When an ENV is not available, envsubst will evaluate it as empty.
|
||||||
|
#
|
||||||
|
# @param ${1} = Use a prefix for a group of environment variables
|
||||||
|
# @param ${2} = Filepath to ENV template
|
||||||
|
# @output = Template file content populated with available ENV
|
||||||
|
function _template_with_env() {
|
||||||
|
local ENV_PREFIX=${1:?ENV prefix is required}
|
||||||
|
local ENV_TEMPLATE=${2:?ENV template filepath is required}
|
||||||
|
|
||||||
|
if [[ ! -f ${ENV_TEMPLATE} ]]; then
|
||||||
|
_dms_panic__invalid_value "file '${ENV_TEMPLATE}' does not exist" 'utils.sh:_use_env_template'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# NOTE: $PATH is retained to avoid needing absolute paths for binaries.
|
||||||
|
env --ignore-environment PATH="${PATH}" \
|
||||||
|
zenv --file <(env | grep "^${ENV_PREFIX}" | sed "s/^${ENV_PREFIX}//") \
|
||||||
|
envsubst < "${ENV_TEMPLATE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Utility to cleanup a config file that may have unset or duplicate keys.
|
||||||
|
# - sed => Removes lines where keys have no value assigned.
|
||||||
|
# - tac + sort => Remove any duplicate keys (keeps the last instance found).
|
||||||
|
#
|
||||||
|
# @param ${1} = A delimiter between key and value columns
|
||||||
|
# @param ${2} = Input filepath to clean
|
||||||
|
# @output = The transformed file content
|
||||||
|
function _cleanse_config() {
|
||||||
|
local KV_DELIMITER=${1:?KV Delimiter is required}
|
||||||
|
local INPUT_FILE=${2?:Input file is required}
|
||||||
|
|
||||||
|
sed "/^[^${KV_DELIMITER}]*${KV_DELIMITER}\s*$/d" ${INPUT_FILE} \
|
||||||
|
| tac | sort -u -t"${KV_DELIMITER}" -k1,1
|
||||||
|
}
|
||||||
|
|
|
@ -9,24 +9,7 @@ function _setup_saslauthd() {
|
||||||
if [[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]] \
|
if [[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]] \
|
||||||
&& [[ ! -f /etc/saslauthd.conf ]]; then
|
&& [[ ! -f /etc/saslauthd.conf ]]; then
|
||||||
_log 'trace' 'Creating /etc/saslauthd.conf'
|
_log 'trace' 'Creating /etc/saslauthd.conf'
|
||||||
|
_create_config_saslauthd
|
||||||
# Create a config based on ENV
|
|
||||||
sed '/^.*: $/d'> /etc/saslauthd.conf << EOF
|
|
||||||
ldap_servers: ${SASLAUTHD_LDAP_SERVER:=${LDAP_SERVER_HOST}}
|
|
||||||
ldap_auth_method: ${SASLAUTHD_LDAP_AUTH_METHOD:=bind}
|
|
||||||
ldap_bind_dn: ${SASLAUTHD_LDAP_BIND_DN:=${LDAP_BIND_DN}}
|
|
||||||
ldap_bind_pw: ${SASLAUTHD_LDAP_PASSWORD:=${LDAP_BIND_PW}}
|
|
||||||
ldap_search_base: ${SASLAUTHD_LDAP_SEARCH_BASE:=${LDAP_SEARCH_BASE}}
|
|
||||||
ldap_filter: ${SASLAUTHD_LDAP_FILTER:=(&(uniqueIdentifier=%u)(mailEnabled=TRUE))}
|
|
||||||
ldap_start_tls: ${SASLAUTHD_LDAP_START_TLS:=no}
|
|
||||||
ldap_tls_check_peer: ${SASLAUTHD_LDAP_TLS_CHECK_PEER:=no}
|
|
||||||
ldap_tls_cacert_file: ${SASLAUTHD_LDAP_TLS_CACERT_FILE}
|
|
||||||
ldap_tls_cacert_dir: ${SASLAUTHD_LDAP_TLS_CACERT_DIR}
|
|
||||||
ldap_password_attr: ${SASLAUTHD_LDAP_PASSWORD_ATTR}
|
|
||||||
ldap_mech: ${SASLAUTHD_LDAP_MECH}
|
|
||||||
ldap_referrals: yes
|
|
||||||
log_level: 10
|
|
||||||
EOF
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sed -i \
|
sed -i \
|
||||||
|
@ -42,3 +25,20 @@ EOF
|
||||||
|
|
||||||
gpasswd -a postfix sasl >/dev/null
|
gpasswd -a postfix sasl >/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _create_config_saslauthd() {
|
||||||
|
local SASLAUTHD_LDAP_SERVER=${SASLAUTHD_LDAP_SERVER:=${LDAP_SERVER_HOST}}
|
||||||
|
local SASLAUTHD_LDAP_BIND_DN=${SASLAUTHD_LDAP_BIND_DN:=${LDAP_BIND_DN}}
|
||||||
|
local SASLAUTHD_LDAP_PASSWORD=${SASLAUTHD_LDAP_PASSWORD:=${LDAP_BIND_PW}}
|
||||||
|
local SASLAUTHD_LDAP_SEARCH_BASE=${SASLAUTHD_LDAP_SEARCH_BASE:=${LDAP_SEARCH_BASE}}
|
||||||
|
local SASLAUTHD_LDAP_FILTER=${SASLAUTHD_LDAP_FILTER:=(&(uniqueIdentifier=%u)(mailEnabled=TRUE))}
|
||||||
|
local SASLAUTHD_LDAP_REFERRALS=${SASLAUTHD_LDAP_REFERRALS:=yes}
|
||||||
|
|
||||||
|
# Generates a config from an ENV template while layering several other sources
|
||||||
|
# into a single temporary file, used as input into `_cleanse_config` which
|
||||||
|
# prepares the final output config.
|
||||||
|
_cleanse_config ':' <(cat 2>/dev/null \
|
||||||
|
/tmp/docker-mailserver/ldap/saslauthd.conf \
|
||||||
|
<(_template_with_env 'SASLAUTHD_' /etc/dms/ldap/saslauthd.tmpl) \
|
||||||
|
) > /etc/saslauthd.conf
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue