mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2024-01-19 02:48:50 +00:00
Fix ldap related critical Problems (#644)
* Fix Dovecot Ldap Problems * Fix typo within DEFAULT_VARS Definitions * Fix wrong ldap hosts value within the bats test * Fix override_config for strings containing & * Fix erroneous removal of an conditional within the postfix override function * Renamed Test 129, to be clear that this belongs to ldap * Fix mail_with_ldap setting dn pass explicit * Add 3 env variables for ldap: LDAP_QUERY_FILTER_{USER,GROUP,ALIAS} * Update README.md
This commit is contained in:
parent
1effcdebd7
commit
21fb3f3c86
6
Makefile
6
Makefile
|
@ -107,6 +107,12 @@ run:
|
|||
-e LDAP_SERVER_HOST=ldap \
|
||||
-e LDAP_SEARCH_BASE=ou=people,dc=localhost,dc=localdomain \
|
||||
-e LDAP_BIND_DN=cn=admin,dc=localhost,dc=localdomain \
|
||||
-e LDAP_BIND_PW=admin \
|
||||
-e LDAP_QUERY_FILTER_USER="(&(mail=%s)(mailEnabled=TRUE))" \
|
||||
-e LDAP_QUERY_FILTER_GROUP="(&(mailGroupMember=%s)(mailEnabled=TRUE))" \
|
||||
-e LDAP_QUERY_FILTER_ALIAS="(&(mailAlias=%s)(mailEnabled=TRUE))" \
|
||||
-e DOVECOT_PASS_FILTER="(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))" \
|
||||
-e DOVECOT_USER_FILTER="(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))" \
|
||||
-e ENABLE_SASLAUTHD=1 \
|
||||
-e SASLAUTHD_MECHANISMS=ldap \
|
||||
-e SASLAUTHD_LDAP_SERVER=ldap \
|
||||
|
|
111
README.md
111
README.md
|
@ -79,6 +79,60 @@ volumes:
|
|||
driver: local
|
||||
```
|
||||
|
||||
__for ldap setup__:
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
mail:
|
||||
image: tvial/docker-mailserver:latest
|
||||
hostname: mail
|
||||
domainname: domain.com
|
||||
container_name: mail
|
||||
ports:
|
||||
- "25:25"
|
||||
- "143:143"
|
||||
- "587:587"
|
||||
- "993:993"
|
||||
volumes:
|
||||
- maildata:/var/mail
|
||||
- mailstate:/var/mail-state
|
||||
- ./config/:/tmp/docker-mailserver/
|
||||
environment:
|
||||
- ENABLE_SPAMASSASSIN=1
|
||||
- ENABLE_CLAMAV=1
|
||||
- ENABLE_FAIL2BAN=1
|
||||
- ENABLE_POSTGREY=1
|
||||
- ONE_DIR=1
|
||||
- DMS_DEBUG=0
|
||||
- ENABLE_LDAP=1
|
||||
- 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
|
||||
- LDAP_BIND_PW=admin
|
||||
- LDAP_QUERY_FILTER_USER="(&(mail=%s)(mailEnabled=TRUE))"
|
||||
- LDAP_QUERY_FILTER_GROUP="(&(mailGroupMember=%s)(mailEnabled=TRUE))"
|
||||
- LDAP_QUERY_FILTER_ALIAS="(&(mailAlias=%s)(mailEnabled=TRUE))"
|
||||
- DOVECOT_PASS_FILTER="(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))"
|
||||
- DOVECOT_USER_FILTER="(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))"
|
||||
- ENABLE_SASLAUTHD=1
|
||||
- SASLAUTHD_MECHANISMS=ldap
|
||||
- SASLAUTHD_LDAP_SERVER=ldap
|
||||
- SASLAUTHD_LDAP_BIND_DN=cn=admin,dc=localhost,dc=localdomain
|
||||
- SASLAUTHD_LDAP_PASSWORD=admin
|
||||
- SASLAUTHD_LDAP_SEARCH_BASE=ou=people,dc=localhost,dc=localdomain
|
||||
- POSTMASTER_ADDRESS=postmaster@localhost.localdomain
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
|
||||
volumes:
|
||||
maildata:
|
||||
driver: local
|
||||
mailstate:
|
||||
driver: local
|
||||
```
|
||||
|
||||
#### Create your mail accounts
|
||||
|
||||
Don't forget to adapt MAIL_USER and MAIL_PASS to your needs
|
||||
|
@ -212,6 +266,29 @@ Otherwise, `iptables` won't be able to ban IPs.
|
|||
- **empty** => admin
|
||||
- => Specify the password to bind against ldap
|
||||
|
||||
##### LDAP_QUERY_FILTER_USER
|
||||
|
||||
- e.g. `"(&(mail=%s)(mailEnabled=TRUE))"`
|
||||
- => Specify how ldap should be asked for users
|
||||
|
||||
##### LDAP_QUERY_FILTER_GROUP
|
||||
|
||||
- e.g. `"(&(mailGroupMember=%s)(mailEnabled=TRUE))"`
|
||||
- => Specify how ldap should be asked for groups
|
||||
|
||||
##### LDAP_QUERY_FILTER_ALIAS
|
||||
|
||||
- e.g. `"(&(mailAlias=%s)(mailEnabled=TRUE))"`
|
||||
- => Specify how ldap should be asked for aliases
|
||||
|
||||
##### DOVECOT_USER_FILTER
|
||||
|
||||
- e.g. `"(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))"`
|
||||
|
||||
##### DOVECOT_PASS_FILTER
|
||||
|
||||
- e.g. `"(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))"`
|
||||
|
||||
##### OVERRIDE_HOSTNAME
|
||||
|
||||
- **empty** => uses the `hostname` command to get the mail server's canonical hostname
|
||||
|
@ -253,10 +330,10 @@ Note: This postgrey setting needs `ENABLE_POSTGREY=1`
|
|||
##### SASLAUTHD_MECHANISMS
|
||||
|
||||
- empty => pam
|
||||
- ldap => authenticate against ldap server
|
||||
- shadow => authenticate against local user db
|
||||
- mysql => authenticate against mysql db
|
||||
- rimap => authenticate against imap server
|
||||
- `ldap` => authenticate against ldap server
|
||||
- `shadow` => authenticate against local user db
|
||||
- `mysql` => authenticate against mysql db
|
||||
- `rimap` => authenticate against imap server
|
||||
- NOTE: can be a list of mechanisms like pam ldap shadow
|
||||
|
||||
##### SASLAUTHD_MECH_OPTIONS
|
||||
|
@ -270,8 +347,8 @@ Note: This postgrey setting needs `ENABLE_POSTGREY=1`
|
|||
|
||||
##### SASLAUTHD_LDAP_SSL
|
||||
|
||||
- empty or 0 => ldap:// will be used
|
||||
- 1 => ldaps:// will be used
|
||||
- empty or 0 => `ldap://` will be used
|
||||
- 1 => `ldaps://` will be used
|
||||
|
||||
##### SASLAUTHD_LDAP_BIND_DN
|
||||
|
||||
|
@ -291,9 +368,9 @@ Note: This postgrey setting needs `ENABLE_POSTGREY=1`
|
|||
|
||||
##### SASLAUTHD_LDAP_FILTER
|
||||
|
||||
- empty => default filter (&(uniqueIdentifier=%u)(mailEnabled=TRUE))
|
||||
- e.g. for active directory: (&(sAMAccountName=%U)(objectClass=person))
|
||||
- e.g. for openldap: (&(uid=%U)(objectClass=person))
|
||||
- empty => default filter `(&(uniqueIdentifier=%u)(mailEnabled=TRUE))`
|
||||
- e.g. for active directory: `(&(sAMAccountName=%U)(objectClass=person))`
|
||||
- e.g. for openldap: `(&(uid=%U)(objectClass=person))`
|
||||
|
||||
##### SASL_PASSWD
|
||||
|
||||
|
@ -331,14 +408,16 @@ Set how many days a virusmail will stay on the server before being deleted
|
|||
##### ENABLE_POSTFIX_VIRTUAL_TRANSPORT
|
||||
|
||||
This Option is activating the Usage of POSTFIX_DAGENT to specify a ltmp client different from default dovecot socket.
|
||||
- **empty** => disabled
|
||||
- 1 => enabled
|
||||
|
||||
- **empty** => disabled
|
||||
- 1 => enabled
|
||||
|
||||
##### POSTFIX_DAGENT
|
||||
|
||||
Enabled by ENABLE_POSTFIX_VIRTUAL_TRANSPORT. Specify the final delivery of postfix
|
||||
- **empty**: fail
|
||||
- lmtp:unix:private/dovecot-lmtp (use socket)
|
||||
- lmtps:inet:<host>:<port> (secure lmtp with starttls, take a look at https://sys4.de/en/blog/2014/11/17/sicheres-lmtp-mit-starttls-in-dovecot/)
|
||||
- lmtp:<kopano-host>:2003 (use kopano as mailstore)
|
||||
- etc.
|
||||
|
||||
- **empty**: fail
|
||||
- `lmtp:unix:private/dovecot-lmtp` (use socket)
|
||||
- `lmtps:inet:<host>:<port>` (secure lmtp with starttls, take a look at https://sys4.de/en/blog/2014/11/17/sicheres-lmtp-mit-starttls-in-dovecot/)
|
||||
- `lmtp:<kopano-host>:2003` (use kopano as mailstore)
|
||||
- etc.
|
||||
|
|
|
@ -317,47 +317,47 @@ function display_startup_daemon() {
|
|||
}
|
||||
|
||||
function override_config() {
|
||||
notify "task" "Starting do do overrides"
|
||||
notify "task" "Starting do do overrides"
|
||||
|
||||
declare -A config_overrides
|
||||
declare -A config_overrides
|
||||
|
||||
_env_variable_prefix=$1
|
||||
[ -z ${_env_variable_prefix} ] && return 1
|
||||
_env_variable_prefix=$1
|
||||
[ -z ${_env_variable_prefix} ] && return 1
|
||||
|
||||
|
||||
IFS=" " read -r -a _config_files <<< $2
|
||||
IFS=" " read -r -a _config_files <<< $2
|
||||
|
||||
# dispatch env variables
|
||||
for env_variable in $(printenv | grep $_env_variable_prefix);do
|
||||
# get key
|
||||
# IFS not working because values like ldap_query_filter or search base consists of several '='
|
||||
# IFS="=" read -r -a __values <<< $env_variable
|
||||
# key="${__values[0]}"
|
||||
# value="${__values[1]}"
|
||||
key=$(echo $env_variable | cut -d "=" -f1)
|
||||
key=${key#"${_env_variable_prefix}"}
|
||||
# make key lowercase
|
||||
key=${key,,}
|
||||
# get value
|
||||
value=$(echo $env_variable | cut -d "=" -f2-)
|
||||
# dispatch env variables
|
||||
for env_variable in $(printenv | grep $_env_variable_prefix);do
|
||||
# get key
|
||||
# IFS not working because values like ldap_query_filter or search base consists of several '='
|
||||
# IFS="=" read -r -a __values <<< $env_variable
|
||||
# key="${__values[0]}"
|
||||
# value="${__values[1]}"
|
||||
key=$(echo $env_variable | cut -d "=" -f1)
|
||||
key=${key#"${_env_variable_prefix}"}
|
||||
# make key lowercase
|
||||
key=${key,,}
|
||||
# get value
|
||||
value=$(echo $env_variable | cut -d "=" -f2-)
|
||||
|
||||
config_overrides[$key]=$value
|
||||
done
|
||||
config_overrides[$key]=$value
|
||||
done
|
||||
|
||||
for f in "${_config_files[@]}"
|
||||
do
|
||||
if [ ! -f "${f}" ];then
|
||||
echo "Can not find ${f}. Skipping override"
|
||||
else
|
||||
for key in ${!config_overrides[@]}
|
||||
do
|
||||
[ -z $key ] && echo -e "\t no key provided" && return 1
|
||||
for f in "${_config_files[@]}"
|
||||
do
|
||||
if [ ! -f "${f}" ];then
|
||||
echo "Can not find ${f}. Skipping override"
|
||||
else
|
||||
for key in ${!config_overrides[@]}
|
||||
do
|
||||
[ -z $key ] && echo -e "\t no key provided" && return 1
|
||||
|
||||
sed -i -e "s|^${key}[[:space:]]\+.*|${key} = "${config_overrides[$key]}'|g' \
|
||||
${f}
|
||||
done
|
||||
fi
|
||||
done
|
||||
sed -i -e "s|^${key}[[:space:]]\+.*|${key} = ${config_overrides[$key]//&/\\&}|g" \
|
||||
${f}
|
||||
done
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
@ -574,15 +574,31 @@ function _setup_ldap() {
|
|||
done
|
||||
|
||||
notify 'inf' 'Starting to override configs'
|
||||
override_config "LDAP_" "/etc/postfix/ldap-users.cf /etc/postfix/ldap-groups.cf /etc/postfix/ldap-aliases.cf"
|
||||
for f in /etc/postfix/ldap-users.cf /etc/postfix/ldap-groups.cf /etc/postfix/ldap-aliases.cf
|
||||
do
|
||||
[[ $f =~ ldap-user ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_USER}"
|
||||
[[ $f =~ ldap-group ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_GROUP}"
|
||||
[[ $f =~ ldap-aliases ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_ALIAS}"
|
||||
override_config "LDAP_" "${f}"
|
||||
done
|
||||
|
||||
# @TODO: Environment Variables for DOVECOT ldap integration to configure for better control
|
||||
notify 'inf' "Configuring dovecot LDAP authentification"
|
||||
sed -i -e 's|^hosts.*|hosts = '${LDAP_SERVER_HOST:="mail.domain.com"}'|g' \
|
||||
-e 's|^base.*|base = '${LDAP_SEARCH_BASE:="ou=people,dc=domain,dc=com"}'|g' \
|
||||
-e 's|^dn\s*=.*|dn = '${LDAP_BIND_DN:="cn=admin,dc=domain,dc=com"}'|g' \
|
||||
-e 's|^dnpass\s*=.*|dnpass = '${LDAP_BIND_PW:="admin"}'|g' \
|
||||
/etc/dovecot/dovecot-ldap.conf.ext
|
||||
notify 'inf' "Configuring dovecot LDAP"
|
||||
|
||||
declare -A _dovecot_ldap_mapping
|
||||
|
||||
_dovecot_ldap_mapping["DOVECOT_BASE"]="${DOVECOT_BASE:="${LDAP_SEARCH_BASE}"}"
|
||||
_dovecot_ldap_mapping["DOVECOT_DN"]="${DOVECOT_DN:="${LDAP_BIND_DN}"}"
|
||||
_dovecot_ldap_mapping["DOVECOT_DNPASS"]="${DOVECOT_DNPASS:="${LDAP_BIND_PW}"}"
|
||||
_dovecot_ldap_mapping["DOVECOT_HOSTS"]="${DOVECOT_HOSTS:="${LDAP_SERVER_HOST}"}"
|
||||
# Not sure whether this can be the same or not
|
||||
# _dovecot_ldap_mapping["DOVECOT_PASS_FILTER"]="${DOVECOT_PASS_FILTER:="${LDAP_QUERY_FILTER_USER}"}"
|
||||
# _dovecot_ldap_mapping["DOVECOT_USER_FILTER"]="${DOVECOT_USER_FILTER:="${LDAP_QUERY_FILTER_USER}"}"
|
||||
|
||||
for var in ${!_dovecot_ldap_mapping[@]}; do
|
||||
export $var=${_dovecot_ldap_mapping[$var]}
|
||||
done
|
||||
|
||||
override_config "DOVECOT_" "/etc/dovecot/dovecot-ldap.conf.ext"
|
||||
|
||||
# Add domainname to vhost.
|
||||
echo $DOMAINNAME >> /tmp/vhost.tmp
|
||||
|
@ -667,7 +683,7 @@ EOF
|
|||
sed -i \
|
||||
-e "/^[^#].*smtpd_sasl_type.*/s/^/#/g" \
|
||||
-e "/^[^#].*smtpd_sasl_path.*/s/^/#/g" \
|
||||
etc/postfix/master.cf
|
||||
/etc/postfix/master.cf
|
||||
|
||||
sed -i \
|
||||
-e "s|^START=.*|START=yes|g" \
|
||||
|
|
|
@ -1088,7 +1088,7 @@ load 'test_helper/bats-assert/load'
|
|||
assert_success
|
||||
}
|
||||
|
||||
@test "checking dovecot: mail delivery works" {
|
||||
@test "checking dovecot: ldap mail delivery works" {
|
||||
run docker exec mail_with_ldap /bin/sh -c "sendmail -f user@external.tld some.user@localhost.localdomain < /tmp/docker-mailserver-test/email-templates/test-email.txt"
|
||||
sleep 10
|
||||
run docker exec mail_with_ldap /bin/sh -c "ls -A /var/mail/localhost.localdomain/some.user/new | wc -l"
|
||||
|
@ -1096,6 +1096,15 @@ load 'test_helper/bats-assert/load'
|
|||
assert_output 1
|
||||
}
|
||||
|
||||
@test "checking dovecot: ldap config overwrites success" {
|
||||
run docker exec mail_with_ldap /bin/sh -c "grep 'hosts = ldap' /etc/dovecot/dovecot-ldap.conf.ext"
|
||||
assert_success
|
||||
run docker exec mail_with_ldap /bin/sh -c "grep 'base = ou=people,dc=localhost,dc=localdomain' /etc/dovecot/dovecot-ldap.conf.ext"
|
||||
assert_success
|
||||
run docker exec mail_with_ldap /bin/sh -c "grep 'dn = cn=admin,dc=localhost,dc=localdomain' /etc/dovecot/dovecot-ldap.conf.ext"
|
||||
assert_success
|
||||
}
|
||||
|
||||
# saslauthd
|
||||
@test "checking saslauthd: sasl ldap authentication works" {
|
||||
run docker exec mail_with_ldap bash -c "testsaslauthd -u some.user -p secret"
|
||||
|
|
Loading…
Reference in a new issue