diff --git a/docs/content/config/environment.md b/docs/content/config/environment.md index 3091aa40..b181a8ec 100644 --- a/docs/content/config/environment.md +++ b/docs/content/config/environment.md @@ -39,7 +39,8 @@ The log-level will show everything in its class and above. 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. -- **empty** => localhost only. +- **none** => Explicitly force authentication +- container => Container IP address only. - host => Add docker host (ipv4 only). - network => Add the docker default bridge network (172.16.0.0/12); **WARNING**: `docker-compose` might use others (e.g. 192.168.0.0/16) use `PERMIT_DOCKER=connected-networks` in this case. - connected-networks => Add all connected docker networks (ipv4 only). diff --git a/mailserver.env b/mailserver.env index 519330fe..abac0d53 100644 --- a/mailserver.env +++ b/mailserver.env @@ -48,12 +48,13 @@ UPDATE_CHECK_INTERVAL=1d # https://github.com/docker-mailserver/docker-mailserver/issues/1405#issuecomment-590106498 # The same can happen for rootless podman. To prevent this, set the value to "none" or configure slirp4netns # https://github.com/docker-mailserver/docker-mailserver/issues/2377 -# => container ip only +# # none => Explicitly force authentication +# container => Container IP address only # host => Add docker container network (ipv4 only) # network => Add all docker container networks (ipv4 only) # connected-networks => Add all connected docker networks (ipv4 only) -PERMIT_DOCKER= +PERMIT_DOCKER=none # In case you network interface differs from 'eth0', e.g. when you are using HostNetworking in Kubernetes, # you can set NETWORK_INTERFACE to whatever interface you want. This interface will then be used. diff --git a/target/scripts/start-mailserver.sh b/target/scripts/start-mailserver.sh index bc64d2e3..1c70462c 100755 --- a/target/scripts/start-mailserver.sh +++ b/target/scripts/start-mailserver.sh @@ -47,6 +47,7 @@ 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[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}" # ~10MB diff --git a/target/scripts/startup/setup-stack.sh b/target/scripts/startup/setup-stack.sh index 64f5affe..edf474e7 100644 --- a/target/scripts/startup/setup-stack.sh +++ b/target/scripts/startup/setup-stack.sh @@ -754,38 +754,44 @@ function _setup_docker_permit postconf -e "mynetworks =" ;; - "host" ) - _notify 'inf' "Adding ${CONTAINER_NETWORK}/16 to my networks" - postconf -e "$(postconf | grep '^mynetworks =') ${CONTAINER_NETWORK}/16" - echo "${CONTAINER_NETWORK}/16" >> /etc/opendmarc/ignore.hosts - echo "${CONTAINER_NETWORK}/16" >> /etc/opendkim/TrustedHosts - ;; - - "network" ) - _notify 'inf' "Adding docker network in my networks" - postconf -e "$(postconf | grep '^mynetworks =') 172.16.0.0/12" - echo 172.16.0.0/12 >> /etc/opendmarc/ignore.hosts - echo 172.16.0.0/12 >> /etc/opendkim/TrustedHosts - ;; - "connected-networks" ) for NETWORK in "${CONTAINER_NETWORKS[@]}" do NETWORK=$(_sanitize_ipv4_to_subnet_cidr "${NETWORK}") - _notify 'inf' "Adding docker network ${NETWORK} in my networks" + _notify 'inf' "Adding docker network ${NETWORK} to Postfix's 'mynetworks'" postconf -e "$(postconf | grep '^mynetworks =') ${NETWORK}" echo "${NETWORK}" >> /etc/opendmarc/ignore.hosts echo "${NETWORK}" >> /etc/opendkim/TrustedHosts done ;; - * ) - _notify 'inf' 'Adding container ip in my networks' + "container" ) + _notify 'inf' "Adding container IP address to Postfix's 'mynetworks'" postconf -e "$(postconf | grep '^mynetworks =') ${CONTAINER_IP}/32" echo "${CONTAINER_IP}/32" >> /etc/opendmarc/ignore.hosts echo "${CONTAINER_IP}/32" >> /etc/opendkim/TrustedHosts ;; + "host" ) + _notify 'inf' "Adding ${CONTAINER_NETWORK}/16 to Postfix's 'mynetworks'" + postconf -e "$(postconf | grep '^mynetworks =') ${CONTAINER_NETWORK}/16" + echo "${CONTAINER_NETWORK}/16" >> /etc/opendmarc/ignore.hosts + echo "${CONTAINER_NETWORK}/16" >> /etc/opendkim/TrustedHosts + ;; + + "network" ) + _notify 'inf' "Adding docker network to Postfix's 'mynetworks'" + postconf -e "$(postconf | grep '^mynetworks =') 172.16.0.0/12" + echo 172.16.0.0/12 >> /etc/opendmarc/ignore.hosts + echo 172.16.0.0/12 >> /etc/opendkim/TrustedHosts + ;; + + * ) + _notify 'warn' "Invalid value for PERMIT_DOCKER: ${PERMIT_DOCKER}" + _notify 'inf' "Clearing Postfix's 'mynetworks'" + postconf -e "mynetworks =" + ;; + esac } diff --git a/test/mail_lmtp_ip.bats b/test/mail_lmtp_ip.bats index 87fc2aeb..151c966b 100644 --- a/test/mail_lmtp_ip.bats +++ b/test/mail_lmtp_ip.bats @@ -5,13 +5,14 @@ setup_file() { PRIVATE_CONFIG="$(duplicate_config_for_container .)" PRIVATE_ETC="$(duplicate_config_for_container dovecot-lmtp/ mail_lmtp_ip_dovecot-lmtp)" docker run -d --name mail_lmtp_ip \ - -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ - -v "${PRIVATE_ETC}":/etc/dovecot \ - -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ - -e ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1 \ - -e POSTFIX_DAGENT=lmtp:127.0.0.1:24 \ - -e DMS_DEBUG=0 \ - -h mail.my-domain.com -t "${NAME}" + -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ + -v "${PRIVATE_ETC}":/etc/dovecot \ + -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ + -e DMS_DEBUG=0 \ + -e ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1 \ + -e POSTFIX_DAGENT=lmtp:127.0.0.1:24 \ + -e PERMIT_DOCKER=container \ + -h mail.my-domain.com -t "${NAME}" wait_for_finished_setup_in_container mail_lmtp_ip } diff --git a/test/mail_pop3.bats b/test/mail_pop3.bats index fdc8fb41..d78f1348 100644 --- a/test/mail_pop3.bats +++ b/test/mail_pop3.bats @@ -4,11 +4,12 @@ function setup_file() { local PRIVATE_CONFIG PRIVATE_CONFIG="$(duplicate_config_for_container .)" docker run -d --name mail_pop3 \ - -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ - -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ - -e ENABLE_POP3=1 \ - -e DMS_DEBUG=0 \ - -h mail.my-domain.com -t "${NAME}" + -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ + -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ + -e DMS_DEBUG=0 \ + -e ENABLE_POP3=1 \ + -e PERMIT_DOCKER=container \ + -h mail.my-domain.com -t "${NAME}" wait_for_finished_setup_in_container mail_pop3 } diff --git a/test/mail_spam_bounced.bats b/test/mail_spam_bounced.bats index 571e7129..7de19585 100644 --- a/test/mail_spam_bounced.bats +++ b/test/mail_spam_bounced.bats @@ -27,6 +27,7 @@ function setup_file() { # shellcheck disable=SC2034 local TEST_DOCKER_ARGS=( --env ENABLE_SPAMASSASSIN=1 + --env PERMIT_DOCKER=container --env SPAMASSASSIN_SPAM_TO_INBOX=0 ) diff --git a/test/mail_spam_junk_folder.bats b/test/mail_spam_junk_folder.bats index fda69bb3..6f0fd03e 100644 --- a/test/mail_spam_junk_folder.bats +++ b/test/mail_spam_junk_folder.bats @@ -11,9 +11,10 @@ load 'test_helper/common' -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ -e ENABLE_SPAMASSASSIN=1 \ - -e SPAMASSASSIN_SPAM_TO_INBOX=1 \ -e MOVE_SPAM_TO_JUNK=1 \ + -e PERMIT_DOCKER=container \ -e SA_SPAM_SUBJECT="SPAM: " \ + -e SPAMASSASSIN_SPAM_TO_INBOX=1 \ -h mail.my-domain.com -t "${NAME}" teardown() { docker rm -f mail_spam_moved_junk; } @@ -39,9 +40,10 @@ load 'test_helper/common' -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ -e ENABLE_SPAMASSASSIN=1 \ - -e SPAMASSASSIN_SPAM_TO_INBOX=1 \ -e MOVE_SPAM_TO_JUNK=0 \ + -e PERMIT_DOCKER=container \ -e SA_SPAM_SUBJECT="SPAM: " \ + -e SPAMASSASSIN_SPAM_TO_INBOX=1 \ -h mail.my-domain.com -t "${NAME}" teardown() { docker rm -f mail_spam_moved_new; } diff --git a/test/mail_ssl_letsencrypt.bats b/test/mail_ssl_letsencrypt.bats index b7815626..231d6c14 100644 --- a/test/mail_ssl_letsencrypt.bats +++ b/test/mail_ssl_letsencrypt.bats @@ -50,6 +50,7 @@ function teardown() { local TEST_DOCKER_ARGS=( --volume "${TEST_TMP_CONFIG}/letsencrypt/${TARGET_DOMAIN}/:/etc/letsencrypt/live/${TARGET_DOMAIN}/:ro" + --env PERMIT_DOCKER='container' --env SSL_TYPE='letsencrypt' ) @@ -69,6 +70,7 @@ function teardown() { local TEST_DOCKER_ARGS=( --volume "${TEST_TMP_CONFIG}/letsencrypt/${TARGET_DOMAIN}/:/etc/letsencrypt/live/${TARGET_DOMAIN}/:ro" + --env PERMIT_DOCKER='container' --env SSL_TYPE='letsencrypt' ) @@ -107,9 +109,10 @@ function teardown() { # shellcheck disable=SC2034 local TEST_DOCKER_ARGS=( --volume "${TEST_TMP_CONFIG}/letsencrypt/acme.json:/etc/letsencrypt/acme.json:ro" - --env SSL_TYPE='letsencrypt' - --env SSL_DOMAIN='*.example.test' --env DMS_DEBUG=1 + --env PERMIT_DOCKER='container' + --env SSL_DOMAIN='*.example.test' + --env SSL_TYPE='letsencrypt' ) common_container_setup 'TEST_DOCKER_ARGS' diff --git a/test/mail_with_imap.bats b/test/mail_with_imap.bats index 0a976984..7fbbdbea 100644 --- a/test/mail_with_imap.bats +++ b/test/mail_with_imap.bats @@ -5,14 +5,15 @@ setup_file() { local PRIVATE_CONFIG PRIVATE_CONFIG="$(duplicate_config_for_container .)" docker run -d --name mail_with_imap \ - -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ - -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ - -e ENABLE_SASLAUTHD=1 \ - -e SASLAUTHD_MECHANISMS=rimap \ - -e SASLAUTHD_MECH_OPTIONS=127.0.0.1 \ - -e POSTMASTER_ADDRESS=postmaster@localhost.localdomain \ - -e DMS_DEBUG=0 \ - -h mail.my-domain.com -t "${NAME}" + -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ + -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ + -e DMS_DEBUG=0 \ + -e ENABLE_SASLAUTHD=1 \ + -e POSTMASTER_ADDRESS=postmaster@localhost.localdomain \ + -e SASLAUTHD_MECH_OPTIONS=127.0.0.1 \ + -e SASLAUTHD_MECHANISMS=rimap \ + -e PERMIT_DOCKER=container \ + -h mail.my-domain.com -t "${NAME}" wait_for_smtp_port_in_container mail_with_imap } diff --git a/test/mail_with_ldap.bats b/test/mail_with_ldap.bats index 1fea71ad..a297f731 100644 --- a/test/mail_with_ldap.bats +++ b/test/mail_with_ldap.bats @@ -28,26 +28,27 @@ function setup_file() { docker run -d --name mail_with_ldap \ -v "${PRIVATE_CONFIG}:/tmp/docker-mailserver" \ -v "$(pwd)/test/test-files:/tmp/docker-mailserver-test:ro" \ - -e SPOOF_PROTECTION=1 \ + -e DMS_DEBUG=0 \ + -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 LDAP_SERVER_HOST=ldap \ - -e LDAP_START_TLS=no \ - -e LDAP_SEARCH_BASE=ou=people,dc=localhost,dc=localdomain \ + -e ENABLE_SASLAUTHD=1 \ -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)(objectClass=PostfixBookMailForward))(&(mailAlias=%s)(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)))" \ -e LDAP_QUERY_FILTER_DOMAIN="(|(&(mail=*@%s)(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE))(&(mailGroupMember=*@%s)(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE))(&(mailalias=*@%s)(objectClass=PostfixBookMailForward)))" \ + -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 DOVECOT_TLS=no \ - -e DOVECOT_PASS_FILTER="(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))" \ - -e DOVECOT_USER_FILTER="(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))" \ - -e REPORT_RECIPIENT=1 \ - -e ENABLE_SASLAUTHD=1 \ - -e SASLAUTHD_MECHANISMS=ldap \ + -e LDAP_QUERY_FILTER_USER="(&(mail=%s)(mailEnabled=TRUE))" \ + -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 DMS_DEBUG=0 \ + -e REPORT_RECIPIENT=1 \ + -e SASLAUTHD_MECHANISMS=ldap \ + -e SPOOF_PROTECTION=1 \ -e SSL_TYPE='snakeoil' \ --network "${DMS_TEST_NETWORK}" \ --hostname "${FQDN_MAIL}" \ @@ -190,14 +191,14 @@ function teardown_file() { assert_failure } -@test "checking spoofing: rejects sender forging" { +@test "checking spoofing (with LDAP): rejects sender forging" { wait_for_smtp_port_in_container_to_respond mail_with_ldap run docker exec mail_with_ldap /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/ldap-smtp-auth-spoofed.txt | grep 'Sender address rejected: not owned by user'" assert_success } # ATTENTION: these tests must come after "checking dovecot: ldap mail delivery works" since they will deliver an email which skews the count in said test, leading to failure -@test "checking spoofing: accepts sending as alias" { +@test "checking spoofing: accepts sending as alias (with LDAP)" { run docker exec mail_with_ldap /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/ldap-smtp-auth-spoofed-alias.txt | grep 'End data with'" assert_success } diff --git a/test/mail_with_postgrey.bats b/test/mail_with_postgrey.bats index 6f1a8f61..ffb9d3ba 100644 --- a/test/mail_with_postgrey.bats +++ b/test/mail_with_postgrey.bats @@ -6,13 +6,14 @@ function setup_file() { docker run -d --name mail_with_postgrey \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ + -e DMS_DEBUG=0 \ + -e ENABLE_DNSBL=1 \ -e ENABLE_POSTGREY=1 \ + -e PERMIT_DOCKER=container \ + -e POSTGREY_AUTO_WHITELIST_CLIENTS=5 \ -e POSTGREY_DELAY=15 \ -e POSTGREY_MAX_AGE=35 \ - -e POSTGREY_AUTO_WHITELIST_CLIENTS=5 \ -e POSTGREY_TEXT="Delayed by Postgrey" \ - -e ENABLE_DNSBL=1 \ - -e DMS_DEBUG=0 \ -h mail.my-domain.com -t "${NAME}" # using postfix availability as start indicator, this might be insufficient for postgrey wait_for_smtp_port_in_container mail_with_postgrey diff --git a/test/tests.bats b/test/tests.bats index 13b06350..f4580f0c 100644 --- a/test/tests.bats +++ b/test/tests.bats @@ -19,9 +19,9 @@ setup_file() { -e ENABLE_MANAGESIEVE=1 \ -e ENABLE_QUOTAS=1 \ -e ENABLE_SPAMASSASSIN=1 \ - -e SPAMASSASSIN_SPAM_TO_INBOX=0 \ -e ENABLE_SRS=1 \ -e ENABLE_UPDATE_CHECK=0 \ + -e PERMIT_DOCKER=container \ -e PERMIT_DOCKER=host \ -e REPORT_RECIPIENT=user1@localhost.localdomain \ -e REPORT_SENDER=report1@mail.my-domain.com \ @@ -30,6 +30,7 @@ setup_file() { -e SA_TAG=-5.0 \ -e SA_TAG2=2.0 \ -e SASL_PASSWD="external-domain.com username:password" \ + -e SPAMASSASSIN_SPAM_TO_INBOX=0 \ -e SPOOF_PROTECTION=1 \ -e SSL_TYPE='snakeoil' \ -e VIRUSMAILS_DELETE_DELAY=7 \