From 85915652b3a4e340281f81579286deee3401c291 Mon Sep 17 00:00:00 2001 From: link2xt Date: Wed, 22 Apr 2026 15:45:17 +0200 Subject: [PATCH] feat: do not bind SMTP client sockets to public addresses This change reverts 06560dd0710167d1e819f10b3e8fe1a6285e7a6c Main reason for using the same address for sending as the one used in DNS is to pass FCrDNS (forward-confirmed reverse DNS) checks: IP address used by SMTP client should resolve to the domain which in turn resolves to the same IP. chatmail relays don't do check reverse DNS for incoming connections, but other email servers may do and reject email if the check does not pass. Most chatmail relays only have one IP address per address family, so this configuration does not change anything. For chatmail relays that have multiple addresses and only publishing one IP to DNS, source address used for outgoing SMTP connections should be the public IP. This can be ensured by configuring the source address in the routing table, e.g. with the `src` argument to `ip route add/change/replace` command. Solving this by binding SMTP client address on the application level prevents chatmail relays from configuring alternative routes. Besides, some chatmail relays are NATed and NAT is responsible for translating the address to the public one, in which case using `smtp_bind_address_enforce` will result in unnecessarily deferring all mails. --- chatmaild/src/chatmaild/config.py | 3 --- cmdeploy/src/cmdeploy/cmdeploy.py | 3 --- cmdeploy/src/cmdeploy/postfix/main.cf.j2 | 9 --------- 3 files changed, 15 deletions(-) diff --git a/chatmaild/src/chatmaild/config.py b/chatmaild/src/chatmaild/config.py index 43339fb3..6a9e6bdb 100644 --- a/chatmaild/src/chatmaild/config.py +++ b/chatmaild/src/chatmaild/config.py @@ -1,4 +1,3 @@ -import os from pathlib import Path import iniconfig @@ -47,8 +46,6 @@ class Config: ) self.mtail_address = params.get("mtail_address") self.disable_ipv6 = params.get("disable_ipv6", "false").lower() == "true" - self.addr_v4 = os.environ.get("CHATMAIL_ADDR_V4", "") - self.addr_v6 = os.environ.get("CHATMAIL_ADDR_V6", "") self.acme_email = params.get("acme_email", "") self.imap_rawlog = params.get("imap_rawlog", "false").lower() == "true" self.imap_compress = params.get("imap_compress", "false").lower() == "true" diff --git a/cmdeploy/src/cmdeploy/cmdeploy.py b/cmdeploy/src/cmdeploy/cmdeploy.py index ebd05ce4..9fbc221d 100644 --- a/cmdeploy/src/cmdeploy/cmdeploy.py +++ b/cmdeploy/src/cmdeploy/cmdeploy.py @@ -101,9 +101,6 @@ def run_cmd(args, out): env["CHATMAIL_WEBSITE_ONLY"] = "True" if args.website_only else "" env["CHATMAIL_DISABLE_MAIL"] = "True" if args.disable_mail else "" env["CHATMAIL_REQUIRE_IROH"] = "True" if require_iroh else "" - if not args.dns_check_disabled: - env["CHATMAIL_ADDR_V4"] = remote_data.get("A") or "" - env["CHATMAIL_ADDR_V6"] = remote_data.get("AAAA") or "" deploy_path = importlib.resources.files(__package__).joinpath("run.py").resolve() pyinf = "pyinfra --dry" if args.dry_run else "pyinfra" diff --git a/cmdeploy/src/cmdeploy/postfix/main.cf.j2 b/cmdeploy/src/cmdeploy/postfix/main.cf.j2 index cbae0f27..ffe64375 100644 --- a/cmdeploy/src/cmdeploy/postfix/main.cf.j2 +++ b/cmdeploy/src/cmdeploy/postfix/main.cf.j2 @@ -69,15 +69,6 @@ mynetworks = 127.0.0.0/8 {% else %} mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 {% endif %} -{% if config.addr_v4 %} -smtp_bind_address = {{ config.addr_v4 }} -{% endif %} -{% if config.addr_v6 %} -smtp_bind_address6 = {{ config.addr_v6 }} -{% endif %} -{% if config.addr_v4 or config.addr_v6 %} -smtp_bind_address_enforce = yes -{% endif %} mailbox_size_limit = 0 message_size_limit = {{config.max_message_size}} recipient_delimiter = +