Skip to content

Commit

Permalink
feat: Add MTA-STS support for outbound mail (#3592)
Browse files Browse the repository at this point in the history
* feat: add support for MTA-STS for outgoing mails

* Hook-up mta-sts-daemon into basic process handling test

* fix: Call python script directly

The python3 shebang will run it, which will now meet the expectations of the process testing via pgrep. fail2ban has the same approach.

---------

Co-authored-by: Brennan Kinney <[email protected]>
  • Loading branch information
jsonn and polarathene authored Jan 13, 2024
1 parent 71e1102 commit e3331b0
Show file tree
Hide file tree
Showing 14 changed files with 101 additions and 4 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ All notable changes to this project will be documented in this file. The format
### Features

- **Authentication with OIDC / OAuth 2.0** 🎉
- DMS now supports authentication via OAuth2 (_via `XOAUTH2` or `OAUTHBEARER` SASL mechanisms_) from capable services (_like Roundcube_).
- **Authentication with OIDC / OAuth 2.0** 🎉
- DMS now supports authentication via OAuth2 (_via `XOAUTH2` or `OAUTHBEARER` SASL mechanisms_) from capable services (_like Roundcube_).
- This does not replace the need for an `ACCOUNT_PROVISIONER` (`FILE` / `LDAP`), which is required for an account to receive or send mail.
- Successful authentication (_via Dovecot PassDB_) still requires an existing account (_lookup via Dovecot UserDB_).
- **MTA-STS** (_Optional support for mandatory outgoing TLS encryption_)
- If enabled and the outbound recipient has an MTA-STS policy set, TLS is mandatory for delivering to that recipient.
- Enable via the ENV `ENABLE_MTA_STS=1`
- Supported by major email service providers like Gmail, Yahoo and Outlook.

### Updates

Expand Down
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,15 @@ COPY target/opendmarc/opendmarc.conf /etc/opendmarc.conf
COPY target/opendmarc/default-opendmarc /etc/default/opendmarc
COPY target/opendmarc/ignore.hosts /etc/opendmarc/ignore.hosts

# --------------------------------------------------
# --- postfix-mta-sts-daemon -----------------------
# --------------------------------------------------
COPY target/mta-sts-daemon/mta-sts-daemon.yml /etc/mta-sts-daemon.yml
RUN <<EOF
mkdir /var/run/mta-sts
chown -R _mta-sts:root /var/run/mta-sts
EOF

# --------------------------------------------------
# --- Fetchmail, Getmail, Postfix & Let'sEncrypt ---
# --------------------------------------------------
Expand Down
30 changes: 30 additions & 0 deletions docs/content/config/best-practices/mta-sts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: 'Best practices | MTA-STS'
hide:
- toc # Hide Table of Contents for this page
---

MTA-STS is an optional mechanism for a domain to signal support for STARTTLS.

- It can be used to prevent man-in-the-middle-attacks from hiding STARTTLS support that would force DMS to send outbound mail through an insecure connection.
- MTA-STS is an alternative to DANE without the need of DNSSEC.
- MTA-STS is supported by some of the biggest mail providers like Google Mail and Outlook.

## Supporting MTA-STS for outbound mail

Enable this feature via the ENV setting [`ENABLE_MTA_STS=1`](../environment.md#enable_mta_sts).

!!! warning "If you have configured DANE"

Enabling MTA-STS will by default override DANE if both are configured for a domain.

This can be partially addressed by configuring a dane-only policy resolver before the MTA-STS entry in `smtp_tls_policy_maps`. See the [`postfix-mta-sts-resolver` documentation][postfix-mta-sts-resolver::dane] for further details.

[postfix-mta-sts-resolver::dane]: https://github.com/Snawoot/postfix-mta-sts-resolver#warning-mta-sts-policy-overrides-dane-tls-authentication

## Supporting MTA-STS for inbound mail

While this feature in DMS supports ensuring STARTTLS is used when mail is sent to another mail server, you may setup similar for mail servers sending mail to DMS.

This requires configuring your DNS and hosting the MTA-STS policy file via a webserver. A good introduction can be found on [dmarcian.com](https://dmarcian.com/mta-sts/).

9 changes: 9 additions & 0 deletions docs/content/config/environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ This enables DNS block lists in _Postscreen_. If you want to know which lists we
- **0** => DNS block lists are disabled
- 1 => DNS block lists are enabled

##### ENABLE_MTA_STS

Enables MTA-STS support for outbound mail.

- **0** => Disabled
- 1 => Enabled

See [MTA-STS](best-practices/mta-sts.md) for further explanation.

##### ENABLE_OPENDKIM

Enables the OpenDKIM service.
Expand Down
3 changes: 2 additions & 1 deletion docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ nav:
- 'Environment Variables': config/environment.md
- 'User Management': config/user-management.md
- 'Best Practices':
- 'DKIM, DMARC & SPF': config/best-practices/dkim_dmarc_spf.md
- 'Auto-discovery': config/best-practices/autodiscover.md
- 'DKIM, DMARC & SPF': config/best-practices/dkim_dmarc_spf.md
- 'MTA-STS': config/best-practices/mta-sts.md
- 'Security':
- 'Understanding the Ports': config/security/understanding-the-ports.md
- 'SSL/TLS': config/security/ssl.md
Expand Down
6 changes: 6 additions & 0 deletions mailserver.env
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,12 @@ POSTFIX_REJECT_UNKNOWN_CLIENT_HOSTNAME=0
# Note: More details at http://www.postfix.org/postconf.5.html#inet_protocols
POSTFIX_INET_PROTOCOLS=all

# Enables MTA-STS support for outbound mail.
# More details: https://docker-mailserver.github.io/docker-mailserver/latest/config/advanced/mail-mta-sts/
# - **0** ==> MTA-STS disabled
# - 1 => MTA-STS enabled
ENABLE_MTA_STS=0

# Choose TCP/IP protocols for dovecot to use
# **all** => Listen on all interfaces
# ipv4 => Listen only on IPv4 interfaces. Most likely you want this behind Docker.
Expand Down
7 changes: 7 additions & 0 deletions target/mta-sts-daemon/mta-sts-daemon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Docs: https://github.com/Snawoot/postfix-mta-sts-resolver/blob/master/man/mta-sts-daemon.yml.5.adoc
path: /var/run/mta-sts/daemon.sock
mode: 0666
cache:
type: sqlite
options:
filename: "/var/lib/mta-sts/cache.db"
2 changes: 1 addition & 1 deletion target/scripts/build/packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function _install_packages() {
)

POSTFIX_PACKAGES=(
pflogsumm postgrey postfix-ldap
pflogsumm postgrey postfix-ldap postfix-mta-sts-resolver
postfix-pcre postfix-policyd-spf-python postsrsd
)

Expand Down
5 changes: 5 additions & 0 deletions target/scripts/start-mailserver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ function _register_functions() {
_register_setup_function '_setup_apply_fixes_after_configuration'
_register_setup_function '_environment_variables_export'

if [[ ${ENABLE_MTA_STS} -eq 1 ]]; then
_register_setup_function '_setup_mta_sts'
_register_start_daemon '_start_daemon_mta_sts_daemon'
fi

# ? >> Daemons

_register_start_daemon '_start_daemon_cron'
Expand Down
1 change: 1 addition & 0 deletions target/scripts/startup/daemons-stack.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function _start_daemon_opendkim { _default_start_daemon 'opendkim' ;
function _start_daemon_opendmarc { _default_start_daemon 'opendmarc' ; }
function _start_daemon_postgrey { _default_start_daemon 'postgrey' ; }
function _start_daemon_postsrsd { _default_start_daemon 'postsrsd' ; }
function _start_daemon_mta_sts_daemon { _default_start_daemon 'mta-sts-daemon' ; }
function _start_daemon_rspamd { _default_start_daemon 'rspamd' ; }
function _start_daemon_rspamd_redis { _default_start_daemon 'rspamd-redis' ; }
function _start_daemon_rsyslog { _default_start_daemon 'rsyslog' ; }
Expand Down
2 changes: 2 additions & 0 deletions target/scripts/startup/setup.d/mail_state.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function _setup_save_states() {
[[ ${ENABLE_FAIL2BAN} -eq 1 ]] && SERVICEDIRS+=('lib/fail2ban')
[[ ${ENABLE_FETCHMAIL} -eq 1 ]] && SERVICEDIRS+=('lib/fetchmail')
[[ ${ENABLE_GETMAIL} -eq 1 ]] && SERVICEDIRS+=('lib/getmail')
[[ ${ENABLE_MTA_STS} -eq 1 ]] && SERVICEDIRS+=('lib/mta-sts')
[[ ${ENABLE_POSTGREY} -eq 1 ]] && SERVICEDIRS+=('lib/postgrey')
[[ ${ENABLE_RSPAMD} -eq 1 ]] && SERVICEDIRS+=('lib/rspamd')
[[ ${ENABLE_RSPAMD_REDIS} -eq 1 ]] && SERVICEDIRS+=('lib/redis')
Expand Down Expand Up @@ -84,6 +85,7 @@ function _setup_save_states() {
[[ ${ENABLE_AMAVIS} -eq 1 ]] && chown -R amavis:amavis "${STATEDIR}/lib-amavis"
[[ ${ENABLE_CLAMAV} -eq 1 ]] && chown -R clamav:clamav "${STATEDIR}/lib-clamav"
[[ ${ENABLE_FETCHMAIL} -eq 1 ]] && chown -R fetchmail:nogroup "${STATEDIR}/lib-fetchmail"
[[ ${ENABLE_MTA_STS} -eq 1 ]] && chown -R _mta-sts:_mta-sts "${STATEDIR}/lib-mta-sts"
[[ ${ENABLE_POSTGREY} -eq 1 ]] && chown -R postgrey:postgrey "${STATEDIR}/lib-postgrey"
[[ ${ENABLE_RSPAMD} -eq 1 ]] && chown -R _rspamd:_rspamd "${STATEDIR}/lib-rspamd"
[[ ${ENABLE_RSPAMD_REDIS} -eq 1 ]] && chown -R redis:redis "${STATEDIR}/lib-redis"
Expand Down
7 changes: 7 additions & 0 deletions target/scripts/startup/setup.d/mta-sts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash


function _setup_mta_sts() {
_log 'trace' 'Adding MTA-STS lookup to the Postfix TLS policy map'
_add_to_or_update_postfix_main smtp_tls_policy_maps 'socketmap:unix:/var/run/mta-sts/daemon.sock:postfix'
}
12 changes: 12 additions & 0 deletions target/supervisor/conf.d/supervisor-app.conf
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,15 @@ autostart=false
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
command=/bin/bash -l -c /usr/local/bin/update-check.sh

# Docs: https://github.com/Snawoot/postfix-mta-sts-resolver/blob/master/man/mta-sts-daemon.1.adoc
[program:mta-sts-daemon]
startsecs=0
stopwaitsecs=55
autostart=false
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
command=/usr/bin/mta-sts-daemon --config /etc/mta-sts-daemon.yml
user=_mta-sts
environment=HOME=/var/lib/mta-sts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ function teardown() { _default_teardown ; }
# dovecot (/usr/sbin/dovecot)
# fetchmail (/usr/bin/fetchmail)
# fail2ban-server (/usr/bin/python3 /usr/bin/fail2ban-server) - Started by fail2ban-wrapper.sh
# mta-sts-daemon (/usr/bin/bin/python3 /usr/bin/mta-sts-daemon)
# postgrey (postgrey) - NOTE: This process lacks path information to match with `--full` in pgrep / pkill
# postsrsd (/usr/sbin/postsrsd) - NOTE: Also matches the wrapper: `/bin/bash /usr/local/bin/postsrsd-wrapper.sh`
# saslauthd (/usr/sbin/saslauthd) - x5 of the same process are found running (1 is a parent of 4)
Expand All @@ -44,6 +45,7 @@ ENV_PROCESS_LIST=(
dovecot
fail2ban-server
fetchmail
mta-sts-daemon
opendkim
opendmarc
postgrey
Expand All @@ -58,6 +60,7 @@ ENV_PROCESS_LIST=(
--env ENABLE_CLAMAV=0
--env ENABLE_FAIL2BAN=0
--env ENABLE_FETCHMAIL=0
--env ENABLE_MTA_STS=0
--env ENABLE_OPENDKIM=0
--env ENABLE_OPENDMARC=0
--env ENABLE_POSTGREY=0
Expand Down Expand Up @@ -93,6 +96,7 @@ ENV_PROCESS_LIST=(
--env ENABLE_AMAVIS=1
--env ENABLE_FAIL2BAN=1
--env ENABLE_FETCHMAIL=1
--env ENABLE_MTA_STS=1
--env ENABLE_OPENDKIM=1
--env ENABLE_OPENDMARC=1
--env FETCHMAIL_PARALLEL=1
Expand Down

0 comments on commit e3331b0

Please sign in to comment.