From 2e4e65b705bf3d53710f56e87a60af079e1bd5db Mon Sep 17 00:00:00 2001 From: alinmear Date: Wed, 7 Jun 2017 15:35:42 +0200 Subject: [PATCH 1/6] Fix Container Startup Fails on daemon start: opendkim #621 (#627) --- Makefile | 8 ++++++++ target/start-mailserver.sh | 3 +++ test/tests.bats | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/Makefile b/Makefile index ede3f53c..d8a99868 100644 --- a/Makefile +++ b/Makefile @@ -51,6 +51,13 @@ run: -e OVERRIDE_HOSTNAME=mail.my-domain.com \ -t $(NAME) sleep 15 + docker run -d --name mail_smtponly_without_config \ + -e SMTP_ONLY=1 \ + -e ENABLE_LDAP=1 \ + -e PERMIT_DOCKER=network \ + -e OVERRIDE_HOSTNAME=mail.mydomain.com \ + -t $(NAME) + sleep 15 docker run -d --name mail_override_hostname \ -v "`pwd`/test/config":/tmp/docker-mailserver \ -v "`pwd`/test":/tmp/docker-mailserver-test \ @@ -177,6 +184,7 @@ clean: mail \ mail_pop3 \ mail_smtponly \ + mail_smtponly_without_config \ mail_fail2ban \ mail_fetchmail \ fail-auth-mailer \ diff --git a/target/start-mailserver.sh b/target/start-mailserver.sh index 94bddb6c..220a1e0c 100644 --- a/target/start-mailserver.sh +++ b/target/start-mailserver.sh @@ -734,6 +734,9 @@ function _setup_dkim() { chmod -R 0700 /etc/opendkim/keys/ else notify 'warn' "No DKIM key provided. Check the documentation to find how to get your keys." + + local _f_keytable="/etc/opendkim/KeyTable" + [ ! -f "$_f_keytable" ] && touch "$_f_keytable" fi } diff --git a/test/tests.bats b/test/tests.bats index 05c73536..c8700da2 100644 --- a/test/tests.bats +++ b/test/tests.bats @@ -472,6 +472,12 @@ load 'test_helper/bats-assert/load' assert_output 2 } +@test "checking opendkim: /etc/opendkim/KeyTable dummy file generated without keys provided" { + run docker exec mail_smtponly_without_config /bin/bash -c "cat /etc/opendkim/KeyTable" + assert_success +} + + @test "checking opendkim: /etc/opendkim/keys/ should contain 2 entries" { run docker exec mail /bin/sh -c "ls -l /etc/opendkim/keys/ | grep '^d' | wc -l" assert_success From 3569aebcb6bee8a5f5e520df3c516a3604485fc2 Mon Sep 17 00:00:00 2001 From: MadsRC Date: Tue, 13 Jun 2017 13:20:25 +0200 Subject: [PATCH 2/6] Support for modifying Postfix' master.cf (#595) * Support for modifying Postfix' master.cf, using the syntax, in postfix-master.cf --- config/postfix-master.cf | 0 target/start-mailserver.sh | 10 ++++++++++ test/config/postfix-master.cf | 1 + test/tests.bats | 5 +++++ 4 files changed, 16 insertions(+) create mode 100644 config/postfix-master.cf create mode 100644 test/config/postfix-master.cf diff --git a/config/postfix-master.cf b/config/postfix-master.cf new file mode 100644 index 00000000..e69de29b diff --git a/target/start-mailserver.sh b/target/start-mailserver.sh index 220a1e0c..a2a6b5de 100644 --- a/target/start-mailserver.sh +++ b/target/start-mailserver.sh @@ -904,6 +904,16 @@ function _setup_postfix_override_configuration() { else notify 'inf' "No extra postfix settings loaded because optional '/tmp/docker-mailserver/postfix-main.cf' not provided." fi + if [ -f /tmp/docker-mailserver/postfix-master.cf ]; then + while read line; do + if [[ "$line" =~ ^[a-z] ]]; then + postconf -P "$line" + fi + done < /tmp/docker-mailserver/postfix-master.cf + notify 'inf' "Loaded 'config/postfix-master.cf'" + else + notify 'inf' "No extra postfix settings loaded because optional '/tmp/docker-mailserver/postfix-master.cf' not provided." + fi } function _setup_postfix_sasl_password() { diff --git a/test/config/postfix-master.cf b/test/config/postfix-master.cf new file mode 100644 index 00000000..a6c1d80d --- /dev/null +++ b/test/config/postfix-master.cf @@ -0,0 +1 @@ +submission/inet/smtpd_sasl_security_options=noanonymous diff --git a/test/tests.bats b/test/tests.bats index c8700da2..512aee35 100644 --- a/test/tests.bats +++ b/test/tests.bats @@ -391,6 +391,11 @@ load 'test_helper/bats-assert/load' assert_success } +@test "checking postfix: master.cf overrides" { + run docker exec mail grep -q 'submission/inet/smtpd_sasl_security_options=noanonymous' /tmp/docker-mailserver/postfix-master.cf + assert_success +} + # # dovecot # From 5a86193dbffefc253d9cbae040dc08927ddaa612 Mon Sep 17 00:00:00 2001 From: Alexander Elbracht Date: Fri, 23 Jun 2017 21:50:01 +0200 Subject: [PATCH 3/6] Environment variable for amavis subject tag (#596) * Environment variable for spam subject tag * Add SA_SPAM_SUBJECT to readme * Add integration tests for spam subject tag * Fix overwrite environment variable in config file --- Makefile | 1 + README.md | 7 ++++++- target/start-mailserver.sh | 1 + test/tests.bats | 4 ++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d8a99868..c43fd70b 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ run: -e SA_TAG=-5.0 \ -e SA_TAG2=2.0 \ -e SA_KILL=3.0 \ + -e SA_SPAM_SUBJECT="SPAM: " \ -e VIRUSMAILS_DELETE_DELAY=7 \ -e SASL_PASSWD="external-domain.com username:password" \ -e ENABLE_MANAGESIEVE=1 \ diff --git a/README.md b/README.md index 22e981ea..438af213 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,12 @@ Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1` Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1` +##### SA_SPAM_SUBJECT + + - **\*\*\*SPAM\*\*\*** => add tag to subject if spam detected + +Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1` + ##### ONE_DIR - **0** => state in default directories @@ -336,4 +342,3 @@ Enabled by ENABLE_POSTFIX_VIRTUAL_TRANSPORT. Specify the final delivery of postf - lmtps:inet:: (secure lmtp with starttls, take a look at https://sys4.de/en/blog/2014/11/17/sicheres-lmtp-mit-starttls-in-dovecot/) - lmtp::2003 (use kopano as mailstore) - etc. - diff --git a/target/start-mailserver.sh b/target/start-mailserver.sh index a2a6b5de..56a7ac6c 100644 --- a/target/start-mailserver.sh +++ b/target/start-mailserver.sh @@ -970,6 +970,7 @@ function _setup_security_stack() { SA_TAG=${SA_TAG:="2.0"} && sed -i -r 's/^\$sa_tag_level_deflt (.*);/\$sa_tag_level_deflt = '$SA_TAG';/g' /etc/amavis/conf.d/20-debian_defaults SA_TAG2=${SA_TAG2:="6.31"} && sed -i -r 's/^\$sa_tag2_level_deflt (.*);/\$sa_tag2_level_deflt = '$SA_TAG2';/g' /etc/amavis/conf.d/20-debian_defaults SA_KILL=${SA_KILL:="6.31"} && sed -i -r 's/^\$sa_kill_level_deflt (.*);/\$sa_kill_level_deflt = '$SA_KILL';/g' /etc/amavis/conf.d/20-debian_defaults + SA_SPAM_SUBJECT=${SA_SPAM_SUBJECT:="***SPAM*** "} && sed -i -r 's/^\$sa_spam_subject_tag (.*);/\$sa_spam_subject_tag = '"'$SA_SPAM_SUBJECT'"';/g' /etc/amavis/conf.d/20-debian_defaults test -e /tmp/docker-mailserver/spamassassin-rules.cf && cp /tmp/docker-mailserver/spamassassin-rules.cf /etc/spamassassin/ fi diff --git a/test/tests.bats b/test/tests.bats index 512aee35..c27872b0 100644 --- a/test/tests.bats +++ b/test/tests.bats @@ -429,6 +429,8 @@ load 'test_helper/bats-assert/load' assert_success run docker exec mail_pop3 /bin/sh -c "grep '\$sa_kill_level_deflt' /etc/amavis/conf.d/20-debian_defaults | grep '= 6.31'" assert_success + run docker exec mail_pop3 /bin/sh -c "grep '\$sa_spam_subject_tag' /etc/amavis/conf.d/20-debian_defaults | grep '= .\*\*\*SPAM\*\*\* .'" + assert_success } @test "checking spamassassin: docker env variables are set correctly (custom)" { @@ -438,6 +440,8 @@ load 'test_helper/bats-assert/load' assert_success run docker exec mail /bin/sh -c "grep '\$sa_kill_level_deflt' /etc/amavis/conf.d/20-debian_defaults | grep '= 3.0'" assert_success + run docker exec mail /bin/sh -c "grep '\$sa_spam_subject_tag' /etc/amavis/conf.d/20-debian_defaults | grep '= .SPAM: .'" + assert_success } @test "checking spamassassin: all registered domains should see spam headers" { From 1effcdebd744077361d2e27d4b28c3c19f334b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20F=C3=A9vrier?= Date: Sat, 1 Jul 2017 14:32:12 +0200 Subject: [PATCH 4/6] Letsencrypt : do not check the optional cert.pem (#639) --- target/start-mailserver.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/target/start-mailserver.sh b/target/start-mailserver.sh index 56a7ac6c..c26d8366 100644 --- a/target/start-mailserver.sh +++ b/target/start-mailserver.sh @@ -747,8 +747,7 @@ function _setup_ssl() { case $SSL_TYPE in "letsencrypt" ) # letsencrypt folders and files mounted in /etc/letsencrypt - if [ -e "/etc/letsencrypt/live/$HOSTNAME/cert.pem" ] \ - && [ -e "/etc/letsencrypt/live/$HOSTNAME/fullchain.pem" ]; then + if [ -e "/etc/letsencrypt/live/$HOSTNAME/fullchain.pem" ]; then KEY="" if [ -e "/etc/letsencrypt/live/$HOSTNAME/privkey.pem" ]; then KEY="privkey" From 21fb3f3c86391f079afb7fb59260b64019fa2e51 Mon Sep 17 00:00:00 2001 From: alinmear Date: Mon, 3 Jul 2017 13:16:16 +0200 Subject: [PATCH 5/6] 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 --- Makefile | 6 ++ README.md | 117 +++++++++++++++++++++++++++++++------ target/start-mailserver.sh | 110 +++++++++++++++++++--------------- test/tests.bats | 37 +++++++----- 4 files changed, 190 insertions(+), 80 deletions(-) diff --git a/Makefile b/Makefile index c43fd70b..e0695097 100644 --- a/Makefile +++ b/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 \ diff --git a/README.md b/README.md index 438af213..18c0f2ed 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Your configs must be mounted in `/tmp/docker-mailserver/`. To understand how thi `restart: always` ensures that the mail server container (and ELK container when using the mail server together with ELK stack) is automatically restarted by Docker in cases like a Docker service or host restart or container exit. -```yaml +```yaml version: '2' services: @@ -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 @@ -234,13 +311,13 @@ Otherwise, `iptables` won't be able to ban IPs. Note: This postgrey setting needs `ENABLE_POSTGREY=1` ##### POSTGREY_MAX_AGE - + - **35** => delete entries older than N days since the last time that they have been seen Note: This postgrey setting needs `ENABLE_POSTGREY=1` ##### POSTGREY_TEXT - + - **Delayed by postgrey** => response when a mail is greylisted Note: This postgrey setting needs `ENABLE_POSTGREY=1` @@ -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:: (secure lmtp with starttls, take a look at https://sys4.de/en/blog/2014/11/17/sicheres-lmtp-mit-starttls-in-dovecot/) - - lmtp::2003 (use kopano as mailstore) - - etc. + +- **empty**: fail +- `lmtp:unix:private/dovecot-lmtp` (use socket) +- `lmtps:inet::` (secure lmtp with starttls, take a look at https://sys4.de/en/blog/2014/11/17/sicheres-lmtp-mit-starttls-in-dovecot/) +- `lmtp::2003` (use kopano as mailstore) +- etc. diff --git a/target/start-mailserver.sh b/target/start-mailserver.sh index c26d8366..1f5438d0 100644 --- a/target/start-mailserver.sh +++ b/target/start-mailserver.sh @@ -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 - # 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-) + IFS=" " read -r -a _config_files <<< $2 - config_overrides[$key]=$value - done + # 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-) - 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 + 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 + + sed -i -e "s|^${key}[[:space:]]\+.*|${key} = ${config_overrides[$key]//&/\\&}|g" \ + ${f} + done + fi + done } # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -569,21 +569,37 @@ function _setup_ldap() { for i in 'users' 'groups' 'aliases'; do fpath="/tmp/docker-mailserver/ldap-${i}.cf" if [ -f $fpath ]; then - cp ${fpath} /etc/postfix/ldap-${i}.cf + cp ${fpath} /etc/postfix/ldap-${i}.cf fi 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 + + 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" - # @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 - # Add domainname to vhost. echo $DOMAINNAME >> /tmp/vhost.tmp @@ -629,7 +645,7 @@ EOF # cyrus sasl or dovecot sasl if [[ ${ENABLE_SASLAUTHD} == 1 ]] || [[ ${SMTP_ONLY} == 0 ]];then sed -i -e 's|^smtpd_sasl_auth_enable[[:space:]]\+.*|smtpd_sasl_auth_enable = yes|g' /etc/postfix/main.cf - else + else sed -i -e 's|^smtpd_sasl_auth_enable[[:space:]]\+.*|smtpd_sasl_auth_enable = no|g' /etc/postfix/main.cf fi @@ -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" \ diff --git a/test/tests.bats b/test/tests.bats index c27872b0..e6d6db7c 100644 --- a/test/tests.bats +++ b/test/tests.bats @@ -341,7 +341,7 @@ load 'test_helper/bats-assert/load' run docker exec mail_smtponly /bin/sh -c 'grep -cE "to=.*status\=sent" /var/log/mail/mail.log' [ "$status" -ge 0 ] } - + # @@ -1051,34 +1051,34 @@ load 'test_helper/bats-assert/load' } @test "checking postfix: ldap custom config files copied" { - run docker exec mail_with_ldap /bin/sh -c "grep '# Testconfig for ldap integration' /etc/postfix/ldap-users.cf" + run docker exec mail_with_ldap /bin/sh -c "grep '# Testconfig for ldap integration' /etc/postfix/ldap-users.cf" assert_success - run docker exec mail_with_ldap /bin/sh -c "grep '# Testconfig for ldap integration' /etc/postfix/ldap-groups.cf" + run docker exec mail_with_ldap /bin/sh -c "grep '# Testconfig for ldap integration' /etc/postfix/ldap-groups.cf" assert_success - run docker exec mail_with_ldap /bin/sh -c "grep '# Testconfig for ldap integration' /etc/postfix/ldap-aliases.cf" + run docker exec mail_with_ldap /bin/sh -c "grep '# Testconfig for ldap integration' /etc/postfix/ldap-aliases.cf" assert_success } @test "checking postfix: ldap config overwrites success" { - run docker exec mail_with_ldap /bin/sh -c "grep 'server_host = ldap' /etc/postfix/ldap-users.cf" + run docker exec mail_with_ldap /bin/sh -c "grep 'server_host = ldap' /etc/postfix/ldap-users.cf" assert_success - run docker exec mail_with_ldap /bin/sh -c "grep 'search_base = ou=people,dc=localhost,dc=localdomain' /etc/postfix/ldap-users.cf" + run docker exec mail_with_ldap /bin/sh -c "grep 'search_base = ou=people,dc=localhost,dc=localdomain' /etc/postfix/ldap-users.cf" assert_success - run docker exec mail_with_ldap /bin/sh -c "grep 'bind_dn = cn=admin,dc=localhost,dc=localdomain' /etc/postfix/ldap-users.cf" + run docker exec mail_with_ldap /bin/sh -c "grep 'bind_dn = cn=admin,dc=localhost,dc=localdomain' /etc/postfix/ldap-users.cf" assert_success - run docker exec mail_with_ldap /bin/sh -c "grep 'server_host = ldap' /etc/postfix/ldap-groups.cf" + run docker exec mail_with_ldap /bin/sh -c "grep 'server_host = ldap' /etc/postfix/ldap-groups.cf" assert_success - run docker exec mail_with_ldap /bin/sh -c "grep 'search_base = ou=people,dc=localhost,dc=localdomain' /etc/postfix/ldap-groups.cf" + run docker exec mail_with_ldap /bin/sh -c "grep 'search_base = ou=people,dc=localhost,dc=localdomain' /etc/postfix/ldap-groups.cf" assert_success - run docker exec mail_with_ldap /bin/sh -c "grep 'bind_dn = cn=admin,dc=localhost,dc=localdomain' /etc/postfix/ldap-groups.cf" + run docker exec mail_with_ldap /bin/sh -c "grep 'bind_dn = cn=admin,dc=localhost,dc=localdomain' /etc/postfix/ldap-groups.cf" assert_success - run docker exec mail_with_ldap /bin/sh -c "grep 'server_host = ldap' /etc/postfix/ldap-aliases.cf" + run docker exec mail_with_ldap /bin/sh -c "grep 'server_host = ldap' /etc/postfix/ldap-aliases.cf" assert_success - run docker exec mail_with_ldap /bin/sh -c "grep 'search_base = ou=people,dc=localhost,dc=localdomain' /etc/postfix/ldap-aliases.cf" + run docker exec mail_with_ldap /bin/sh -c "grep 'search_base = ou=people,dc=localhost,dc=localdomain' /etc/postfix/ldap-aliases.cf" assert_success - run docker exec mail_with_ldap /bin/sh -c "grep 'bind_dn = cn=admin,dc=localhost,dc=localdomain' /etc/postfix/ldap-aliases.cf" + run docker exec mail_with_ldap /bin/sh -c "grep 'bind_dn = cn=admin,dc=localhost,dc=localdomain' /etc/postfix/ldap-aliases.cf" assert_success } @@ -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" From dbf65789f2bd35d725217048d8aa9b8cc49b6090 Mon Sep 17 00:00:00 2001 From: alinmear Date: Mon, 10 Jul 2017 00:11:00 +0200 Subject: [PATCH 6/6] Integrate docker-configomat for configuration parts of start-mailserver.sh #648 (#650) * Add submodule docker-configomat * Add configomat.sh to Dockerfile * Replaced override_config with configomat.sh --- .gitmodules | 3 +++ Dockerfile | 2 +- target/docker-configomat | 1 + target/start-mailserver.sh | 51 +++----------------------------------- 4 files changed, 9 insertions(+), 48 deletions(-) create mode 160000 target/docker-configomat diff --git a/.gitmodules b/.gitmodules index 0ed2caff..bc127a9e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "test/test_helper/bats-assert"] path = test/test_helper/bats-assert url = https://github.com/ztombol/bats-assert +[submodule "target/docker-configomat"] + path = target/docker-configomat + url = https://github.com/alinmear/docker-configomat diff --git a/Dockerfile b/Dockerfile index 5eb466e1..677394a1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -144,7 +144,7 @@ RUN curl -s https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > /et COPY ./target/bin /usr/local/bin # Start-mailserver script -COPY ./target/start-mailserver.sh /usr/local/bin/ +COPY ./target/start-mailserver.sh ./target/docker-configomat/configomat.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/* EXPOSE 25 587 143 993 110 995 4190 diff --git a/target/docker-configomat b/target/docker-configomat new file mode 160000 index 00000000..e3e84ded --- /dev/null +++ b/target/docker-configomat @@ -0,0 +1 @@ +Subproject commit e3e84ded29d88b2945c0782dbb43237c561a54a9 diff --git a/target/start-mailserver.sh b/target/start-mailserver.sh index 1f5438d0..e2c4d5e3 100644 --- a/target/start-mailserver.sh +++ b/target/start-mailserver.sh @@ -316,50 +316,6 @@ function display_startup_daemon() { return $res } -function override_config() { - notify "task" "Starting do do overrides" - - declare -A config_overrides - - _env_variable_prefix=$1 - [ -z ${_env_variable_prefix} ] && return 1 - - - 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-) - - 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 - - sed -i -e "s|^${key}[[:space:]]\+.*|${key} = ${config_overrides[$key]//&/\\&}|g" \ - ${f} - done - fi - done -} - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # ! CARE --> DON'T CHANGE, except you know exactly what you are doing # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -579,7 +535,7 @@ function _setup_ldap() { [[ $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}" + configomat.sh "LDAP_" "${f}" done notify 'inf' "Configuring dovecot LDAP" @@ -598,7 +554,7 @@ function _setup_ldap() { export $var=${_dovecot_ldap_mapping[$var]} done - override_config "DOVECOT_" "/etc/dovecot/dovecot-ldap.conf.ext" + configomat.sh "DOVECOT_" "/etc/dovecot/dovecot-ldap.conf.ext" # Add domainname to vhost. echo $DOMAINNAME >> /tmp/vhost.tmp @@ -763,7 +719,8 @@ function _setup_ssl() { case $SSL_TYPE in "letsencrypt" ) # letsencrypt folders and files mounted in /etc/letsencrypt - if [ -e "/etc/letsencrypt/live/$HOSTNAME/fullchain.pem" ]; then + if [ -e "/etc/letsencrypt/live/$HOSTNAME/cert.pem" ] \ + && [ -e "/etc/letsencrypt/live/$HOSTNAME/fullchain.pem" ]; then KEY="" if [ -e "/etc/letsencrypt/live/$HOSTNAME/privkey.pem" ]; then KEY="privkey"