This commit is contained in:
Noah Overcash 2025-03-31 21:08:35 -04:00 committed by GitHub
commit a7c8a837ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 148 additions and 41 deletions

View File

@ -184,10 +184,12 @@ The most noteworthy change of this release is the update of the container's base
- **Documentation:** - **Documentation:**
- A guide for configuring a public server to relay inbound and outbound mail from DMS on a private server ([#3973](https://github.com/docker-mailserver/docker-mailserver/pull/3973)) - A guide for configuring a public server to relay inbound and outbound mail from DMS on a private server ([#3973](https://github.com/docker-mailserver/docker-mailserver/pull/3973))
- Added information on how to configure send-only aliases ([#4044](https://github.com/docker-mailserver/docker-mailserver/pull/4044))
- **Environment Variables:** - **Environment Variables:**
- `LOGROTATE_COUNT` defines the number of files kept by logrotate ([#3907](https://github.com/docker-mailserver/docker-mailserver/pull/3907)) - `LOGROTATE_COUNT` defines the number of files kept by logrotate ([#3907](https://github.com/docker-mailserver/docker-mailserver/pull/3907))
- The fail2ban log file is now also taken into account by `LOGROTATE_COUNT` and `LOGROTATE_INTERVAL` ([#3915](https://github.com/docker-mailserver/docker-mailserver/pull/3915), [#3919](https://github.com/docker-mailserver/docker-mailserver/pull/3919)) - The fail2ban log file is now also taken into account by `LOGROTATE_COUNT` and `LOGROTATE_INTERVAL` ([#3915](https://github.com/docker-mailserver/docker-mailserver/pull/3915), [#3919](https://github.com/docker-mailserver/docker-mailserver/pull/3919))
- **Postfix:**
- `smtpd_sender_login_maps` allows configuration with sender-only aliases out of the box using `postfix-regexp-send-only.cf` ([#4044](https://github.com/docker-mailserver/docker-mailserver/pull/4044))
- **Internal:** - **Internal:**
- Regular container restarts are now better supported. Setup scripts that ran previously will now be skipped ([#3929](https://github.com/docker-mailserver/docker-mailserver/pull/3929)) - Regular container restarts are now better supported. Setup scripts that ran previously will now be skipped ([#3929](https://github.com/docker-mailserver/docker-mailserver/pull/3929))

View File

@ -80,6 +80,7 @@ This is a list of all configuration files and directories which are optional, au
- **postfix-sasl-password.cf:** listing of relayed domains with their respective `<username>:<password>`. Modify via `setup.sh relay add-auth <domain> <username> [<password>]`. (Docs: [Relay-Hosts Auth][docs::relay-hosts::advanced]) - **postfix-sasl-password.cf:** listing of relayed domains with their respective `<username>:<password>`. Modify via `setup.sh relay add-auth <domain> <username> [<password>]`. (Docs: [Relay-Hosts Auth][docs::relay-hosts::advanced])
- **postfix-relaymap.cf:** domain-specific relays and exclusions. Modify via `setup.sh relay add-domain` and `setup.sh relay exclude-domain`. (Docs: [Relay-Hosts Senders][docs::relay-hosts::advanced]) - **postfix-relaymap.cf:** domain-specific relays and exclusions. Modify via `setup.sh relay add-domain` and `setup.sh relay exclude-domain`. (Docs: [Relay-Hosts Senders][docs::relay-hosts::advanced])
- **postfix-regexp.cf:** Regular expression alias file. (Docs: [Aliases][docs-aliases-regex]) - **postfix-regexp.cf:** Regular expression alias file. (Docs: [Aliases][docs-aliases-regex])
- **postfix-regexp-send-only.cf:** Regular expression alias file for sending only. (Docs: [Send-Only Aliases][docs-aliases-send-only])
- **ldap-users.cf:** Configuration for the virtual user mapping `virtual_mailbox_maps`. See the [`setup-stack.sh`][github-commit-setup-stack.sh-L411] script. - **ldap-users.cf:** Configuration for the virtual user mapping `virtual_mailbox_maps`. See the [`setup-stack.sh`][github-commit-setup-stack.sh-L411] script.
- **ldap-groups.cf:** Configuration for the virtual alias mapping `virtual_alias_maps`. See the [`setup-stack.sh`][github-commit-setup-stack.sh-L411] script. - **ldap-groups.cf:** Configuration for the virtual alias mapping `virtual_alias_maps`. See the [`setup-stack.sh`][github-commit-setup-stack.sh-L411] script.
- **ldap-aliases.cf:** Configuration for the virtual alias mapping `virtual_alias_maps`. See the [`setup-stack.sh`][github-commit-setup-stack.sh-L411] script. - **ldap-aliases.cf:** Configuration for the virtual alias mapping `virtual_alias_maps`. See the [`setup-stack.sh`][github-commit-setup-stack.sh-L411] script.
@ -97,8 +98,9 @@ This is a list of all configuration files and directories which are optional, au
[docker-docs::volumes]: https://docs.docker.com/storage/volumes/ [docker-docs::volumes]: https://docs.docker.com/storage/volumes/
[docker-docs::volumes::bind-mount]: https://docs.docker.com/storage/bind-mounts/ [docker-docs::volumes::bind-mount]: https://docs.docker.com/storage/bind-mounts/
[docs-accounts-quota]: ../../config/account-management/provisioner/file.md#quotas [docs-accounts-quota]: ../../config/user-management.md#quotas
[docs-aliases-regex]: ../../config/account-management/provisioner/file.md#configuring-regex-aliases [docs-aliases-regex]: ../../config/user-management.md#configuring-regexp-aliases
[docs-aliases-send-only]: ../../config/user-management.md#send-only-aliases
[docs-dkim]: ../../config/best-practices/dkim_dmarc_spf.md#dkim [docs-dkim]: ../../config/best-practices/dkim_dmarc_spf.md#dkim
[docs-fail2ban]: ../../config/security/fail2ban.md [docs-fail2ban]: ../../config/security/fail2ban.md
[docs-faq-spamrules]: ../../faq.md#how-can-i-manage-my-custom-spamassassin-rules [docs-faq-spamrules]: ../../faq.md#how-can-i-manage-my-custom-spamassassin-rules

View File

@ -204,6 +204,8 @@ Configures the handling of creating mails with forged sender addresses.
- **0** => (not recommended) Mail address spoofing allowed. Any logged in user may create email messages with a [forged sender address](https://en.wikipedia.org/wiki/Email_spoofing). - **0** => (not recommended) Mail address spoofing allowed. Any logged in user may create email messages with a [forged sender address](https://en.wikipedia.org/wiki/Email_spoofing).
- 1 => Mail spoofing denied. Each user may only send with their own or their alias addresses. Addresses with [extension delimiters](http://www.postfix.org/postconf.5.html#recipient_delimiter) are not able to send messages. - 1 => Mail spoofing denied. Each user may only send with their own or their alias addresses. Addresses with [extension delimiters](http://www.postfix.org/postconf.5.html#recipient_delimiter) are not able to send messages.
To allow certain accounts to send as other addresses, set the `SPOOF_PROTECTION` to `1` and see [the Aliases page in the documentation][docs-aliases].
##### ENABLE_SRS ##### ENABLE_SRS
Enables the Sender Rewriting Scheme. SRS is needed if DMS acts as forwarder. See [postsrsd](https://github.com/roehling/postsrsd/blob/main/README.rst) for further explanation. Enables the Sender Rewriting Scheme. SRS is needed if DMS acts as forwarder. See [postsrsd](https://github.com/roehling/postsrsd/blob/main/README.rst) for further explanation.

View File

@ -138,6 +138,7 @@ function _postfix_dovecot_changes() {
# Regenerate system + virtual account aliases via `helpers/aliases.sh`: # Regenerate system + virtual account aliases via `helpers/aliases.sh`:
[[ ${CHANGED} =~ ${DMS_DIR}/postfix-virtual.cf ]] && _handle_postfix_virtual_config [[ ${CHANGED} =~ ${DMS_DIR}/postfix-virtual.cf ]] && _handle_postfix_virtual_config
[[ ${CHANGED} =~ ${DMS_DIR}/postfix-regexp.cf ]] && _handle_postfix_regexp_config [[ ${CHANGED} =~ ${DMS_DIR}/postfix-regexp.cf ]] && _handle_postfix_regexp_config
[[ ${CHANGED} =~ ${DMS_DIR}/postfix-regexp-send-only.cf ]] && _handle_postfix_regexp_send_only_config
[[ ${CHANGED} =~ ${DMS_DIR}/postfix-aliases.cf ]] && _handle_postfix_aliases_config [[ ${CHANGED} =~ ${DMS_DIR}/postfix-aliases.cf ]] && _handle_postfix_aliases_config
# Legacy workaround handled here, only seems necessary for _create_accounts: # Legacy workaround handled here, only seems necessary for _create_accounts:

View File

@ -30,6 +30,17 @@ function _handle_postfix_regexp_config() {
fi fi
} }
function _handle_postfix_regexp_send_only_config() {
: >/etc/postfix/regexp-send-only
if [[ -f /tmp/docker-mailserver/postfix-regexp-send-only.cf ]]; then
_log 'trace' "Adding regexp-send-only alias file postfix-regexp-send-only.cf"
cp -f /tmp/docker-mailserver/postfix-regexp-send-only.cf /etc/postfix/regexp-send-only
# we specifically do NOT append this to virtual_alias_maps
fi
}
function _handle_postfix_aliases_config() { function _handle_postfix_aliases_config() {
_log 'trace' 'Configuring root alias' _log 'trace' 'Configuring root alias'
@ -46,5 +57,6 @@ function _handle_postfix_aliases_config() {
function _create_aliases() { function _create_aliases() {
_handle_postfix_virtual_config _handle_postfix_virtual_config
_handle_postfix_regexp_config _handle_postfix_regexp_config
_handle_postfix_regexp_send_only_config
_handle_postfix_aliases_config _handle_postfix_aliases_config
} }

View File

@ -34,6 +34,7 @@ function _monitored_files_checksums() {
"${DMS_DIR}/postfix-accounts.cf" "${DMS_DIR}/postfix-accounts.cf"
"${DMS_DIR}/postfix-virtual.cf" "${DMS_DIR}/postfix-virtual.cf"
"${DMS_DIR}/postfix-regexp.cf" "${DMS_DIR}/postfix-regexp.cf"
"${DMS_DIR}/postfix-regexp-send-only.cf"
"${DMS_DIR}/postfix-aliases.cf" "${DMS_DIR}/postfix-aliases.cf"
"${DMS_DIR}/postfix-relaymap.cf" "${DMS_DIR}/postfix-relaymap.cf"
"${DMS_DIR}/postfix-sasl-password.cf" "${DMS_DIR}/postfix-sasl-password.cf"

View File

@ -14,7 +14,11 @@ function _setup_spoof_protection() {
# NOTE: This file is always created at startup, it potentially has content added. # NOTE: This file is always created at startup, it potentially has content added.
# TODO: From section: "SPOOF_PROTECTION=1 handling for smtpd_sender_login_maps" # TODO: From section: "SPOOF_PROTECTION=1 handling for smtpd_sender_login_maps"
# https://github.com/docker-mailserver/docker-mailserver/issues/2819#issue-1402114383 # https://github.com/docker-mailserver/docker-mailserver/issues/2819#issue-1402114383
if [[ -f /etc/postfix/regexp ]]; then if [[ -f /etc/postfix/regexp && -f /etc/postfix/regexp-send-only ]]; then
postconf 'smtpd_sender_login_maps = unionmap:{ texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre, pcre:/etc/postfix/regexp, pcre:/etc/postfix/regexp-send-only }'
elif [[ -f /etc/postfix/regexp-send-only ]]; then
postconf 'smtpd_sender_login_maps = unionmap:{ texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre, pcre:/etc/postfix/regexp-send-only }'
elif [[ -f /etc/postfix/regexp ]]; then
postconf 'smtpd_sender_login_maps = unionmap:{ texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre, pcre:/etc/postfix/regexp }' postconf 'smtpd_sender_login_maps = unionmap:{ texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre, pcre:/etc/postfix/regexp }'
else else
postconf 'smtpd_sender_login_maps = texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre' postconf 'smtpd_sender_login_maps = texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/maps/sender_login_maps.pcre'

View File

@ -0,0 +1 @@
/^user3@localhost.localdomain/ user1@localhost.localdomain

View File

@ -1,4 +1,4 @@
From: Not_My_Business <user2@localhost.localdomain> From: test123_alias <test123@localhost.localdomain>
To: Existing Local User <user1@localhost.localdomain> To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400 Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message Subject: Test Message

View File

@ -0,0 +1,5 @@
From: User 1 <user1@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.

View File

@ -0,0 +1,5 @@
From: User 3 <user3@localhost.localdomain>
To: Existing Local User <user3@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message
This is a test mail.

View File

@ -0,0 +1,105 @@
load "${REPOSITORY_ROOT}/test/helper/common"
load "${REPOSITORY_ROOT}/test/helper/setup"
BATS_TEST_NAME_PREFIX='[Postfix] (sender spoofing) '
CONTAINER_NAME='dms-test_postfix-spoofing'
function setup_file() {
_init_with_defaults
local CUSTOM_SETUP_ARGUMENTS=(
--env SPOOF_PROTECTION=1
--env LOG_LEVEL=trace
--env SSL_TYPE='snakeoil'
)
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
_wait_for_service postfix
_wait_for_smtp_port_in_container_to_respond
}
function teardown_file() { _default_teardown ; }
# These tests ensure spoofing protection works, and that exceptions are available for aliases.
# user1 has aliases configured for the following accounts:
# - test\d* via /etc/postfix/regexp
# - alias1@localhost via /etc/postfix/virtual
# - user3@localhost via /etc/postfix/regexp-send-only
@test "allows forging as send-only alias" {
# An authenticated account should be able to send mail from a send-only alias,
# Verifies `main.cf:smtpd_sender_login_maps` includes /etc/postfix/regexp-send-only
_send_email \
--port 587 -tls --auth PLAIN \
--auth-user user1@localhost.localdomain \
--auth-password mypassword \
--ehlo mail \
--from user3@localhost.localdomain \
--data 'auth/added-smtp-auth-spoofed-from-user3.txt'
assert_success
assert_output --partial 'End data with'
}
@test "allows forging as regular alias" {
# An authenticated account should be able to send mail from an alias,
# Verifies `main.cf:smtpd_sender_login_maps` includes /etc/postfix/virtual
_send_email \
--port 587 -tls --auth PLAIN \
--auth-user user1@localhost.localdomain \
--auth-password mypassword \
--ehlo mail \
--from alias1@localhost.localdomain \
--data 'auth/added-smtp-auth-spoofed-from-alias1.txt'
assert_success
assert_output --partial 'End data with'
}
@test "allows forging as regular (regex) alias" {
# An authenticated account should be able to send mail from an alias,
# Verifies `main.cf:smtpd_sender_login_maps` includes /etc/postfix/regexp
_send_email \
--port 587 -tls --auth PLAIN \
--auth-user user1@localhost.localdomain \
--auth-password mypassword \
--ehlo mail \
--from test123@localhost.localdomain \
--data 'auth/added-smtp-auth-spoofed-from-test123.txt'
assert_success
assert_output --partial 'End data with'
}
@test "rejects sender forging" {
# An authenticated user cannot use an envelope sender (MAIL FROM)
# address they do not own according to `main.cf:smtpd_sender_login_maps` lookup
_send_email --expect-rejection \
--port 587 -tls --auth PLAIN \
--auth-user user3@localhost.localdomain \
--auth-password mypassword \
--ehlo mail \
--from user1@localhost.localdomain \
--data 'auth/added-smtp-auth-spoofed-from-user1.txt'
assert_output --partial 'Sender address rejected: not owned by user'
}
@test "send-only alias does not affect incoming mail" {
# user1 is allowed to send as user3, however, mail to user3 should still be delivered to user3.
# Verifies that /etc/postfix/regexp-send-only does not affect incoming mail.
_send_email \
--port 587 -tls --auth PLAIN \
--auth-user user1@localhost.localdomain \
--auth-password mypassword \
--ehlo mail \
--from user1@localhost.localdomain \
--to user3@localhost.localdomain \
--data 'test-email.txt'
assert_success
assert_output --partial 'End data with'
_wait_for_empty_mail_queue_in_container
# would have an orig_to if it got forwarded
_service_log_should_contain_string 'mail' ': to=<user3@localhost.localdomain>'
assert_output --partial 'status=sent'
_should_output_number_of_lines 1
}

View File

@ -281,39 +281,6 @@ EOF
assert_success assert_success
} }
@test "spoofing: rejects sender forging" {
# rejection of spoofed sender
_wait_for_smtp_port_in_container_to_respond
# An authenticated user cannot use an envelope sender (MAIL FROM)
# address they do not own according to `main.cf:smtpd_sender_login_maps` lookup
_send_email --expect-rejection \
--port 465 -tlsc --auth PLAIN \
--auth-user added@localhost.localdomain \
--auth-password mypassword \
--ehlo mail \
--from user2@localhost.localdomain \
--data 'auth/added-smtp-auth-spoofed.txt'
assert_output --partial 'Sender address rejected: not owned by user'
}
@test "spoofing: accepts sending as alias" {
# An authenticated account should be able to send mail from an alias,
# Verifies `main.cf:smtpd_sender_login_maps` includes /etc/postfix/virtual
# The envelope sender address (MAIL FROM) is the lookup key
# to each table. Address is authorized when a result that maps to
# the DMS account is returned.
_send_email \
--port 465 -tlsc --auth PLAIN \
--auth-user user1@localhost.localdomain \
--auth-password mypassword \
--ehlo mail \
--from alias1@localhost.localdomain \
--data 'auth/added-smtp-auth-spoofed-alias.txt'
assert_success
assert_output --partial 'End data with'
}
# #
# Pflogsumm delivery check # Pflogsumm delivery check
# #