diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index cfe4586e..cd5294ed 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -29,7 +29,7 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} persist-credentials: false - name: download filtermail - run: curl -L https://github.com/chatmail/filtermail/releases/download/v0.6.1/filtermail-x86_64 -o /usr/local/bin/filtermail && chmod +x /usr/local/bin/filtermail + run: curl -L https://github.com/chatmail/filtermail/releases/download/v0.6.2/filtermail-x86_64 -o /usr/local/bin/filtermail && chmod +x /usr/local/bin/filtermail - name: run chatmaild tests working-directory: chatmaild run: pipx run tox diff --git a/chatmaild/src/chatmaild/config.py b/chatmaild/src/chatmaild/config.py index 6a9e6bdb..6f9acd04 100644 --- a/chatmaild/src/chatmaild/config.py +++ b/chatmaild/src/chatmaild/config.py @@ -40,6 +40,9 @@ class Config: self.filtermail_http_port_incoming = int( params.get("filtermail_http_port_incoming", "10082") ) + self.filtermail_lmtp_port_transport = int( + params.get("filtermail_lmtp_port_transport", "10083") + ) self.postfix_reinject_port = int(params.get("postfix_reinject_port", "10025")) self.postfix_reinject_port_incoming = int( params.get("postfix_reinject_port_incoming", "10026") diff --git a/cmdeploy/src/cmdeploy/filtermail/deployer.py b/cmdeploy/src/cmdeploy/filtermail/deployer.py index fed98ccf..e8b5e682 100644 --- a/cmdeploy/src/cmdeploy/filtermail/deployer.py +++ b/cmdeploy/src/cmdeploy/filtermail/deployer.py @@ -7,7 +7,7 @@ from cmdeploy.basedeploy import Deployer, get_resource class FiltermailDeployer(Deployer): - services = ["filtermail", "filtermail-incoming"] + services = ["filtermail", "filtermail-incoming", "filtermail-transport"] bin_path = "/usr/local/bin/filtermail" config_path = "/usr/local/lib/chatmaild/chatmail.ini" @@ -26,10 +26,10 @@ class FiltermailDeployer(Deployer): return arch = host.get_fact(facts.server.Arch) - url = f"https://github.com/chatmail/filtermail/releases/download/v0.6.1/filtermail-{arch}" + url = f"https://github.com/chatmail/filtermail/releases/download/v0.6.2/filtermail-{arch}" sha256sum = { - "x86_64": "48b3fb80c092d00b9b0a0ef77a8673496da3b9aed5ec1851e1df936d5589d62f", - "aarch64": "c65bd5f45df187d3d65d6965a285583a3be0f44a6916ff12909ff9a8d702c22e", + "x86_64": "0c68456d0999da727914e937cfce97fce6d3612f997438f536f4224c839f0ace", + "aarch64": "5ac6f0be433b1c1ee907e1c1c47304473737a40fb5456d082a60f9dbb1688c36", }[arch] self.need_restart |= files.download( name="Download filtermail", diff --git a/cmdeploy/src/cmdeploy/filtermail/filtermail-transport.service.j2 b/cmdeploy/src/cmdeploy/filtermail/filtermail-transport.service.j2 new file mode 100644 index 00000000..ccb4f98f --- /dev/null +++ b/cmdeploy/src/cmdeploy/filtermail/filtermail-transport.service.j2 @@ -0,0 +1,11 @@ +[Unit] +Description=Chatmail transport service + +[Service] +ExecStart={{ bin_path }} {{ config_path }} transport +Restart=always +RestartSec=30 +User=vmail + +[Install] +WantedBy=multi-user.target diff --git a/cmdeploy/src/cmdeploy/postfix/main.cf.j2 b/cmdeploy/src/cmdeploy/postfix/main.cf.j2 index ffe64375..9924201a 100644 --- a/cmdeploy/src/cmdeploy/postfix/main.cf.j2 +++ b/cmdeploy/src/cmdeploy/postfix/main.cf.j2 @@ -79,22 +79,6 @@ inet_protocols = ipv4 inet_protocols = all {% endif %} -# Postfix does not try IPv4 and IPv6 connections -# concurrently as of version 3.7.11. -# -# When relay has both A (IPv4) and AAAA (IPv6) records, -# but broken IPv6 connectivity, -# every second message is delayed by the connection timeout -# -# which defaults to 30 seconds. Reducing timeouts is not a solution -# as this will result in a failure to connect to slow servers. -# -# As a workaround we always prefer IPv4 when it is available. -# -# The setting is documented at -# -smtp_address_preference=ipv4 - virtual_transport = lmtp:unix:private/dovecot-lmtp virtual_mailbox_domains = {{ config.mail_domain }} lmtp_header_checks = regexp:/etc/postfix/lmtp_header_cleanup @@ -109,3 +93,10 @@ smtpd_sender_login_maps = regexp:/etc/postfix/login_map # Do not lookup SMTP client hostnames to reduce delays # and avoid unnecessary DNS requests. smtpd_peername_lookup = no + +# Use filtermail-transport to relay messages. +# We can't force postfix to split messages per destination, +# when specifying a custom next-hop, +# so instead this is handled in filtermail. +# We use LMTP instead SMTP so we can communicate per-recipient errors back to postfix. +default_transport = lmtp-filtermail:inet:[127.0.0.1]:{{ config.filtermail_lmtp_port_transport }} diff --git a/cmdeploy/src/cmdeploy/postfix/master.cf.j2 b/cmdeploy/src/cmdeploy/postfix/master.cf.j2 index 4914767c..34081b28 100644 --- a/cmdeploy/src/cmdeploy/postfix/master.cf.j2 +++ b/cmdeploy/src/cmdeploy/postfix/master.cf.j2 @@ -100,3 +100,8 @@ filter unix - n n - - lmtp # cannot send unprotected Subject. authclean unix n - - - 0 cleanup -o header_checks=regexp:/etc/postfix/submission_header_cleanup + +lmtp-filtermail unix - - y - - lmtp + -o syslog_name=postfix/lmtp-filtermail + -o lmtp_header_checks= + -o lmtp_tls_security_level=none diff --git a/doc/source/overview.rst b/doc/source/overview.rst index 8c1608c2..9b040b7f 100644 --- a/doc/source/overview.rst +++ b/doc/source/overview.rst @@ -153,6 +153,7 @@ Chatmail relay dependency diagram autoconfig.xml --- dovecot; postfix --- |10080|filtermail-outgoing; postfix --- |10081|filtermail-incoming; + postfix --- |10083|filtermail-transport; filtermail-outgoing --- |10025 reinject|postfix; filtermail-incoming --- |10026 reinject|postfix; dovecot --- |doveauth.socket|doveauth; @@ -295,9 +296,7 @@ ensured by ``filtermail`` proxy. TLS requirements ~~~~~~~~~~~~~~~~ -Postfix is configured to require valid TLS by setting -`smtp_tls_security_level `_ -to ``verify``. +Filtermail (used for delivery) requires a valid TLS. You can test it by resolving ``MX`` records of your relay domain and then connecting to MX relays (e.g ``mx.example.org``) with