From 5594b16923cb205095e16e908e00f0339f1acd86 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 19:36:30 +0000 Subject: [PATCH] Reject spam to forwarded addresses instead of passing it on Mail to an address in settings.forwards is sent on from our IP, so spam that would only be marked for a local mailbox was forwarded to Gmail & co. under our reputation. An Rspamd settings rule for the forwarded recipients rejects at settings.forwardRejectScore (6, Rspamd's add-header threshold) during SMTP, leaving the bounce to the sending server. Closes #10 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01G22o7QQ17GRtkCqpJNFr9B --- modules/mail.nix | 18 ++++++++++++++++++ settings.nix | 3 +++ 2 files changed, 21 insertions(+) diff --git a/modules/mail.nix b/modules/mail.nix index 73cb32c..56cdc1b 100644 --- a/modules/mail.nix +++ b/modules/mail.nix @@ -177,6 +177,24 @@ in } ''; + # Mail to forwarded addresses leaves again from our IP. Spam that would + # normally only be marked ("add header") is rejected instead, so we never + # pass it on to Gmail & co. under our own reputation. Rejecting during + # SMTP leaves the bounce to the sending server: no backscatter. + "settings.conf".text = lib.optionalString (settings.forwards != { }) '' + forwarded_recipients { + priority = high; + rcpt = ${builtins.toJSON (lib.attrNames settings.forwards)}; + apply { + actions { + reject = ${toString settings.forwardRejectScore}; + "add header" = null; + "rewrite subject" = null; + } + } + } + ''; + # Cap how much mail one authenticated account can send, so a leaked # password can't turn the server into a spam cannon (and get its IP # blocklisted). diff --git a/settings.nix b/settings.nix index 0f0cf85..2565a79 100644 --- a/settings.nix +++ b/settings.nix @@ -58,6 +58,9 @@ # Forwarding breaks SPF; Sender Rewriting Scheme (SRS) is turned on # automatically when forwards exist, so forwarded mail still passes. forwards = { }; + # Spam score at which mail to a forwarded address is rejected rather than + # passed on (Rspamd's normal "add header" threshold is 6). + forwardRejectScore = 6; # Contact address published in DMARC/TLS-RPT reports and used for the # Let's Encrypt account.