scripts: rework environment variables setup (#2716)

* outsourcing env variable setup

This commit contains major parts of the work of refactoring the setup
and usage of environment variables. It outsources the setup into its own
script and provides dedicated functions to be executed at a later point in time.

A **new** env variable was added: `USER_PROVISIONG` which provides a
better way of defining which method / protocol to use when it comes to
setting up users. This way, the `ENABLE_LDAP` variable is deprecated,
but all of this is backwards compatible due to a "compatibility layer", a function provided by the new variables script.

This is not a breaking change. It mostly refators internal scripts. The
only change facing the user-side is the deprecation of `ENABLE_LDAP`. We
can prolong the period of deprecation for this variable as long as we
want, because the new function that ensures backwards compatibility
provides a clean interface for the future.

Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com>
Co-authored-by: Casper <casperklein@users.noreply.github.com>
This commit is contained in:
Georg Lauterbach 2022-08-22 08:31:32 +02:00 committed by GitHub
parent 26053c22bd
commit ab55343d8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 302 additions and 185 deletions

View File

@ -293,7 +293,8 @@ services:
- ENABLE_FAIL2BAN=1
- ENABLE_POSTGREY=1
- ONE_DIR=1
- ENABLE_LDAP=1
- ENABLE_LDAP=1 # with the :edge tag, use ACCOUNT_PROVISIONER
- ACCOUNT_PROVISIONER=LDAP
- LDAP_SERVER_HOST=ldap # your ldap container/IP/ServerName
- LDAP_SEARCH_BASE=ou=people,dc=localhost,dc=localdomain
- LDAP_BIND_DN=cn=admin,dc=localhost,dc=localdomain

View File

@ -34,7 +34,9 @@ Those variables contain the LDAP lookup filters for postfix, using `%s` as the p
A really simple `LDAP_QUERY_FILTER` configuration, using only the _user filter_ and allowing only `admin@*` to spoof any sender addresses.
```yaml
- ENABLE_LDAP=1
- ENABLE_LDAP=1 # with the :edge tag, use ACCOUNT_PROVISIONER
- LDAP_START_TLS=yes
- ACCOUNT_PROVISIONER=LDAP
- LDAP_SERVER_HOST=ldap.example.org
- LDAP_SEARCH_BASE=dc=example,dc=org"
- LDAP_BIND_DN=cn=admin,dc=example,dc=org
@ -138,7 +140,7 @@ In addition to LDAP explanation above, when Docker Mailserver is intended to be
The configuration shown to get the Group to work is from [here](https://doc.zarafa.com/trunk/Administrator_Manual/en-US/html/_MTAIntegration.html) and [here](https://kb.kopano.io/display/WIKI/Postfix).
```
```bash
# user-patches.sh
...
@ -149,7 +151,7 @@ grep -q '^special_result_attribute = member$' /etc/postfix/ldap-groups.cf || ech
- In `/etc/ldap/ldap.conf`, if the `TLS_REQCERT` is `demand` / `hard` (default), the CA certificate used to verify the LDAP server certificate must be recognized as a trusted CA. This can be done by volume mounting the `ca.crt` file and updating the trust store via a `user-patches.sh` script:
```
```bash
# user-patches.sh
...
@ -160,7 +162,7 @@ update-ca-certificates
The changes on the configurations necessary to work with Active Directory (**only changes are listed, the rest of the LDAP configuration can be taken from the other examples** shown in this documentation):
```
```yaml
# If StartTLS is the chosen method to establish a secure connection with Active Directory.
- LDAP_START_TLS=yes
- SASLAUTHD_LDAP_START_TLS=yes
@ -215,7 +217,8 @@ The changes on the configurations necessary to work with Active Directory (**onl
- ENABLE_POSTGREY=1
# >>> Postfix LDAP Integration
- ENABLE_LDAP=1
- ENABLE_LDAP=1 # with the :edge tag, use ACCOUNT_PROVISIONER
- ACCOUNT_PROVISIONER=LDAP
- LDAP_SERVER_HOST=ldap.example.org
- LDAP_BIND_DN=cn=admin,ou=users,dc=example,dc=org
- LDAP_BIND_PW=mypassword
@ -287,7 +290,8 @@ The changes on the configurations necessary to work with Active Directory (**onl
# <<< SASL Authentication
# >>> Postfix Ldap Integration
- ENABLE_LDAP=1
- ENABLE_LDAP=1 # with the :edge tag, use ACCOUNT_PROVISIONER
- ACCOUNT_PROVISIONER=LDAP
- LDAP_SERVER_HOST=<yourLdapContainer/yourLdapServer>
- LDAP_SEARCH_BASE=dc=mydomain,dc=loc
- LDAP_BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=loc

View File

@ -40,6 +40,17 @@ The log-level will show everything in its class and above.
- 0 => state in default directories.
- **1** => consolidate all states into a single directory (`/var/mail-state`) to allow persistence using docker volumes. See the [related FAQ entry][docs-faq-onedir] for more information.
##### ACCOUNT_PROVISIONER
Configures the provisioning source of user accounts (including aliases) for user queries and authentication by services managed by DMS (_Postfix and Dovecot_).
User provisioning via OIDC is planned for the future, see [this tracking issue](https://github.com/docker-mailserver/docker-mailserver/issues/2713).
- **empty** => use FILE
- LDAP => use LDAP authentication
- OIDC => use OIDC authentication (**not yet implemented**)
- FILE => use local files (this is used as the default)
##### PERMIT_DOCKER
Set different options for mynetworks option (can be overwrite in postfix-main.cf) **WARNING**: Adding the docker network's gateway to the list of trusted hosts, e.g. using the `network` or `connected-networks` option, can create an [**open relay**](https://en.wikipedia.org/wiki/Open_mail_relay), for instance if IPv6 is enabled on the host machine but not in Docker.
@ -439,11 +450,7 @@ Note: The defaults of your fetchmailrc file need to be at the top of the file. O
##### ENABLE_LDAP
- **empty** => LDAP authentification is disabled
- 1 => LDAP authentification is enabled
- NOTE:
- A second container for the ldap service is necessary (e.g. [docker-openldap](https://github.com/osixia/docker-openldap))
- For preparing the ldap server to use in combination with this container [this](http://acidx.net/wordpress/2014/06/installing-a-mailserver-with-postfix-dovecot-sasl-ldap-roundcube/) article may be helpful
Deprecated. See [`ACCOUNT_PROVISIONER`](#account_provisioner).
##### LDAP_START_TLS

View File

@ -130,9 +130,7 @@ function _setup_postfix_aliases
cp -f /tmp/docker-mailserver/postfix-virtual.cf /etc/postfix/virtual
# the `to` is important, don't delete it
# shellcheck disable=SC2034
while read -r FROM TO
while read -r FROM _
do
# Setting variables for better readability
UNAME=$(echo "${FROM}" | cut -d @ -f1)

View File

@ -30,7 +30,8 @@ We can create aliases with `./setup.sh`, like this:
If you want to send emails from outside the mail-server you have to authenticate somehow (with a username and password). One way of doing it is described in [this discussion][github-issue-1247]. However if there are many user accounts, it is better to use authentication with LDAP. The settings for this on `mailserver.env` are:
```env
ENABLE_LDAP=1
ENABLE_LDAP=1 # with the :edge tag, use ACCOUNT_PROVISIONER
ACCOUNT_PROVISIONER=LDAP
LDAP_START_TLS=yes
LDAP_SERVER_HOST=ldap.example.org
LDAP_SEARCH_BASE=ou=users,dc=example,dc=org
@ -104,9 +105,5 @@ You see that besides `query_filter`, I had to customize as well `result_attribut
Another solution that serves as a forward-only mail-server is [this](https://gitlab.com/docker-scripts/postfix).
!!! tip
One user reports only having success if `ENABLE_LDAP=0` was set.
[docs-userpatches]: ../../config/advanced/override-defaults/user-patches.md
[github-issue-1247]: https://github.com/docker-mailserver/docker-mailserver/issues/1247

View File

@ -34,6 +34,12 @@ SUPERVISOR_LOGLEVEL=
# 1 => consolidate all states into a single directory (`/var/mail-state`) to allow persistence using docker volumes
ONE_DIR=1
# **empty** => use FILE
# LDAP => use LDAP authentication
# OIDC => use OIDC authentication (not yet implemented)
# FILE => use local files (this is used as the default)
ACCOUNT_PROVISIONER=
# empty => postmaster@domain.com
# => Specify the postmaster address
POSTMASTER_ADDRESS=
@ -324,6 +330,7 @@ FETCHMAIL_POLL=300
# A second container for the ldap service is necessary (i.e. https://github.com/osixia/docker-openldap)
# For preparing the ldap server to use in combination with this container this article may be helpful: http://acidx.net/wordpress/2014/06/installing-a-mailserver-with-postfix-dovecot-sasl-ldap-roundcube/
# with the :edge tag, use ACCOUNT_PROVISIONER=LDAP
# empty => LDAP authentification is disabled
# 1 => LDAP authentification is enabled
ENABLE_LDAP=

View File

@ -14,10 +14,11 @@ function _create_accounts
: >/etc/postfix/vmailbox
: >"${DOVECOT_USERDB_FILE}"
[[ ${ENABLE_LDAP} -eq 1 ]] && return 0
[[ ${ACCOUNT_PROVISIONER} == 'FILE' ]] || return 0
local DATABASE_ACCOUNTS='/tmp/docker-mailserver/postfix-accounts.cf'
_create_masters
if [[ -f ${DATABASE_ACCOUNTS} ]]
then
_log 'trace' "Checking file line endings"

View File

@ -17,6 +17,9 @@ function _obtain_hostname_and_domainname
# TODO: Consider changing to `DMS_FQDN`; a more accurate name, and removing the `export`, assuming no
# subprocess like postconf would be called that would need access to the same value via `$HOSTNAME` ENV.
#
# ! There is already a stub in variables.sh which contains DMS_FQDN. One will just need to uncomment the
# ! correct lines in variables.sh.
#
# TODO: `OVERRIDE_HOSTNAME` was introduced for non-Docker runtimes that could not configure an explicit hostname.
# Kubernetes was the particular runtime in 2017. This does not update `/etc/hosts` or other locations, thus risking
# inconsistency with expected behaviour. Investigate if it's safe to remove support. (--net=host also uses this as a workaround)

View File

@ -80,7 +80,7 @@ function _vhost_collect_postfix_domains
# conditionally include a 2nd table (ldap:/etc/postfix/ldap-domains.cf).
function _vhost_ldap_support
{
[[ ${ENABLE_LDAP} -eq 1 ]] && echo "${DOMAINNAME}" >>"${TMP_VHOST}"
[[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]] && echo "${DOMAINNAME}" >>"${TMP_VHOST}"
}
# Docs - Postfix lookup table files:

View File

@ -0,0 +1,212 @@
#! /bin/bash
# shellcheck disable=SC2034
declare -A VARS
# shellcheck disable=SC2034
declare -a FUNCS_SETUP FUNCS_FIX FUNCS_CHECK FUNCS_MISC DAEMONS_START
# This function handles variables that are deprecated. This allows a
# smooth transition period, without the need of removing a variable
# completely with a single version.
function _environment_variables_backwards_compatibility
{
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
# TODO this can be uncommented in a PR handling the HOSTNAME/DOMAINNAME issue
# TODO see check_for_changes.sh and dns.sh
# if [[ -n ${OVERRIDE_HOSTNAME:-} ]]
# then
# _log 'warn' "'OVERRIDE_HOSTNAME' is deprecated (and will be removed in v13.0.0) => use 'DMS_FQDN' instead"
# [[ -z ${DMS_FQDN} ]] && DMS_FQDN=${OVERRIDE_HOSTNAME}
# fi
}
# This function Writes the contents of the `VARS` map (associative array)
# to locations where they can be sourced from (e.g. `/etc/dms-settings`)
# or where they can be used by Bash directly (e.g. `/root/.bashrc`).
function _environment_variables_export
{
_log 'debug' "Exporting environment variables now (creating '/etc/dms-settings')"
: >/root/.bashrc # make DMS variables available in login shells and their subprocesses
: >/etc/dms-settings # this file can be sourced by other scripts
local VAR
for VAR in "${!VARS[@]}"
do
echo "export ${VAR}='${VARS[${VAR}]}'" >>/root/.bashrc
echo "${VAR}='${VARS[${VAR}]}'" >>/etc/dms-settings
done
sort -o /root/.bashrc /root/.bashrc
sort -o /etc/dms-settings /etc/dms-settings
}
# This function sets almost all environment variables. This involves setting
# a default if no value was provided and writing the variable and its value
# to the VARS map.
function _environment_variables_general_setup
{
_log 'debug' 'Handling general environment variable setup'
# these variables must be defined first
# they are used as default values for other variables
VARS[POSTMASTER_ADDRESS]="${POSTMASTER_ADDRESS:=postmaster@${DOMAINNAME}}"
VARS[REPORT_RECIPIENT]="${REPORT_RECIPIENT:=${POSTMASTER_ADDRESS}}"
VARS[REPORT_SENDER]="${REPORT_SENDER:=mailserver-report@${HOSTNAME}}"
_log 'trace' 'Setting anti-spam & anti-virus environment variables'
VARS[AMAVIS_LOGLEVEL]="${AMAVIS_LOGLEVEL:=0}"
VARS[CLAMAV_MESSAGE_SIZE_LIMIT]="${CLAMAV_MESSAGE_SIZE_LIMIT:=25M}"
VARS[FAIL2BAN_BLOCKTYPE]="${FAIL2BAN_BLOCKTYPE:=drop}"
VARS[MOVE_SPAM_TO_JUNK]="${MOVE_SPAM_TO_JUNK:=1}"
VARS[POSTGREY_AUTO_WHITELIST_CLIENTS]="${POSTGREY_AUTO_WHITELIST_CLIENTS:=5}"
VARS[POSTGREY_DELAY]="${POSTGREY_DELAY:=300}"
VARS[POSTGREY_MAX_AGE]="${POSTGREY_MAX_AGE:=35}"
VARS[POSTGREY_TEXT]="${POSTGREY_TEXT:=Delayed by Postgrey}"
VARS[POSTSCREEN_ACTION]="${POSTSCREEN_ACTION:=enforce}"
VARS[SA_KILL]=${SA_KILL:="6.31"}
VARS[SA_SPAM_SUBJECT]=${SA_SPAM_SUBJECT:="***SPAM*** "}
VARS[SA_TAG]=${SA_TAG:="2.0"}
VARS[SA_TAG2]=${SA_TAG2:="6.31"}
VARS[SPAMASSASSIN_SPAM_TO_INBOX]="${SPAMASSASSIN_SPAM_TO_INBOX:=1}"
VARS[SPOOF_PROTECTION]="${SPOOF_PROTECTION:=0}"
VARS[VIRUSMAILS_DELETE_DELAY]="${VIRUSMAILS_DELETE_DELAY:=7}"
_log 'trace' 'Setting service-enabling environment variables'
VARS[ENABLE_AMAVIS]="${ENABLE_AMAVIS:=1}"
VARS[ENABLE_CLAMAV]="${ENABLE_CLAMAV:=0}"
VARS[ENABLE_DNSBL]="${ENABLE_DNSBL:=0}"
VARS[ENABLE_FAIL2BAN]="${ENABLE_FAIL2BAN:=0}"
VARS[ENABLE_FETCHMAIL]="${ENABLE_FETCHMAIL:=0}"
VARS[ENABLE_MANAGESIEVE]="${ENABLE_MANAGESIEVE:=0}"
VARS[ENABLE_POP3]="${ENABLE_POP3:=0}"
VARS[ENABLE_POSTGREY]="${ENABLE_POSTGREY:=0}"
VARS[ENABLE_QUOTAS]="${ENABLE_QUOTAS:=1}"
VARS[ENABLE_SASLAUTHD]="${ENABLE_SASLAUTHD:=0}"
VARS[ENABLE_SPAMASSASSIN]="${ENABLE_SPAMASSASSIN:=0}"
VARS[ENABLE_SPAMASSASSIN_KAM]="${ENABLE_SPAMASSASSIN_KAM:=0}"
VARS[ENABLE_SRS]="${ENABLE_SRS:=0}"
VARS[ENABLE_UPDATE_CHECK]="${ENABLE_UPDATE_CHECK:=1}"
_log 'trace' 'Setting IP, DNS and SSL environment variables'
VARS[DEFAULT_RELAY_HOST]="${DEFAULT_RELAY_HOST:=}"
# VARS[DMS_FQDN]="${DMS_FQDN:=}"
# VARS[DMS_DOMAINNAME]="${DMS_DOMAINNAME:=}"
# VARS[DMS_HOSTNAME]="${DMS_HOSTNAME:=}"
VARS[NETWORK_INTERFACE]="${NETWORK_INTERFACE:=eth0}"
VARS[OVERRIDE_HOSTNAME]="${OVERRIDE_HOSTNAME:-}"
VARS[RELAY_HOST]="${RELAY_HOST:=}"
VARS[SSL_TYPE]="${SSL_TYPE:=}"
VARS[TLS_LEVEL]="${TLS_LEVEL:=modern}"
_log 'trace' 'Setting Dovecot- and Postfix-specific environment variables'
VARS[DOVECOT_INET_PROTOCOLS]="${DOVECOT_INET_PROTOCOLS:=all}"
VARS[DOVECOT_MAILBOX_FORMAT]="${DOVECOT_MAILBOX_FORMAT:=maildir}"
VARS[DOVECOT_TLS]="${DOVECOT_TLS:=no}"
VARS[POSTFIX_INET_PROTOCOLS]="${POSTFIX_INET_PROTOCOLS:=all}"
VARS[POSTFIX_MAILBOX_SIZE_LIMIT]="${POSTFIX_MAILBOX_SIZE_LIMIT:=0}"
VARS[POSTFIX_MESSAGE_SIZE_LIMIT]="${POSTFIX_MESSAGE_SIZE_LIMIT:=10240000}" # ~10 MB
_log 'trace' 'Setting miscellaneous environment variables'
VARS[ACCOUNT_PROVISIONER]="${ACCOUNT_PROVISIONER:=FILE}"
VARS[FETCHMAIL_PARALLEL]="${FETCHMAIL_PARALLEL:=0}"
VARS[FETCHMAIL_POLL]="${FETCHMAIL_POLL:=300}"
VARS[LOG_LEVEL]="${LOG_LEVEL:=info}"
VARS[LOGROTATE_INTERVAL]="${LOGROTATE_INTERVAL:=weekly}"
VARS[LOGWATCH_INTERVAL]="${LOGWATCH_INTERVAL:=none}"
VARS[LOGWATCH_RECIPIENT]="${LOGWATCH_RECIPIENT:=${REPORT_RECIPIENT}}"
VARS[LOGWATCH_SENDER]="${LOGWATCH_SENDER:=${REPORT_SENDER}}"
VARS[ONE_DIR]="${ONE_DIR:=1}"
VARS[PERMIT_DOCKER]="${PERMIT_DOCKER:=none}"
VARS[PFLOGSUMM_RECIPIENT]="${PFLOGSUMM_RECIPIENT:=${REPORT_RECIPIENT}}"
VARS[PFLOGSUMM_SENDER]="${PFLOGSUMM_SENDER:=${REPORT_SENDER}}"
VARS[PFLOGSUMM_TRIGGER]="${PFLOGSUMM_TRIGGER:=none}"
VARS[SMTP_ONLY]="${SMTP_ONLY:=0}"
VARS[SRS_SENDER_CLASSES]="${SRS_SENDER_CLASSES:=envelope_sender}"
VARS[SUPERVISOR_LOGLEVEL]="${SUPERVISOR_LOGLEVEL:=warn}"
VARS[TZ]="${TZ:=}"
VARS[UPDATE_CHECK_INTERVAL]="${UPDATE_CHECK_INTERVAL:=1d}"
}
# This function handles environment variables related to LDAP.
function _environment_variables_ldap
{
_log 'debug' 'Setting LDAP-related environment variables now'
VARS[LDAP_BIND_DN]="${LDAP_BIND_DN:=}"
VARS[LDAP_BIND_PW]="${LDAP_BIND_PW:=}"
VARS[LDAP_SEARCH_BASE]="${LDAP_SEARCH_BASE:=}"
VARS[LDAP_SERVER_HOST]="${LDAP_SERVER_HOST:=}"
VARS[LDAP_START_TLS]="${LDAP_START_TLS:=no}"
}
# This function handles environment variables related to SASLAUTHD
# and, if activated, variables related to SASLAUTHD and LDAP.
function _environment_variables_saslauthd
{
_log 'debug' 'Setting SASLAUTHD-related environment variables now'
VARS[SASLAUTHD_MECHANISMS]="${SASLAUTHD_MECHANISMS:=pam}"
# SASL ENV for configuring an LDAP specific
# `saslauthd.conf` via `setup-stack.sh:_setup_sasulauthd()`
if [[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]]
then
_log 'trace' 'Setting SASLSAUTH-LDAP variables nnow'
VARS[SASLAUTHD_LDAP_AUTH_METHOD]="${SASLAUTHD_LDAP_AUTH_METHOD:=bind}"
VARS[SASLAUTHD_LDAP_BIND_DN]="${SASLAUTHD_LDAP_BIND_DN:=${LDAP_BIND_DN}}"
VARS[SASLAUTHD_LDAP_FILTER]="${SASLAUTHD_LDAP_FILTER:=(&(uniqueIdentifier=%u)(mailEnabled=TRUE))}"
VARS[SASLAUTHD_LDAP_PASSWORD]="${SASLAUTHD_LDAP_PASSWORD:=${LDAP_BIND_PW}}"
VARS[SASLAUTHD_LDAP_SEARCH_BASE]="${SASLAUTHD_LDAP_SEARCH_BASE:=${LDAP_SEARCH_BASE}}"
VARS[SASLAUTHD_LDAP_SERVER]="${SASLAUTHD_LDAP_SERVER:=${LDAP_SERVER_HOST}}"
[[ ${SASLAUTHD_LDAP_SERVER} != *'://'* ]] && SASLAUTHD_LDAP_SERVER="ldap://${SASLAUTHD_LDAP_SERVER}"
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
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
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
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
SASLAUTHD_LDAP_MECH=''
else
SASLAUTHD_LDAP_MECH="ldap_mech: ${SASLAUTHD_LDAP_MECH}"
fi
VARS[SASLAUTHD_LDAP_MECH]="${SASLAUTHD_LDAP_MECH}"
fi
}

View File

@ -31,142 +31,19 @@ source /usr/local/bin/daemons-stack.sh
# ------------------------------------------------------------
# ? << Sourcing helpers & stacks
# --
# ? >> Setup Supervisor & DNS names
# ? >> Early setup & environment variables setup
# ------------------------------------------------------------
# Setup supervisord as early as possible
declare -A VARS
VARS[SUPERVISOR_LOGLEVEL]="${SUPERVISOR_LOGLEVEL:=warn}"
# shellcheck source=./helpers/variables.sh
source /usr/local/bin/helpers/variables.sh
_setup_supervisor
_obtain_hostname_and_domainname
_environment_variables_backwards_compatibility
_environment_variables_general_setup
# ------------------------------------------------------------
# ? << Setup Supervisor & DNS names
# --
# ? >> Setup of default and global values / variables
# ------------------------------------------------------------
# shellcheck disable=SC2034
declare -a FUNCS_SETUP FUNCS_FIX FUNCS_CHECK FUNCS_MISC DAEMONS_START
# These variables must be defined first; They are used as default values for other variables.
VARS[POSTMASTER_ADDRESS]="${POSTMASTER_ADDRESS:=postmaster@${DOMAINNAME}}"
VARS[REPORT_RECIPIENT]="${REPORT_RECIPIENT:=${POSTMASTER_ADDRESS}}"
VARS[REPORT_SENDER]="${REPORT_SENDER:=mailserver-report@${HOSTNAME}}"
VARS[AMAVIS_LOGLEVEL]="${AMAVIS_LOGLEVEL:=0}"
VARS[CLAMAV_MESSAGE_SIZE_LIMIT]="${CLAMAV_MESSAGE_SIZE_LIMIT:=25M}" # 25 MB
VARS[DEFAULT_RELAY_HOST]="${DEFAULT_RELAY_HOST:=}"
VARS[DOVECOT_INET_PROTOCOLS]="${DOVECOT_INET_PROTOCOLS:=all}"
VARS[DOVECOT_MAILBOX_FORMAT]="${DOVECOT_MAILBOX_FORMAT:=maildir}"
VARS[DOVECOT_TLS]="${DOVECOT_TLS:=no}"
VARS[ENABLE_AMAVIS]="${ENABLE_AMAVIS:=1}"
VARS[ENABLE_CLAMAV]="${ENABLE_CLAMAV:=0}"
VARS[ENABLE_DNSBL]="${ENABLE_DNSBL:=0}"
VARS[ENABLE_FAIL2BAN]="${ENABLE_FAIL2BAN:=0}"
VARS[ENABLE_FETCHMAIL]="${ENABLE_FETCHMAIL:=0}"
VARS[ENABLE_LDAP]="${ENABLE_LDAP:=0}"
VARS[ENABLE_MANAGESIEVE]="${ENABLE_MANAGESIEVE:=0}"
VARS[ENABLE_POP3]="${ENABLE_POP3:=0}"
VARS[ENABLE_POSTGREY]="${ENABLE_POSTGREY:=0}"
VARS[ENABLE_QUOTAS]="${ENABLE_QUOTAS:=1}"
VARS[ENABLE_SASLAUTHD]="${ENABLE_SASLAUTHD:=0}"
VARS[ENABLE_SPAMASSASSIN]="${ENABLE_SPAMASSASSIN:=0}"
VARS[ENABLE_SPAMASSASSIN_KAM]="${ENABLE_SPAMASSASSIN_KAM:=0}"
VARS[ENABLE_SRS]="${ENABLE_SRS:=0}"
VARS[ENABLE_UPDATE_CHECK]="${ENABLE_UPDATE_CHECK:=1}"
VARS[FAIL2BAN_BLOCKTYPE]="${FAIL2BAN_BLOCKTYPE:=drop}"
VARS[FETCHMAIL_PARALLEL]="${FETCHMAIL_PARALLEL:=0}"
VARS[FETCHMAIL_POLL]="${FETCHMAIL_POLL:=300}"
VARS[LDAP_START_TLS]="${LDAP_START_TLS:=no}"
VARS[LOG_LEVEL]="${LOG_LEVEL:=info}"
VARS[LOGROTATE_INTERVAL]="${LOGROTATE_INTERVAL:=weekly}"
VARS[LOGWATCH_INTERVAL]="${LOGWATCH_INTERVAL:=none}"
VARS[LOGWATCH_RECIPIENT]="${LOGWATCH_RECIPIENT:=${REPORT_RECIPIENT}}"
VARS[LOGWATCH_SENDER]="${LOGWATCH_SENDER:=${REPORT_SENDER}}"
VARS[MOVE_SPAM_TO_JUNK]="${MOVE_SPAM_TO_JUNK:=1}"
VARS[NETWORK_INTERFACE]="${NETWORK_INTERFACE:=eth0}"
VARS[ONE_DIR]="${ONE_DIR:=1}"
VARS[OVERRIDE_HOSTNAME]="${OVERRIDE_HOSTNAME:-}"
VARS[PERMIT_DOCKER]="${PERMIT_DOCKER:=none}"
VARS[PFLOGSUMM_RECIPIENT]="${PFLOGSUMM_RECIPIENT:=${REPORT_RECIPIENT}}"
VARS[PFLOGSUMM_SENDER]="${PFLOGSUMM_SENDER:=${REPORT_SENDER}}"
VARS[PFLOGSUMM_TRIGGER]="${PFLOGSUMM_TRIGGER:=none}"
VARS[POSTFIX_INET_PROTOCOLS]="${POSTFIX_INET_PROTOCOLS:=all}"
VARS[POSTFIX_MAILBOX_SIZE_LIMIT]="${POSTFIX_MAILBOX_SIZE_LIMIT:=0}"
VARS[POSTFIX_MESSAGE_SIZE_LIMIT]="${POSTFIX_MESSAGE_SIZE_LIMIT:=10240000}" # ~10 MB
VARS[POSTGREY_AUTO_WHITELIST_CLIENTS]="${POSTGREY_AUTO_WHITELIST_CLIENTS:=5}"
VARS[POSTGREY_DELAY]="${POSTGREY_DELAY:=300}"
VARS[POSTGREY_MAX_AGE]="${POSTGREY_MAX_AGE:=35}"
VARS[POSTGREY_TEXT]="${POSTGREY_TEXT:=Delayed by Postgrey}"
VARS[POSTSCREEN_ACTION]="${POSTSCREEN_ACTION:=enforce}"
VARS[RELAY_HOST]="${RELAY_HOST:=}"
VARS[SA_KILL]=${SA_KILL:="6.31"}
VARS[SA_SPAM_SUBJECT]=${SA_SPAM_SUBJECT:="***SPAM*** "}
VARS[SA_TAG]=${SA_TAG:="2.0"}
VARS[SA_TAG2]=${SA_TAG2:="6.31"}
VARS[SMTP_ONLY]="${SMTP_ONLY:=0}"
VARS[SPAMASSASSIN_SPAM_TO_INBOX]="${SPAMASSASSIN_SPAM_TO_INBOX:=1}"
VARS[SPOOF_PROTECTION]="${SPOOF_PROTECTION:=0}"
VARS[SRS_SENDER_CLASSES]="${SRS_SENDER_CLASSES:=envelope_sender}"
VARS[SSL_TYPE]="${SSL_TYPE:=}"
VARS[TLS_LEVEL]="${TLS_LEVEL:=modern}"
VARS[TZ]="${TZ:=}"
VARS[UPDATE_CHECK_INTERVAL]="${UPDATE_CHECK_INTERVAL:=1d}"
VARS[VIRUSMAILS_DELETE_DELAY]="${VIRUSMAILS_DELETE_DELAY:=7}"
# SASL specific variables
VARS[LDAP_BIND_DN]="${LDAP_BIND_DN:=}"
VARS[LDAP_BIND_PW]="${LDAP_BIND_PW:=}"
VARS[LDAP_SEARCH_BASE]="${LDAP_SEARCH_BASE:=}"
VARS[LDAP_SERVER_HOST]="${LDAP_SERVER_HOST:=}"
VARS[SASLAUTHD_LDAP_AUTH_METHOD]="${SASLAUTHD_LDAP_AUTH_METHOD:=bind}"
VARS[SASLAUTHD_LDAP_BIND_DN]="${SASLAUTHD_LDAP_BIND_DN:=${LDAP_BIND_DN}}"
VARS[SASLAUTHD_LDAP_FILTER]="${SASLAUTHD_LDAP_FILTER:=(&(uniqueIdentifier=%u)(mailEnabled=TRUE))}"
VARS[SASLAUTHD_LDAP_PASSWORD]="${SASLAUTHD_LDAP_PASSWORD:=${LDAP_BIND_PW}}"
VARS[SASLAUTHD_LDAP_SEARCH_BASE]="${SASLAUTHD_LDAP_SEARCH_BASE:=${LDAP_SEARCH_BASE}}"
VARS[SASLAUTHD_LDAP_SERVER]="${SASLAUTHD_LDAP_SERVER:=${LDAP_SERVER_HOST}}"
[[ ${SASLAUTHD_LDAP_SERVER} != *'://'* ]] && SASLAUTHD_LDAP_SERVER="ldap://${SASLAUTHD_LDAP_SERVER}"
VARS[SASLAUTHD_LDAP_START_TLS]="${SASLAUTHD_LDAP_START_TLS:=no}"
VARS[SASLAUTHD_LDAP_TLS_CHECK_PEER]="${SASLAUTHD_LDAP_TLS_CHECK_PEER:=no}"
VARS[SASLAUTHD_MECHANISMS]="${SASLAUTHD_MECHANISMS:=pam}"
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
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
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
SASLAUTHD_LDAP_MECH=''
else
SASLAUTHD_LDAP_MECH="ldap_mech: ${SASLAUTHD_LDAP_MECH}"
fi
VARS[SASLAUTHD_LDAP_MECH]="${SASLAUTHD_LDAP_MECH}"
# ------------------------------------------------------------
# ? << Setup of default and global values / variables
# ? << Early setup & environment variables setup
# --
# ? >> Registering functions
# ------------------------------------------------------------
@ -183,22 +60,42 @@ function _register_functions
# ? >> Setup
_register_setup_function '_setup_default_vars'
_register_setup_function '_setup_file_permissions'
[[ -n ${TZ} ]] && _register_setup_function '_setup_timezone'
_register_setup_function '_setup_timezone'
if [[ ${SMTP_ONLY} -ne 1 ]]
then
_register_setup_function '_setup_dovecot'
_register_setup_function '_setup_dovecot_dhparam'
_register_setup_function '_setup_dovecot_quota'
_register_setup_function '_setup_dovecot_local_user'
fi
[[ ${ENABLE_LDAP} -eq 1 ]] && _register_setup_function '_setup_ldap'
case "${ACCOUNT_PROVISIONER}" in
( 'FILE' )
_register_setup_function '_setup_dovecot_local_user'
;;
( 'LDAP' )
_environment_variables_ldap
_register_setup_function '_setup_ldap'
;;
( 'OIDC' )
_register_setup_function '_setup_oidc'
;;
( * )
_shutdown "'${ACCOUNT_PROVISIONER}' is not a valid value for ACCOUNT_PROVISIONER"
;;
esac
if [[ ${ENABLE_SASLAUTHD} -eq 1 ]]
then
_environment_variables_saslauthd
_register_setup_function '_setup_saslauthd'
fi
[[ ${ENABLE_POSTGREY} -eq 1 ]] && _register_setup_function '_setup_postgrey'
[[ ${ENABLE_SASLAUTHD} -eq 1 ]] && _register_setup_function '_setup_saslauthd'
[[ ${POSTFIX_INET_PROTOCOLS} != 'all' ]] && _register_setup_function '_setup_postfix_inet_protocols'
[[ ${DOVECOT_INET_PROTOCOLS} != 'all' ]] && _register_setup_function '_setup_dovecot_inet_protocols'
[[ ${ENABLE_FAIL2BAN} -eq 1 ]] && _register_setup_function '_setup_fail2ban'
@ -259,6 +156,7 @@ function _register_functions
# ? >> Miscellaneous
_register_misc_function '_misc_save_states'
_register_setup_function '_environment_variables_export'
# ? >> Daemons
@ -282,7 +180,7 @@ function _register_functions
[[ ${ENABLE_FAIL2BAN} -eq 1 ]] && _register_start_daemon '_start_daemon_fail2ban'
[[ ${ENABLE_FETCHMAIL} -eq 1 ]] && _register_start_daemon '_start_daemon_fetchmail'
[[ ${ENABLE_CLAMAV} -eq 1 ]] && _register_start_daemon '_start_daemon_clamav'
[[ ${ENABLE_LDAP} -eq 0 ]] && _register_start_daemon '_start_daemon_changedetector'
[[ ${ACCOUNT_PROVISIONER} == 'FILE' ]] && _register_start_daemon '_start_daemon_changedetector'
[[ ${ENABLE_AMAVIS} -eq 1 ]] && _register_start_daemon '_start_daemon_amavis'
}

View File

@ -14,6 +14,8 @@ function _setup
function _setup_supervisor
{
SUPERVISOR_LOGLEVEL="${SUPERVISOR_LOGLEVEL:-warn}"
if ! grep -q "loglevel = ${SUPERVISOR_LOGLEVEL}" /etc/supervisor/supervisord.conf
then
case "${SUPERVISOR_LOGLEVEL}" in
@ -26,9 +28,7 @@ function _setup_supervisor
exit
;;
( 'warn' )
return 0
;;
( 'warn' ) ;;
( * )
_log 'warn' \
@ -41,24 +41,6 @@ function _setup_supervisor
return 0
}
function _setup_default_vars
{
_log 'debug' 'Setting up default variables'
: >/root/.bashrc # make DMS variables available in login shells and their subprocesses
: >/etc/dms-settings # this file can be sourced by other scripts
local VAR
for VAR in "${!VARS[@]}"
do
echo "export ${VAR}='${VARS[${VAR}]}'" >>/root/.bashrc
echo "${VAR}='${VARS[${VAR}]}'" >>/etc/dms-settings
done
sort -o /root/.bashrc /root/.bashrc
sort -o /etc/dms-settings /etc/dms-settings
}
# File/folder permissions are fine when using docker volumes, but may be wrong
# when file system folders are mounted into the container.
# Set the expected values and create missing folders/files just in case.
@ -220,7 +202,7 @@ function _setup_dovecot_quota
_log 'debug' 'Setting up Dovecot quota'
# Dovecot quota is disabled when using LDAP or SMTP_ONLY or when explicitly disabled.
if [[ ${ENABLE_LDAP} -eq 1 ]] || [[ ${SMTP_ONLY} -eq 1 ]] || [[ ${ENABLE_QUOTAS} -eq 0 ]]
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 ]]
@ -274,9 +256,10 @@ function _setup_dovecot_quota
function _setup_dovecot_local_user
{
_log 'debug' 'Setting up Dovecot Local User'
[[ ${SMTP_ONLY} -eq 1 ]] && return 0
[[ ${ACCOUNT_PROVISIONER} == 'FILE' ]] || return 0
[[ ${ENABLE_LDAP} -eq 1 ]] && return 0
_log 'debug' 'Setting up Dovecot Local User'
if [[ ! -f /tmp/docker-mailserver/postfix-accounts.cf ]]
then
@ -401,6 +384,11 @@ function _setup_ldap
return 0
}
function _setup_oidc
{
_shutdown 'OIDC user account provisioning is not yet implemented'
}
function _setup_postgrey
{
_log 'debug' 'Configuring Postgrey'
@ -471,7 +459,7 @@ function _setup_spoof_protection
's|smtpd_sender_restrictions =|smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch,|' \
/etc/postfix/main.cf
if [[ ${ENABLE_LDAP} -eq 1 ]]
if [[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]]
then
if [[ -z ${LDAP_QUERY_FILTER_SENDERS} ]]
then
@ -1197,6 +1185,7 @@ EOF
function _setup_timezone
{
[[ -n ${TZ} ]] || return 0
_log 'debug' "Setting timezone to '${TZ}'"
local ZONEINFO_FILE="/usr/share/zoneinfo/${TZ}"

View File

@ -32,7 +32,7 @@ function setup_file() {
-e DOVECOT_PASS_FILTER="(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))" \
-e DOVECOT_TLS=no \
-e DOVECOT_USER_FILTER="(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))" \
-e ENABLE_LDAP=1 \
-e ACCOUNT_PROVISIONER=LDAP \
-e PFLOGSUMM_TRIGGER=logrotate \
-e ENABLE_SASLAUTHD=1 \
-e LDAP_BIND_DN=cn=admin,dc=localhost,dc=localdomain \
@ -42,9 +42,9 @@ function setup_file() {
-e LDAP_QUERY_FILTER_GROUP="(&(mailGroupMember=%s)(mailEnabled=TRUE))" \
-e LDAP_QUERY_FILTER_SENDERS="(|(&(mail=%s)(mailEnabled=TRUE))(&(mailGroupMember=%s)(mailEnabled=TRUE))(|(&(mailAlias=%s)(objectClass=PostfixBookMailForward))(&(mailAlias=%s)(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)))(uniqueIdentifier=some.user.id))" \
-e LDAP_QUERY_FILTER_USER="(&(mail=%s)(mailEnabled=TRUE))" \
-e LDAP_START_TLS=no \
-e LDAP_SEARCH_BASE=ou=people,dc=localhost,dc=localdomain \
-e LDAP_SERVER_HOST=ldap \
-e LDAP_START_TLS=no \
-e PERMIT_DOCKER=container \
-e POSTMASTER_ADDRESS="postmaster@${FQDN_LOCALHOST_A}" \
-e REPORT_RECIPIENT=1 \