Added reject_authenticated_sender_login_mismatch (#872)

* added reject_authenticated_sender_login_mismatch handling including tests
* removed obsolete reject_sender_login_mismatch
* introduced SPOOF_PROTECTION env variable, tests, documentation and missing documentation for TLS_LEVEL
* added missing email template
This commit is contained in:
17Halbe 2018-03-07 19:33:43 +01:00 committed by Johan Smits
parent 4036588c65
commit a73692cc9f
13 changed files with 131 additions and 17 deletions

View file

@ -22,13 +22,29 @@ ONE_DIR=0
# empty => postmaster@domain.com # empty => postmaster@domain.com
# => Specify the postmaster address # => Specify the postmaster address
POSTMASTER_ADDRESS= POSTMASTER_ADDRESS=
# Set different options for mynetworks option (can be overwrite in postfix-main.cf) # Set different options for mynetworks option (can be overwrite in postfix-main.cf)
# empty => localhost only # empty => localhost only
# host => Add docker host (ipv4 only) # host => Add docker host (ipv4 only)
# network => Add all docker containers (ipv4 only) # network => Add all docker containers (ipv4 only)
PERMIT_DOCKER= PERMIT_DOCKER=
# empty => modern
# modern => Enables TLSv1.2 and modern ciphers only. (default)
# intermediate => Enables TLSv1, TLSv1.1 and TLSv1.2 and broad compatibility ciphers.
# old => NOT implemented. If you really need it, then customize the TLS ciphers overriding postfix and dovecot settings
# (https://github.com/tomav/docker-mailserver/wiki/)
TLS_LEVEL=
# Configures the handling of creating mails with forged sender addresses.
#
# empty => (not recommended, but default for backwards compatability reasons)
# Mail address spoofing allowed. Any logged in user may create email messages with a forged sender address.
# See also https://en.wikipedia.org/wiki/Email_spoofing
# 1 => (recommended) Mail spoofing denied. Each user may only send with his own or his alias addresses.
# Addresses with extension delimiters(http://www.postfix.org/postconf.5.html#recipient_delimiter) are not able to send messages.
SPOOF_PROTECTION=
# 1 => Enables POP3 service # 1 => Enables POP3 service
# empty => disables POP3 # empty => disables POP3
ENABLE_POP3= ENABLE_POP3=
@ -85,7 +101,7 @@ POSTFIX_DAGENT=
ENABLE_SPAMASSASSIN=0 ENABLE_SPAMASSASSIN=0
# add spam info headers if at, or above that level: # add spam info headers if at, or above that level:
SA_TAG=2.0 SA_TAG=2.0
# add 'spam detected' headers at that level # add 'spam detected' headers at that level
SA_TAG2=6.31 SA_TAG2=6.31
@ -102,7 +118,7 @@ SA_SPAM_SUBJECT=***SPAM*****
ENABLE_FETCHMAIL=0 ENABLE_FETCHMAIL=0
# The interval to fetch mail in seconds # The interval to fetch mail in seconds
FETCHMAIL_POLL=300 FETCHMAIL_POLL=300
# ----------------------------------------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------------------------------------
@ -220,4 +236,4 @@ SASLAUTHD_LDAP_FILTER=
# empty => No sasl_passwd will be created # empty => No sasl_passwd will be created
# string => `/etc/postfix/sasl_passwd` will be created with the string as password # string => `/etc/postfix/sasl_passwd` will be created with the string as password
SASL_PASSWD= SASL_PASSWD=

View file

@ -176,7 +176,7 @@ RUN mkdir /var/run/fetchmail && chown fetchmail /var/run/fetchmail
# Configures Postfix # Configures Postfix
COPY target/postfix/main.cf target/postfix/master.cf /etc/postfix/ COPY target/postfix/main.cf target/postfix/master.cf /etc/postfix/
COPY target/postfix/sender_header_filter.pcre /etc/postfix/maps/sender_header_filter.pcre COPY target/postfix/sender_header_filter.pcre target/postfix/sender_login_maps.pcre /etc/postfix/maps/
RUN echo "" > /etc/aliases && \ RUN echo "" > /etc/aliases && \
openssl dhparam -out /etc/postfix/dhparams.pem 2048 && \ openssl dhparam -out /etc/postfix/dhparams.pem 2048 && \
echo "@weekly FILE=`mktemp` ; openssl dhparam -out $FILE 2048 > /dev/null 2>&1 && mv -f $FILE /etc/postfix/dhparams.pem" > /etc/cron.d/dh2048 echo "@weekly FILE=`mktemp` ; openssl dhparam -out $FILE 2048 > /dev/null 2>&1 && mv -f $FILE /etc/postfix/dhparams.pem" > /etc/cron.d/dh2048

View file

@ -23,6 +23,7 @@ run:
-v "`pwd`/test":/tmp/docker-mailserver-test \ -v "`pwd`/test":/tmp/docker-mailserver-test \
-v "`pwd`/test/onedir":/var/mail-state \ -v "`pwd`/test/onedir":/var/mail-state \
-e ENABLE_CLAMAV=1 \ -e ENABLE_CLAMAV=1 \
-e SPOOF_PROTECTION=1 \
-e ENABLE_SPAMASSASSIN=1 \ -e ENABLE_SPAMASSASSIN=1 \
-e SA_TAG=-5.0 \ -e SA_TAG=-5.0 \
-e SA_TAG2=2.0 \ -e SA_TAG2=2.0 \
@ -130,6 +131,7 @@ run:
-e ENABLE_LDAP=1 \ -e ENABLE_LDAP=1 \
-e LDAP_SERVER_HOST=ldap \ -e LDAP_SERVER_HOST=ldap \
-e LDAP_START_TLS=no \ -e LDAP_START_TLS=no \
-e SPOOF_PROTECTION=1 \
-e LDAP_SEARCH_BASE=ou=people,dc=localhost,dc=localdomain \ -e LDAP_SEARCH_BASE=ou=people,dc=localhost,dc=localdomain \
-e LDAP_BIND_DN=cn=admin,dc=localhost,dc=localdomain \ -e LDAP_BIND_DN=cn=admin,dc=localhost,dc=localdomain \
-e LDAP_BIND_PW=admin \ -e LDAP_BIND_PW=admin \

View file

@ -53,16 +53,16 @@ Minimum:
#### Get the tools #### Get the tools
Download the docker-compose.yml, the .env and the setup.sh files: Download the docker-compose.yml, the .env and the setup.sh files:
curl -o setup.sh https://raw.githubusercontent.com/tomav/docker-mailserver/master/setup.sh; chmod a+x ./setup.sh curl -o setup.sh https://raw.githubusercontent.com/tomav/docker-mailserver/master/setup.sh; chmod a+x ./setup.sh
curl -o docker-compose.yml https://raw.githubusercontent.com/tomav/docker-mailserver/master/docker-compose.yml.dist curl -o docker-compose.yml https://raw.githubusercontent.com/tomav/docker-mailserver/master/docker-compose.yml.dist
curl -o .env https://raw.githubusercontent.com/tomav/docker-mailserver/master/.env.dist curl -o .env https://raw.githubusercontent.com/tomav/docker-mailserver/master/.env.dist
#### Create a docker-compose environment #### Create a docker-compose environment
- Edit the `.env` to your liking. Adapt this file with your FQDN. - Edit the `.env` to your liking. Adapt this file with your FQDN.
- Install [docker-compose](https://docs.docker.com/compose/) in the version `1.6` or higher. - Install [docker-compose](https://docs.docker.com/compose/) in the version `1.6` or higher.
#### Create your mail accounts #### Create your mail accounts
@ -232,6 +232,7 @@ If you enable Fail2Ban, don't forget to add the following lines to your `docker-
- NET_ADMIN - NET_ADMIN
Otherwise, `iptables` won't be able to ban IPs. Otherwise, `iptables` won't be able to ban IPs.
##### SMTP_ONLY ##### SMTP_ONLY
- **empty** => all daemons start - **empty** => all daemons start
@ -254,6 +255,11 @@ Please read [the SSL page in the wiki](https://github.com/tomav/docker-mailserve
- intermediate => Enables TLSv1, TLSv1.1 and TLSv1.2 and broad compatibility ciphers. - intermediate => Enables TLSv1, TLSv1.1 and TLSv1.2 and broad compatibility ciphers.
- old => NOT implemented. If you really need it, then customize the TLS ciphers overriding postfix and dovecot settings [ wiki](https://github.com/tomav/docker-mailserver/wiki/ - old => NOT implemented. If you really need it, then customize the TLS ciphers overriding postfix and dovecot settings [ wiki](https://github.com/tomav/docker-mailserver/wiki/
##### SPOOF_PROTECTION
Configures the handling of creating mails with forged sender addresses.
- **empty** => Mail address spoofing allowed. Any logged in user may create email messages with a forged sender address. See also [Wikipedia](https://en.wikipedia.org/wiki/Email_spoofing)(not recommended, but default for backwards compatability reasons)
- 1 => (recommended) Mail spoofing denied. Each user may only send with his own or his alias addresses. Addresses with [extension delimiters](http://www.postfix.org/postconf.5.html#recipient_delimiter) are not able to send messages.
##### PERMIT_DOCKER ##### PERMIT_DOCKER
Set different options for mynetworks option (can be overwrite in postfix-main.cf) Set different options for mynetworks option (can be overwrite in postfix-main.cf)

View file

@ -26,6 +26,8 @@ services:
- POSTSCREEN_ACTION=${POSTSCREEN_ACTION} - POSTSCREEN_ACTION=${POSTSCREEN_ACTION}
- SMTP_ONLY=${SMTP_ONLY} - SMTP_ONLY=${SMTP_ONLY}
- SSL_TYPE=${SSL_TYPE} - SSL_TYPE=${SSL_TYPE}
- TLS_LEVEL=${TLS_LEVEL}
- SPOOF_PROTECTION=${SPOOF_PROTECTION}
- PERMIT_DOCKER=${PERMIT_DOCKER} - PERMIT_DOCKER=${PERMIT_DOCKER}
- VIRUSMAILS_DELETE_DELAY=${VIRUSMAILS_DELETE_DELAY} - VIRUSMAILS_DELETE_DELAY=${VIRUSMAILS_DELETE_DELAY}
- ENABLE_POSTFIX_VIRTUAL_TRANSPORT=${ENABLE_POSTFIX_VIRTUAL_TRANSPORT} - ENABLE_POSTFIX_VIRTUAL_TRANSPORT=${ENABLE_POSTFIX_VIRTUAL_TRANSPORT}
@ -72,4 +74,4 @@ volumes:
driver: local driver: local
mailstate: mailstate:
driver: local driver: local

View file

@ -46,7 +46,7 @@ smtpd_helo_restrictions = permit_mynetworks, reject_invalid_helo_hostname, permi
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, check_policy_service unix:private/policyd-spf, reject_unauth_pipelining, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_recipient_domain, reject_rbl_client zen.spamhaus.org, reject_rbl_client bl.spamcop.net smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, check_policy_service unix:private/policyd-spf, reject_unauth_pipelining, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_recipient_domain, reject_rbl_client zen.spamhaus.org, reject_rbl_client bl.spamcop.net
smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_unauth_pipelining smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_unauth_pipelining
smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unknown_sender_domain, reject_sender_login_mismatch smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unknown_sender_domain
disable_vrfy_command = yes disable_vrfy_command = yes
# Postscreen settings to drop zombies/open relays/spam early # Postscreen settings to drop zombies/open relays/spam early

View file

@ -0,0 +1 @@
/^(.*)$/ ${1}

View file

@ -25,6 +25,7 @@ DEFAULT_VARS["DMS_DEBUG"]="${DMS_DEBUG:="0"}"
DEFAULT_VARS["OVERRIDE_HOSTNAME"]="${OVERRIDE_HOSTNAME}" DEFAULT_VARS["OVERRIDE_HOSTNAME"]="${OVERRIDE_HOSTNAME}"
DEFAULT_VARS["POSTMASTER_ADDRESS"]="${POSTMASTER_ADDRESS:="postmaster@domain.com"}" DEFAULT_VARS["POSTMASTER_ADDRESS"]="${POSTMASTER_ADDRESS:="postmaster@domain.com"}"
DEFAULT_VARS["POSTSCREEN_ACTION"]="${POSTSCREEN_ACTION:="enforce"}" DEFAULT_VARS["POSTSCREEN_ACTION"]="${POSTSCREEN_ACTION:="enforce"}"
DEFAULT_VARS["SPOOF_PROTECTION"]="${SPOOF_PROTECTION:="0"}"
DEFAULT_VARS["TLS_LEVEL"]="${TLS_LEVEL:="modern"}" DEFAULT_VARS["TLS_LEVEL"]="${TLS_LEVEL:="modern"}"
########################################################################## ##########################################################################
# << DEFAULT VARS # << DEFAULT VARS
@ -118,6 +119,11 @@ function register_functions() {
_register_setup_function "_setup_postfix_vhost" _register_setup_function "_setup_postfix_vhost"
_register_setup_function "_setup_postfix_dhparam" _register_setup_function "_setup_postfix_dhparam"
_register_setup_function "_setup_postfix_postscreen" _register_setup_function "_setup_postfix_postscreen"
if [ "$SPOOF_PROTECTION" = 1 ]; then
_register_setup_function "_setup_spoof_protection"
fi
_register_setup_function "_setup_postfix_access_control" _register_setup_function "_setup_postfix_access_control"
if [ ! -z "$AWS_SES_HOST" -a ! -z "$AWS_SES_USERPASS" ]; then if [ ! -z "$AWS_SES_HOST" -a ! -z "$AWS_SES_USERPASS" ]; then
@ -128,7 +134,7 @@ function register_functions() {
_register_setup_function "_setup_postfix_virtual_transport" _register_setup_function "_setup_postfix_virtual_transport"
fi fi
_register_setup_function "_setup_environment" _register_setup_function "_setup_environment"
################### << setup funcs ################### << setup funcs
@ -544,7 +550,7 @@ function _setup_ldap() {
done done
notify 'inf' 'Starting to override configs' notify 'inf' 'Starting to override configs'
for f in /etc/postfix/ldap-users.cf /etc/postfix/ldap-groups.cf /etc/postfix/ldap-aliases.cf /etc/postfix/ldap-domains.cf for f in /etc/postfix/ldap-users.cf /etc/postfix/ldap-groups.cf /etc/postfix/ldap-aliases.cf /etc/postfix/ldap-domains.cf /etc/postfix/maps/sender_login_maps.ldap
do do
[[ $f =~ ldap-user ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_USER}" [[ $f =~ ldap-user ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_USER}"
[[ $f =~ ldap-group ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_GROUP}" [[ $f =~ ldap-group ]] && export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_GROUP}"
@ -615,6 +621,14 @@ function _setup_postfix_postscreen() {
-e "s/postscreen_bare_newline_action = enforce/postscreen_bare_newline_action = $POSTSCREEN_ACTION/" /etc/postfix/main.cf -e "s/postscreen_bare_newline_action = enforce/postscreen_bare_newline_action = $POSTSCREEN_ACTION/" /etc/postfix/main.cf
} }
function _setup_spoof_protection () {
notify 'inf' "Configuring Spoof Protection"
sed -i 's|smtpd_sender_restrictions =|smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch,|' /etc/postfix/main.cf
[ "$ENABLE_LDAP" = 1 ] \
&& postconf -e "smtpd_sender_login_maps=ldap:/etc/postfix/ldap-users.cf ldap:/etc/postfix/ldap-aliases.cf ldap:/etc/postfix/ldap-groups.cf" \
|| postconf -e "smtpd_sender_login_maps=texthash:/etc/postfix/virtual, texthash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre"
}
function _setup_postfix_access_control() { function _setup_postfix_access_control() {
notify 'inf' "Configuring user access" notify 'inf' "Configuring user access"
[ -f /tmp/docker-mailserver/postfix-send-access.cf ] && sed -i 's|smtpd_sender_restrictions =|smtpd_sender_restrictions = check_sender_access texthash:/tmp/docker-mailserver/postfix-send-access.cf,|' /etc/postfix/main.cf [ -f /tmp/docker-mailserver/postfix-send-access.cf ] && sed -i 's|smtpd_sender_restrictions =|smtpd_sender_restrictions = check_sender_access texthash:/tmp/docker-mailserver/postfix-send-access.cf,|' /etc/postfix/main.cf

View file

@ -0,0 +1,14 @@
EHLO mail
AUTH LOGIN dXNlcjFAbG9jYWxob3N0LmxvY2FsZG9tYWlu
bXlwYXNzd29yZA==
MAIL FROM: alias1@localhost.localdomain
RCPT TO: user1@localhost.localdomain
DATA
From: user1_alias <alias1@localhost.localdomain>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message
This is a test mail.
.
QUIT

View file

@ -0,0 +1,14 @@
EHLO mail
AUTH LOGIN YWRkZWRAbG9jYWxob3N0LmxvY2FsZG9tYWlu
bXlwYXNzd29yZA==
MAIL FROM: user2@localhost.localdomain
RCPT TO: user1@localhost.localdomain
DATA
From: Not_My_Business <user2@localhost.localdomain>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message
This is a test mail.
.
QUIT

View file

@ -0,0 +1,15 @@
EHLO mail
AUTH LOGIN
c29tZS51c2VyQGxvY2FsaG9zdC5sb2NhbGRvbWFpbg==
c2VjcmV0
MAIL FROM: postmaster@localhost.localdomain
RCPT TO: some.user@localhost.localdomain
DATA
From: alias_address <postmaster@localhost.localdomain>
To: Existing Local User <some.user@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message
This is a test mail.
.
QUIT

View file

@ -0,0 +1,15 @@
EHLO mail
AUTH LOGIN
c29tZS51c2VyQGxvY2FsaG9zdC5sb2NhbGRvbWFpbg==
c2VjcmV0
MAIL FROM: ldap@localhost.localdomain
RCPT TO: user1@localhost.localdomain
DATA
From: forged_address <ldap@localhost.localdomain>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message
This is a test mail.
.
QUIT

View file

@ -367,8 +367,6 @@ load 'test_helper/bats-assert/load'
[ "$status" -ge 0 ] [ "$status" -ge 0 ]
} }
# #
# accounts # accounts
# #
@ -1089,7 +1087,6 @@ load 'test_helper/bats-assert/load'
assert_success assert_success
} }
@test "checking accounts: listmailuser" { @test "checking accounts: listmailuser" {
run docker exec mail /bin/sh -c "listmailuser | head -n 1" run docker exec mail /bin/sh -c "listmailuser | head -n 1"
assert_success assert_success
@ -1397,11 +1394,29 @@ load 'test_helper/bats-assert/load'
@test "checking dovecot: postmaster address" { @test "checking dovecot: postmaster address" {
run docker exec mail /bin/sh -c "grep 'postmaster_address = postmaster@domain.com' /etc/dovecot/conf.d/15-lda.conf" run docker exec mail /bin/sh -c "grep 'postmaster_address = postmaster@domain.com' /etc/dovecot/conf.d/15-lda.conf"
assert_success assert_success
run docker exec mail_with_ldap /bin/sh -c "grep 'postmaster_address = postmaster@localhost.localdomain' /etc/dovecot/conf.d/15-lda.conf" run docker exec mail_with_ldap /bin/sh -c "grep 'postmaster_address = postmaster@localhost.localdomain' /etc/dovecot/conf.d/15-lda.conf"
assert_success assert_success
} }
@test "checking spoofing: rejects sender forging" {
# checking rejection of spoofed sender
run docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/added-smtp-auth-spoofed.txt | grep 'Sender address rejected: not owned by user'"
assert_success
# checking 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
}
@test "checking spoofing: accepts sending as alias" {
run docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/added-smtp-auth-spoofed-alias.txt | grep 'End data with'"
assert_success
# checking ldap alias
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
}
# saslauthd # saslauthd
@test "checking saslauthd: sasl ldap authentication works" { @test "checking saslauthd: sasl ldap authentication works" {
run docker exec mail_with_ldap bash -c "testsaslauthd -u some.user -p secret" run docker exec mail_with_ldap bash -c "testsaslauthd -u some.user -p secret"