From 01951eadadcc19eb88b75e7341c5a40cd113c94c Mon Sep 17 00:00:00 2001 From: Gonne Date: Fri, 28 Feb 2025 11:11:58 +0100 Subject: [PATCH 01/13] Delete directive proxy_interface This directive is supposed to prevent mail delivery loops that would be caused by portforwarding to itself. Behind this ip address, however, there is our general mail vm and not immediately the mailinglist setup. --- nixos/modules/mailman.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/nixos/modules/mailman.nix b/nixos/modules/mailman.nix index f4ecd0e..1c8eaba 100644 --- a/nixos/modules/mailman.nix +++ b/nixos/modules/mailman.nix @@ -32,7 +32,6 @@ in { config = { transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"]; local_recipient_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"]; - proxy_interfaces = "130.83.2.184"; smtputf8_enable = "no"; # HRZ does not know SMTPUTF8 }; relayHost = "mathebau.de"; # Relay to mail vm which relays to HRZ (see https://www.hrz.tu-darmstadt.de/services/it_services/email_infrastruktur/index.de.jsp) -- 2.39.5 From beaab16ffa93e2b5aa62cf66506ed4221ec68a94 Mon Sep 17 00:00:00 2001 From: Gonne Date: Fri, 28 Feb 2025 11:13:59 +0100 Subject: [PATCH 02/13] Allow unpacking stalwart's webadmin interface --- nixos/modules/mail.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 4d7f950..76eadb1 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -148,6 +148,7 @@ in { # In order to accept mail that we only forward # without having to generate an account. # Invalid addresses are filtered by DFN beforehand. + # See also https://stalw.art/docs/smtp/inbound/rcpt/#catch-all-addresses catch-all = true; relay = [ { @@ -267,6 +268,7 @@ in { "stalwart-mail" = { restartTriggers = lib.attrsets.mapAttrsToList (_: aliaslist: aliaslist.sopsFile) config.sops.secrets; # restart if secrets, especially alias files, have changed. serviceConfig.PrivateTmp = lib.mkForce false; # enable access to generated Sieve script + serviceConfig.ProtectSystem = lib.mkForce "full"; # "strict" does not allow writing to /tmp which we need for unpacking the webadmin interface. "full" is less strict. }; "virt-aliases-generator" = { description = "Virtual Aliases Generator: Generate a sieve script from the virtual alias file"; -- 2.39.5 From 68a02c75e189e65586ba5a27b5ca2f8564312b18 Mon Sep 17 00:00:00 2001 From: Gonne Date: Sun, 2 Mar 2025 08:33:22 +0100 Subject: [PATCH 03/13] Disable matheball.de forwards and submission to mail allowlist until we actually handle it --- nixos/machines/nyarlathotep/configuration.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nixos/machines/nyarlathotep/configuration.nix b/nixos/machines/nyarlathotep/configuration.nix index 64a20ca..39fd189 100644 --- a/nixos/machines/nyarlathotep/configuration.nix +++ b/nixos/machines/nyarlathotep/configuration.nix @@ -15,10 +15,12 @@ stalwartAdminHash = "$argon2i$v=19$m=4096,t=3,p=1$d0hYOTkzclpzSmFTZUplWnhVeWE$I7q9uB19RWL0oZKaPlMPSlGfFp6FQ/vrx80FFKCsalg"; domains = [ # lists.mathebau.de is forwarded to another VM and does not need to be listed here. - { + /* + { domain = "matheball.de"; allowlistPass = config.sops.secrets."allowlistPass/matheball".path; } + */ { domain = "mathebau.de"; allowlistPass = config.sops.secrets."allowlistPass/mathebau".path; -- 2.39.5 From 3ece72db70be374ea212810dce7bdd91d717e234 Mon Sep 17 00:00:00 2001 From: Gonne Date: Sun, 2 Mar 2025 08:34:54 +0100 Subject: [PATCH 04/13] Rename config option after update beyond version 0.11.2 --- nixos/modules/mail.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 76eadb1..07326d0 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -65,7 +65,7 @@ in { openFirewall = true; settings = { server = { - lookup.default.hostname = "fb04184.mathematik.tu-darmstadt.de"; # Because the DNS PTR of 130.83.2.184 is this and this should be used in SMTP EHLO. + hostname = "fb04184.mathematik.tu-darmstadt.de"; # Because the DNS PTR of 130.83.2.184 is this and this should be used in SMTP EHLO. listener = { "smtp" = { bind = ["[::]:25"]; -- 2.39.5 From 0517a5e77c507fe8fb0293edbe4642e5a270dcb8 Mon Sep 17 00:00:00 2001 From: Gonne Date: Sun, 2 Mar 2025 08:36:33 +0100 Subject: [PATCH 05/13] Add mathebau.de to certificate --- nixos/modules/mail.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 07326d0..94cfae6 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -82,7 +82,7 @@ in { tls.implicit = true; }; "management" = { - # Cthulhu forwards requests for http://fb04184.mathematik.tu-darmstadt.de/.well-known/acme-challenge/ http://imap.mathebau.de/.well-known/acme-challenge/ and http://smtp.mathebau.de/.well-known/acme-challenge/ + # Cthulhu forwards requests for http://fb04184.mathematik.tu-darmstadt.de/.well-known/acme-challenge/ http://imap.mathebau.de/.well-known/acme-challenge/ and http://smtp.mathebau.de/.well-known/acme-challenge/ and http://mathebau.de/.well-known/acme-challenge/ # for TLS certificate challenge validation # whereas the rest of the management interface is not available publically. # It can be reached via SSH and portforwarding. @@ -95,7 +95,7 @@ in { directory = "https://acme-v02.api.letsencrypt.org/directory"; # This setting is necessary for this block to be activated challenge = "http-01"; contact = ["root@mathebau.de"]; - domains = ["fb04184.mathematik.tu-darmstadt.de" "imap.mathebau.de" "smtp.mathebau.de"]; + domains = ["fb04184.mathematik.tu-darmstadt.de" "imap.mathebau.de" "smtp.mathebau.de" "mathebau.de"]; default = true; }; # Reevaluate after DKIM and DMARC deployment -- 2.39.5 From b3dde5ef7ac1ef4dda9dfe0cafe3f7e8b57bc8db Mon Sep 17 00:00:00 2001 From: Gonne Date: Sun, 2 Mar 2025 08:37:40 +0100 Subject: [PATCH 06/13] Accept mail from our badly configured VMs --- nixos/modules/mail.nix | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 94cfae6..62fe93a 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -159,6 +159,21 @@ in { ]; }; + session.ehlo.require = [ + { + "if" = "starts_with(remote_ip, '192.168.0.')"; #TODO setup vms properly + "then" = false; + } + {"else" = true;} + ]; + session.ehlo.reject-non-fqdn = [ + { + "if" = "starts_with(remote_ip, '192.168.0.')"; #TODO setup vms properly + "then" = false; + } + {"else" = true;} + ]; + # Stalwart gets its configuration from two places: A TOML configuration file that we control in this module # and from a database that can be configured from web management interface or via Rest API. # We here define what comes from the TOML-file and especially add "sieve.trusted.scripts.*" to the default ones -- 2.39.5 From ea956c99e7a0c1e63829a3548435156eac56b21c Mon Sep 17 00:00:00 2001 From: Gonne Date: Sun, 2 Mar 2025 08:40:47 +0100 Subject: [PATCH 07/13] Set sender and increase redirect limit for our alias file --- nixos/modules/mail.nix | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 62fe93a..1019ffc 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -197,8 +197,15 @@ in { "lookup.default.hostname" "certificate.*" ] # the default ones - ++ ["sieve.trusted.scripts.*"]; #for macros to be able to include our redirection script + ++ ["sieve.trusted.*"]; #for macros to be able to include our redirection script sieve.trusted.scripts.redirects.contents = "%{file:/tmp/virt_aliases}%"; # generated redirect script + sieve.trusted.from-addr = "sender"; # set the from-address to the original sender as specified in the MAIL FROM. + sieve.trusted.from-name = "sender"; + sieve.trusted.return-path = "sender"; + sieve.trusted.limits = { + redirects = 50; + out-messages = 50; + }; session.data.script = "'redirects'"; authentication.fallback-admin = { -- 2.39.5 From c05d7591a854c729432c77dee812b7cd69e212e2 Mon Sep 17 00:00:00 2001 From: Gonne Date: Sun, 2 Mar 2025 08:41:07 +0100 Subject: [PATCH 08/13] Filter out catch-all addresses of the form "@domain.tld" from the allowlist that are not intended for HRZ --- nixos/modules/mail.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 1019ffc..2791b74 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -252,7 +252,8 @@ in { echo "process ${domain}" # This line gets the available mailboxes from stalwart's Rest API, searches for their addresses and collects them to a file for submission. # The regex searches for alphanumerics combined with some special characters as local paths and the right domain. - ${pkgs.curl}/bin/curl -s --header "authorization: Basic $(<${cfg.stalwartAdmin})" http://localhost/api/principal | ${pkgs.gnugrep}/bin/grep -o -e "[A-Za-z0-9.!#\$%&'*+-/=?^_{|}~]*@${domain}" | tee /tmp/addresses + # Exclude @domain.tld which is not a valid mail address but used for catch-all accounts. + ${pkgs.curl}/bin/curl -s --header "authorization: Basic $(<${cfg.stalwartAdmin})" http://localhost/api/principal | ${pkgs.gnugrep}/bin/grep -o -e "[A-Za-z0-9.!#\$%&'*+-/=?^_{|}~]*@${domain}" | grep -v "@${domain}" | tee /tmp/addresses # This line searches for available redirects and adds them to the submission file. ${pkgs.gnugrep}/bin/grep -o -e "[A-Za-z0-9.!#\$%&'*+-/=?^_{|}~]*@${domain}" /tmp/virt_aliases >> /tmp/addresses # This doesn't catch all RFC conform local parts. Improve if you need. # Post local-parts to HRZ, see https://www-cgi.hrz.tu-darmstadt.de/mail/index.php?bereich=whitelist_upload -- 2.39.5 From 10ca56c064064be56d131528833541c8003db1cb Mon Sep 17 00:00:00 2001 From: Gonne Date: Sun, 2 Mar 2025 11:44:08 +0100 Subject: [PATCH 09/13] Enable DKIM signing --- nixos/machines/nyarlathotep/configuration.nix | 12 +++++ nixos/machines/nyarlathotep/dkim.keys.yaml | 40 +++++++++++++++ nixos/modules/mail.nix | 50 +++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 nixos/machines/nyarlathotep/dkim.keys.yaml diff --git a/nixos/machines/nyarlathotep/configuration.nix b/nixos/machines/nyarlathotep/configuration.nix index 39fd189..762224c 100644 --- a/nixos/machines/nyarlathotep/configuration.nix +++ b/nixos/machines/nyarlathotep/configuration.nix @@ -75,6 +75,18 @@ group = "stalwart-mail"; mode = "0440"; }; + "dkim_rsa" = { + sopsFile = ./dkim.keys.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0440"; + }; + "dkim_ed25519" = { + sopsFile = ./dkim.keys.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0440"; + }; # password for https://stalw.art/docs/auth/authorization/administrator/#fallback-administrator encoded to be supplied in the basic auth header stalwartAdmin = { sopsFile = ./stalwartAdmin.secrets.yaml; diff --git a/nixos/machines/nyarlathotep/dkim.keys.yaml b/nixos/machines/nyarlathotep/dkim.keys.yaml new file mode 100644 index 0000000..a923ce2 --- /dev/null +++ b/nixos/machines/nyarlathotep/dkim.keys.yaml @@ -0,0 +1,40 @@ +dkim_rsa: ENC[AES256_GCM,data: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,iv:QbZVXp5FQhmYZvXxXNxWKrNm5GqM+2P3a5pPk499mlc=,tag:F+KNoPRnoLLhOpEj6Czj6Q==,type:str] +dkim_ed25519: ENC[AES256_GCM,data:cZHm7bVpQ/VhYLt2CnNk9364k+J5ybgSLrR7Vm1GsCU6JcAvHl8Y5R7mqwgS+gTnHX7K02GuIGXa8909/aEotE0ZMY5irKJ25SGJqTaqQafbiMOz65CRQh5trtcMBF4s4wRYOkDGgz09KkELbkDHyQZFcrGqvgM=,iv:p9ROj/epqR3xtrimXF1onJJHH9JUqNG9z1MxKVu9uPg=,tag:m53rXkcu+ernS5JX+k8YcA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6VnhvWHdsZWNHemlueFo4 + L0xCTGp4NlRuU3YwRWJiSHFBbmtURTNMQkVRCnlSbFc0Q2xINjRvU2tQeStQc1U5 + VElxcTVuNm9MUm01RkpGYytrYWg0czgKLS0tIHZqUWhkMGRNNjJvUTQrOHBpZXVS + NlpjeDQxbVZIRHFCcmNtT1JSVHp1K2sKSNcC0fcOar/KKzs1twaozB8wfdFT9OdB + 4quV/ycNpJpfs6+2r0RTLBxYFyusybu1swosAni+PJsRXS82+PTXHQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsUTUzYzZuMkYvcTlrUmRK + aStnak5IWitFUSt0eVBQOHIzcTlrMFRFTjA4CmlYUTdobXFUK2tYMWtFekNqNnhp + R2RRRFdHc1p6bFVjYU9lbTRBeEM3Y2sKLS0tIHdsRW1wR25pVkZIYU1yMm9sQXpr + NFhiN0pyaHVWT1h5eVFXMWZDb0sxUGMKIVkYYheD8F9aaAyCA+m9ZGlV8vKbAW4r + H6FUe+ats30abxoYfHZfMJv17BxJtpodksSxWjnPYm0dfRf/EF/vSQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvU3NzY0Uxc0NhY2xJZyti + TCtTS1crV3hzMXZNV3k4cm0zUFNuY2tBL0dNCnNpYytoaUI1eERhdG1PUlZ2eE5C + R2UrVlBwcXR2L1VNR3RJL1lEQmlTSDgKLS0tIFJyLzhZeG5zejFmL2VkYy8xVEM1 + U3QwOXlRdU8yd3ozL2hUVzRXNGE0bDQKT7SLAqICsbFmRUF+3s2avpBt0dLUbHLX + AgQzx5v6GpMMNwCkCrOnpFX6al7zkRSYHe7hbn03BBORz9mPHek5ew== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-03-02T07:58:00Z" + mac: ENC[AES256_GCM,data:OvERjDFfHTJbTfwq9BmXBQy6pjeyIhao6zP4we0KeYL3skbw4+aaMixjUFzjauby0C7nJjEPBSk6pwK3lN+rScS5g7J8tTNtmhfEDQbfsS5zNDKzIQjYxbUbDr2cTPWwCA73gRGMwLbyNvdfuEp46jNV8OJ8km/y2nyG9lDcBb4=,iv:0RSU2MdZWiYEapwXGzevP9/vc/Sk1MS6a0MnCRQyIs8=,tag:vvngXS2IRzH999yzo4JyFQ==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.4 diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 2791b74..391778f 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -108,6 +108,15 @@ in { iprev.verify = "relaxed"; spf.verify.ehlo = "relaxed"; spf.verify.mail-from = "relaxed"; + + # Sign *our* outgoing mails with the configured signatures. + dkim.sign = [ + { + "if" = "is_local_domain('', sender_domain) || sender_domain == 'lists.mathebau.de'"; + "then" = "['rsa-' + sender_domain, 'ed25519-' + sender_domain]"; + } + {"else" = false;} + ]; }; # Forward outgoing mail to HRZ or mail VMs. @@ -202,12 +211,53 @@ in { sieve.trusted.from-addr = "sender"; # set the from-address to the original sender as specified in the MAIL FROM. sieve.trusted.from-name = "sender"; sieve.trusted.return-path = "sender"; + # If we are the sender, we sign the message with DKIM. Else we leave it alone. + sieve.trusted.sign = [ + { + "if" = "is_local_domain('', sender_domain) || sender_domain == 'lists.mathebau.de'"; + "then" = "['rsa-' + sender_domain, 'ed25519-' + sender_domain]"; + } + {"else" = false;} + ]; sieve.trusted.limits = { redirects = 50; out-messages = 50; }; session.data.script = "'redirects'"; + # See https://stalw.art/docs/smtp/authentication/dkim/sign + # We need two blocks per domain because the domain setting in the blocks does not accept variables like `sender_domain`. + signature = let + signatureTemplate = domain: { + "rsa-${domain}" = { + private-key = "%{file:/run/secrets/dkim_rsa}%"; + domain = "${domain}"; + selector = "rsa-default"; + headers = ["From" "To" "Cc" "Date" "Subject" "Message-ID" "Organization" "MIME-Version" "Content-Type" "In-Reply-To" "References" "List-Id" "User-Agent" "Thread-Topic" "Thread-Index"]; + algorithm = "rsa-sha256"; + canonicalization = "relaxed/relaxed"; + }; + "ed25519-${domain}" = { + private-key = "%{file:/run/secrets/dkim_ed25519}%"; + domain = "${domain}"; + selector = "ed-default"; + headers = ["From" "To" "Cc" "Date" "Subject" "Message-ID" "Organization" "MIME-Version" "Content-Type" "In-Reply-To" "References" "List-Id" "User-Agent" "Thread-Topic" "Thread-Index"]; + algorithm = "ed25519-sha256"; + canonicalization = "relaxed/relaxed"; + }; + }; + in + map signatureTemplate (["lists.mathebau.de"] ++ (map ({domain, ...}: domain) cfg.domains)); + + # Sign *our* outgoing mails with the configured signatures. + auth.dkim.sign = [ + { + "if" = "is_local_domain('', sender_domain) || sender_domain == 'lists.mathebau.de'"; + "then" = "['rsa-' + sender_domain, 'ed25519-' + sender_domain]"; + } + {"else" = false;} + ]; + authentication.fallback-admin = { user = "admin"; # see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH -- 2.39.5 From be998b48f56700d951ca232127d97bae665c48be Mon Sep 17 00:00:00 2001 From: Gonne Date: Sun, 2 Mar 2025 11:57:05 +0100 Subject: [PATCH 10/13] Group config parameters --- nixos/modules/mail.nix | 124 ++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 64 deletions(-) diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 391778f..720df68 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -101,7 +101,7 @@ in { # Reevaluate after DKIM and DMARC deployment spam.header.is-spam = "Dummyheader"; # disable moving to spam which would conflict with forwarding auth = { - # TODO check if HRZ conforms to these standards and we can validate them strictly + # TODO check if HRZ and our own VMs conform to these standards and we can validate them strictly dkim.verify = "relaxed"; arc.verify = "relaxed"; dmarc.verify = "relaxed"; @@ -140,52 +140,57 @@ in { starttls = "optional"; # e.g. Lobon does not offer starttls }; }; - remote."hrz" = { - address = "mailout.hrz.tu-darmstadt.de"; - port = 25; - protocol = "smtp"; - tls.implicit = false; # Don't assume TLS on this port but use STARTTLS - }; - remote."mailman" = { - address = "lobon.mathebau.de"; # must be created in DNS as a MX record because this field does not accept ip addresses. - port = 25; - protocol = "smtp"; - tls.implicit = false; # Don't assume TLS on this port but use STARTTLS + remote = { + "hrz" = { + address = "mailout.hrz.tu-darmstadt.de"; + port = 25; + protocol = "smtp"; + tls.implicit = false; # Don't assume TLS on this port but use STARTTLS + }; + "mailman" = { + address = "lobon.mathebau.de"; # must be created in DNS as a MX record because this field does not accept ip addresses. + port = 25; + protocol = "smtp"; + tls.implicit = false; # Don't assume TLS on this port but use STARTTLS + }; }; - session.rcpt = { - # In order to accept mail that we only forward - # without having to generate an account. - # Invalid addresses are filtered by DFN beforehand. - # See also https://stalw.art/docs/smtp/inbound/rcpt/#catch-all-addresses - catch-all = true; - relay = [ + session = { + ehlo.require = [ { - "if" = "!is_empty(authenticated_as) || rcpt_domain == 'lists.mathebau.de' || starts_with(remote_ip, '192.168.0.')"; #TODO restrict trust by IP - "then" = true; + "if" = "starts_with(remote_ip, '192.168.0.')"; #TODO setup vms properly + "then" = false; } - {"else" = false;} + {"else" = true;} + ]; + ehlo.reject-non-fqdn = [ + { + "if" = "starts_with(remote_ip, '192.168.0.')"; #TODO setup vms properly + "then" = false; + } + {"else" = true;} ]; - }; - session.ehlo.require = [ - { - "if" = "starts_with(remote_ip, '192.168.0.')"; #TODO setup vms properly - "then" = false; - } - {"else" = true;} - ]; - session.ehlo.reject-non-fqdn = [ - { - "if" = "starts_with(remote_ip, '192.168.0.')"; #TODO setup vms properly - "then" = false; - } - {"else" = true;} - ]; + rcpt = { + # In order to accept mail that we only forward + # without having to generate an account. + # Invalid addresses are filtered by DFN beforehand. + # See also https://stalw.art/docs/smtp/inbound/rcpt/#catch-all-addresses + catch-all = true; + relay = [ + { + "if" = "!is_empty(authenticated_as) || rcpt_domain == 'lists.mathebau.de' || starts_with(remote_ip, '192.168.0.')"; #TODO restrict trust by IP + "then" = true; + } + {"else" = false;} + ]; + }; + data.script = "'redirects'"; + }; # Stalwart gets its configuration from two places: A TOML configuration file that we control in this module # and from a database that can be configured from web management interface or via Rest API. - # We here define what comes from the TOML-file and especially add "sieve.trusted.scripts.*" to the default ones + # We here define what comes from the TOML-file and especially add "sieve.trusted.*" to the default ones # because only TOML-based keys may use macros to load files from disk. # We want this to be able to load our sieve-script for mail forwarding. # See https://stalw.art/docs/configuration/overview/#local-and-database-settings for more details. @@ -207,24 +212,24 @@ in { "certificate.*" ] # the default ones ++ ["sieve.trusted.*"]; #for macros to be able to include our redirection script - sieve.trusted.scripts.redirects.contents = "%{file:/tmp/virt_aliases}%"; # generated redirect script - sieve.trusted.from-addr = "sender"; # set the from-address to the original sender as specified in the MAIL FROM. - sieve.trusted.from-name = "sender"; - sieve.trusted.return-path = "sender"; - # If we are the sender, we sign the message with DKIM. Else we leave it alone. - sieve.trusted.sign = [ - { - "if" = "is_local_domain('', sender_domain) || sender_domain == 'lists.mathebau.de'"; - "then" = "['rsa-' + sender_domain, 'ed25519-' + sender_domain]"; - } - {"else" = false;} - ]; - sieve.trusted.limits = { - redirects = 50; - out-messages = 50; + sieve.trusted = { + scripts.redirects.contents = "%{file:/tmp/virt_aliases}%"; # generated redirect script + from-addr = "sender"; # set the from-address to the original sender as specified in the MAIL FROM. + from-name = "sender"; + return-path = "sender"; + # If we are the sender, we sign the message with DKIM. Else we leave it alone. + sign = [ + { + "if" = "is_local_domain('', sender_domain) || sender_domain == 'lists.mathebau.de'"; + "then" = "['rsa-' + sender_domain, 'ed25519-' + sender_domain]"; + } + {"else" = false;} + ]; + limits = { + redirects = 50; + out-messages = 50; + }; }; - session.data.script = "'redirects'"; - # See https://stalw.art/docs/smtp/authentication/dkim/sign # We need two blocks per domain because the domain setting in the blocks does not accept variables like `sender_domain`. signature = let @@ -249,15 +254,6 @@ in { in map signatureTemplate (["lists.mathebau.de"] ++ (map ({domain, ...}: domain) cfg.domains)); - # Sign *our* outgoing mails with the configured signatures. - auth.dkim.sign = [ - { - "if" = "is_local_domain('', sender_domain) || sender_domain == 'lists.mathebau.de'"; - "then" = "['rsa-' + sender_domain, 'ed25519-' + sender_domain]"; - } - {"else" = false;} - ]; - authentication.fallback-admin = { user = "admin"; # see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH -- 2.39.5 From 85550be50496e24c8ef3c0461bad0d7fb5d5b509 Mon Sep 17 00:00:00 2001 From: Gonne Date: Mon, 3 Mar 2025 12:58:49 +0100 Subject: [PATCH 11/13] Alias file update --- nixos/machines/nyarlathotep/mathebau.aliases.secrets.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nixos/machines/nyarlathotep/mathebau.aliases.secrets.yaml b/nixos/machines/nyarlathotep/mathebau.aliases.secrets.yaml index aed7177..a4a9509 100644 --- a/nixos/machines/nyarlathotep/mathebau.aliases.secrets.yaml +++ b/nixos/machines/nyarlathotep/mathebau.aliases.secrets.yaml @@ -1,4 +1,4 @@ -mathebau.aliases: ENC[AES256_GCM,data:dSvAQESvLgq+k5YF695dUaBI/uMjKNg/AQ3ABa8UXXi9WoK/I4W+cwTFyppWOgKYg+p1APzJ+yfR4THlUkUOVQNcSCq4pUCcVPzv2UrkeYCOa7/0TOhEZGp4Y5AcfjQ9MH8TdX5FNZ2R4l6RrFJJTD5RKbUjuFtTkw0jpwNnICYiPrl5vm7vcN19nvurvcWERx81+rYRDEr6qWxsy3gCopZl3KGQJ2ZlM0p909xYYGk1u69nWBOP+5icEILMSSbM+dCztFS+ubDJCn1nEhmVNCqlfVIgbLkwbG1NwdC9H7RRndURskjni0m9+lbW9jY4El9OBsohQz0pkQp4W2sA5NSJvwkBDbEaxyYc9DwvpMwR5PUXxcx18fyLEXEmUuUaskiuhwBpwgf+uDsPro3DHUy9qQuGG5bk6hbmpHs8DWlyjJt/pdxAJIqEwKo3OH+QOKn/yjOGhBV9lc7YPevgaWT0859bGbfGi76hmFgAymU5/n/Oy7h6sCkG9flA5H2eoR4sjeg0OBJf1T7ZOvpCyVISBKxJBG+BOeik+0cLx6EoMhIINx2vZM6A0DBc+kLBk9weGdcWcIBDR0ml+x++JbuaVrHIr0EUbtssfmcjiW3aYL2CRjIoqdMqk1f66xwP9QhZ+0ziqpkB99mOsQb9Bkm1Zid/blpYMscd5u1E1hnXhunWFi8gXjDXYTGQQ9CzrKE24B2U9KP11mkvaWQjoveNuj8eek3u7W5gRGOAy6hoJMMwKTXIWu4YJbYT55Q6Ppvb1WNeptxuOlCfuXipOExqmwVntu2DMF1AXXImMS2UM27zChu1QvLuAqs+LKmMY38CKR5D5SzDnXNX9gQhXSyX1XHE9ed290prA1LL0TChG7QYCfnDmHuphbT1ea2l/I/2jqfZGuos2+R8chhjgCzRztuWeNF9NG43lBP37zS8/PFMb94A1YMyhGXM7k7nu6SJh1g8HMPOGXRS9athte1neOQ9YlNNAokV/PalBgHoafBPKqbMY3ovVHPT7SR8/wMkTjjXtzUS1V8GPNqQBHYR/eLTi5WTVd2PENmTbu6MQf13kTVLOzwcJIehWETTwmEo21LJSzA8ZvqgOKGYloPlsL6zpHwrPGATx/cH9eCDf3I/bxsgXAT8v6CjmU+VT02Sd5+HgKAaXLKE0aGF7hX7ZOzlhi4f1MgfaZHT+LbEag8tTzJH79P6AZtjFdBA3G0VV1sViIlSEsq8jbRdaf8dQqLlErkXFV51hnqsGrTUsOeu2kWvsHe3oQ4zGcAkfhsXEfRzB6xpOOwd4XanFgDaDxQ8CXDZ/sFbUQIBwwj02LakZEWx+oMcQo1HTpBhdoq6LVwyRCNHTzBkWdrB40iMJz5HZcTLL/eXXrdyGzNu0E1l6J+FY22O+7FRO6hzd9OGRPJAh6ATQOPJXCk6U4TSL9d1suyR/bJcBGhOwog7Y+RvXnBIwqg6zWWhv1MWjd1810F5lf+elK05Q1PmIbMbdGPhGBZ1yFhYJw550Dl6RskvqJpEMXXQ6b5glJenIE2b/WNNr8PQwqm3XKKY9V53xpvTHG5pcsyf7rmL0qHVZYLP8NBBTFnfhtVHT4fEHuaXc/Qi8/mF2Rcj/0mefVGZ8lvqaG4DvibnMTxDIQ30BWx4+m/maVXslKdGjl6Xhq5FRGpBA0SqZljAFnl9Lg/xhoMVta4XGWWsjixXVlzswxiNjCK4dUQGiE98foNi4P2oCeolV7lDWqPzQGjx2f+S4d1ZYi23JpiUXrmnalBiXlQ8AD+swtXbpbixoFLKT+nWtFwAEZgvjyxLSVfoHySEwWa69v4kNzYVjpAuqyEoD01HkNExCyE6gunpJglggbP2sua4TrRler8GcuH+tqkswm+Pnvh6pNvvkp7ZZ+lcGjUbQo/QllnH7E9uytyZhDLxsawOOhp8c+TYOAB8V+7TNdotOR30Hs5dwO+gum8zoGyeijP1/uSvk4ztxBGaJGWuZXq4HHSq3zDhOvSCnbgrDi5W2nwCkMHCcaA+9XLHWWOy6GLRIHqdDjagKRdmjx2e0MsQuXZIqgSdflNYLahuk/JJ4cqnRykz58ILQi7N7URLxs3SdJvfMZB/7ltCR5hc5raDupBWKJz1dX5qd9ZPY4QPRnSYKVuro49162b0qHwLdu5xsZUJuUey3lFvo9WHW+GcVH/irNH19ua5YzKJWd4qHHbhE5hsi91n4sWxH6gUfs5IF2fY8s98PU5VVstJlHhs8UrjbiYQdn0EhSxEBW5l+3eKLze2nPHCDbiQ6oe5c1uURBgA569ABHcapXi93ZY6Qqge0j1J8sFdyd7I3sOY7fjY6hdYzNH/nJCBMAh9iVMvu5X4v6Hh/E2J6tkZX7DinD5eoGUzxRkSejVRytfvbRLCXthJUePN2MOqBkAOEGCagDfNJx8MgqqoMgv3p/yBa9YxyxbHbaEwVv9s9EHQAabftBo7UQn47reFp6uPD+LTBkBq66oFXAkh6TxcRHjboPg5tVg9cVEg4nb+o8ylL/uyiw3svcnpH1k8WkvE8C71plitgO8cKEyiBdtQCUHi/5xn7DAPzkHO40ywDEtA747jrsaX8oNIwqKDmOarZFuYfPh33H9P6bjJ1++YUWZs9R8BTtAAeqpNthRI1Eww7qCyzthajQpxK0mQMQjj5rrWPvEnpmwKGKkBoAkQgA2FIukn+JV9cv/uM9z5DXvN2VMxe0GfH/QnYana98sWMycWjsQJMK6LDyqy1rC34Z/W7HpeVJPR4yXR94lZ+lepKrTfoVTlBmkZIadZn7TC1HIC5PZdscVRA3hOv8TshwTmT0XijbYmRqafQowMBXrTCe9xRxISaIZgbbG81/GVJnUvJS+uBLT7P3y2ekPczmfoV9DTb/TDgYSvQgVDHZc/qQrhmXMDcsOe4hiCIyJ9NlLHJMXEVvO7BQgFrC5GSsddsrd+I2G+f5p+lDReaT+EHY2yLfuSOq5uacYCXbTn2VEl+pwYqYS+ORb6PO4VLbc9MOwbYdhPQb8+jIwAm0NAYnIdOoRifsiXCDsFAU/z6epjqh2/xy5keZxwQ0ZpewMkKX3BXBqPaDRakHJhzHMYQzCokNLQDwViNYA8Ln0zfN79fjveBkn++jj2tl+x/0cYLEya+BOQjTyEo1bAWPiENTRRBW0xo5b/ynvY5KDQsJ8uz4oJ84UH3utjidw6ZeAG9ukoLxQrAR4rM+Pj/IhDYEjbmDjmpkk3REp+4ONJtaKPRL2VenIViKZfuZw0gfFY4glqtUwzDHWYzRGBSRSR0LIPiOehqgWYt+RFUJBmAuwiuBsfW5Zk2TzN46fsrKD2RBf+uZY94Dhl+L/lJqRXW5liegQEbxbGkjaRWkRTWqgimEPVXlMw3ots3skpj0ezC+5BVcvdSu6ceKBmINcKtkskfzHEx/OEO180U7M5TasfIYePomPJCqk0kht+TEzv2NLMI+k6qy35SsUmEiEaHu54ahII0ciHE56l9zUzLChhGklqu+SF2Yx3vAmcoI0Z17siVG/VJRil4vR7DdFfAqKDEeYjoqGrJRcxNnXZGJWwOTKkx7mH0d/i4z+R7Z8l0kHjsPN4piNHWSo/FnpyOP5EMnlCuO/4rMgmIOdv3LNmdu59bkbb00JCC9VU1ZbAH/uNLrFPNYhfA7VjvlApckgNwIkZKi1cElcUUnm+OJTx7lNmEGJwYJNNG1hxpZuvh2vBzySfYwH9LV34KTivylMqENGD7arBR+ghFfLXpTjnjaRiwAWT8fKyqloj9JAt7RO18DCt9JvYoaS75B/2F4h58+nl/nTmjZubLMf/HYgHEO9k2W+q75WTkz/0HiAEXRD29VTR63c3uPtlLclUEYzlUfHfsDglAUzslAkHmPxhfEfqyCPpjPKgahpMVxRg+9HQgCSxhdYEp1HjJ3ucaHE1AvaU4Z34HmcyyaJGkcbeE7tP+4jM++SZZW7xvd7uSeTVOEz0W03iSSBzCZ2timms+ILH0TSC3hTQpSYlZIqZaQjI+r/G9JvNpBPHCzWpi0OWwD01cpttty7i5P94UNIFHXgSvRFVRdrLpyiHKDeEXdFwSbhCiUmhChjf4L+u7+CI5iIil+KXFhH9RgWEIBT3sYAv9kxuOL3EHGJvHBOz9sR2FQg8X8/OkQkAJF5b99pssxSPSGrzNmoNu5IriyUyYi/P0UWH7L5FLJiKg/2LUXoNa3vD/Rs8z5fFeVVv/GaM6SB3dr1SHFw/xKt0Z0b6NpVd39T1cNNCd4eo+VBbB4/GX8mBi+ARg8NG+VbIrhoudaxxGWEbCt1wIYRE1H+mV28PgC9rOOrMiGk2aTSI+zMGcp+jLpId9zLrR/2V8h3SfLhJTBQJGw6e3QQ3k2IlY22Xw8fY4dvHk1E36+EaP5WHWJlWgnO+iH5ep5t9Kyez+6FdhHnDM+4cc9Ud3JZP2/RAofFMvqRyt4xL84K+szSUwaMcwJDRAlgoikJ7GGOQGIan5VcJ3EXzpfaEkrspijXZ5bYrntvKE9R8mivvhMw+m21c3A2qYn1Vprh0Tcb2c/oPkx+kqMzvKVniNGj0ky6+ancCW6MTmtGSbJv2lfr8R9OjKBrCMpBAe88Q/a2bvYyg+EYtyWx3dpsqyCpXN/wtgDs/N3uRfaSCGRq2F0erhbkYcJYkUwxcsD5c9LQzQvTkL6V55VWna0+tlFrZikBafQCsx3OHPynheU3T5KvE4Kra50Vk52S/a0LDK3ZZOmGcJgruK9u1P4IS4bxj3fP7D9KAadZSWaqxZVbdx+LbweQMyrpScxdD5AOBI+9S7/17syWQyWDd4jA5ADhokMYxbOponnDfm2rhbpMhhwu8OVWBZmPBIGwcECcBGNLBKkKfwoGR0ipOex6+JYfqK73XoOltJMeBUCUtEu1T7rnigfrBpEHJUJxC6Jykk4gSgvFh8lWgYoHIsYYSIkDhuBVD45FViaXq/IU4jBLHiMcNKD8F0TioI6c2TmKkO34LeroFk6KWP5w7R78oy7nO6wYjmcMx01hLUUNfTJjSWNDIyMMoonALOScg3teiDU6fvGfOmfmnjJKjXFX5Zmg48qrVgTrazRDz5TLUMdrBZOREWQJ0V7QPQAk2yk24R8Bcz5GP24txRpkaVwmgoNGHofCFY6WFj13UsDe81F0he0vSq3/FaxhPXQiBpaStuzXyAQNGqPPx3GoXRIZLq5KiGSQTiDVs0Tq5SciHH93G2vRzOQ9zHaYyQJ60fkXbFKY3E7Gbfj/j/oXODmPMxcmCPPqjvYI9gx3oR78BniEAeTq/0r7cRTGx2DcaPh5hZ11tpsBA5MRDA77B8/UjIo6glpk7BNBq2wyw6+dMUixhJ0a6Bn611rZaQDjOTO7hhQPSDUdjfWVzaosB6upriQtLCW5DVJQmc3f9auZnEeVXFI5OL70HxrWY5jbyMVeWMZHkV/4n2fn9B8ynKAzwOvHMy1eHn/F+XHsjIhVh1lCN41lgh87/qEAo0nh4xFefu7wtUChh5tKQiQwb0V7bxwvcTsnFwJf+9j7U88Rz/NkdAMquj2y7CLrdLqqVPJMbJYmRkUW1ko+S+I9V/qnSVjgMalG8Xk0Sqd+tdeboQuU6ygZlt9YkEMmFLhnmKsxEiMonXVudwSJ7tPxWnvj6Q+fbs9EY20NHPR29uT3dgxKzCXWCiADn1kEgeRi/KI0dr4tgrf11sXxrhC2cL5XMpVKJcswvQhnXB9TWZJgakOsy6lU95DYrvSmEz5nS9yIDzAChIB5nUXB6Mos5V7gA39YfrWm1TuRw528YLUdy0gjPGAVO9KfysoGd3IzOR5QkPE2iafkiRa8nuSWFuYjXuoNCTvy1t9UhO6X6i47kAohZerLEBzP9/eotPKtOASrFllg7RPlJO/OIA3y3owYCkB8bhDb07kYwtEhzLX9v14IBEfYq7vA3rcOPr3jSXVU+3Whv7h0VN032SXGq0yORoKmC4yjaWYN9XJqXHOaaq+79yxJai0Vs7tVyq9OcgD3tTSbSWp6ID6EGoT9rYTME71wUvmVG1LGI9DArT3sNDnyhcKUa9Bg/SZecX+32N1AZMxhKLIR2fsOKG7+MfEBC3nvf4VnFGpeBCybSm3WJqygvuHSU8aA3obeqHQPka1rpgtrl7Jc8zho3pAU0dn4lOxH6Hfo3eYZk1z2LF+XMoVj9V5WstfEPxIR/ndRllK0LpcLsZ2/D8llpQQNQC4sGbXzjKE8YzsIp3oh9uVHcdNXlVu9mQkndwHqAOtsKCqyyHT86gV+uiJOp1gz4j0EsbAqR5o4ui+EjA+wjpgLUctylmv6Zq8GfdWNyNUYl4s3Y+1Qw6M3b2Gl11tftQqHC2ajaUcjumLJaX3qAzoO7yyDjObix7kDmwx3e+M1/T1ku41YyBLuFCpKbC1kUmyUfazcQgzdc+tVvYJc3XrM0uKpkSRA41cSRsc82IEjILzxUox9jT7ApKxDRquSJWJc8Ri1Xk5yplFyZkUzYuvUMHEA/IuuA8Mxr2Y1Rc9Y2esOfZK9JgFhPylTZlYpv7Pklabb9KJw6pe6rLoHVtW83yNmnHME+sqSKyz/U9leJbfSKkXS+h0ez42R1Qs9eb0Hmcam9sSOjxQZrnxdiMJxZt7YFJNwaE6AqpANTIcgmOcZl0KLbKoPN9W/9/1LGB4ulbAhdB0CWCqvF3cvm75RxwBvpbsZjYsthFpKXnUF3yWnFNnACtyYGlSdsyt5CYhGYY4DnENzb6meNEkKOg3YMgupoxbeXS6YA0vxQzqEjS+f1eK+Ad5ohQK5puv5S4xtuDxgs99O91E9acCHsAaxKHwoYUuxA96RPyAUlq0jxyoBGtPXpW9sq+wLtVnytLRCfP330W1GsnixN6iGuPtBDekXkb4IVJ5+fE9l/OoKYsmN3oUZRVNdVQNuTjv2hW6mLLBxsuOSVSic/8InMd1Y/0EdyeVaC5oVx4DDyuAhkOXiBSQTSV8CFsvPaiaGpnnHSUbnpoSjmGK1QVnPJySdHtWt3rFJGOLZ2g+U66wjUmADqSyhSZGNKuq+yhFsMTHoBmoEp4qq6kfs5suEd0vdZXfmR13yQgdzYjHNIVQYAGeyTlRDrV5XiJIDFZ6x3pp8/JvlPPXSJA+dINRFHWH13zGKrE5BCkiXxQ8bs9UVMazRZ1x3p2Cx9PNPasjFHRu9xQ5TCnQH0pmmXZuyRXcTmFUyI8uyz6AOhpUqlRWbHNETMzijnkZHYsIRHAB+y2YNZrINRk9KmqXenqIXfG/eH/mUBe31CM9AwCNi3TbQNDDwkZeigbcpqW7/Xt970V0R8cFQKE2H2L7Rk2XWpI+pDSjL9rrXQwqO9o/0/eR5kPsdKBuDRaaDX05Xv0oXv6mZFcBfpq7y3qB/b0tYGKGVB+eePRavK5QVojVKBkwNLN0LpyI9Yb+tL3vyVsVWoPRGwekjAqKqInKzpHF0HujvPqzcFjjFxFrV6E9FeUGTGKH3C8yxenuve+YQaTGcK9oDwfKHgPdV6Q35EfSZVnPlk6a0TfyCerdrqaYFriSpTIlvTJFv9eh7m+x3z5JD2DKSXV2KBEDZmMZ6un6ff7q+g7Sxq9VuBlYhX1buxEP3BkdQT/qKqGP7mj0JrmwzEbyjUIeRdMBdEN0zlEYkhCjBI9KvX/HNV6ERKcurn/7h8Zf44DkDA2jQxKeBtJPGABpYNDpnmXPkglgWoW1SPUxCCMKPSPZExgIkDt9acQhJF6fYJ9wPwbFhC7aRxSj09IYIZdgJ/yCxQukLi/pEuojDg/oqN30PoBi7r0+VP39Mh7bBvSuPuamjexV4m7Ujxv5BdEvl+PcaR1Wdj1p0ctecEH/zBv0RA4qggY+dvG6nrGS/uFRJRRWAaSFuUcnk2iJV7dRs+29BBmKS+jjTRIsp4OgvUeYppZYBP8ZVC1Iqk3JhkvlEB+iBeFErkpQ2m4v8jhgYDSi2KQcBvtD9dKqJeKRg5jJaH9pzr2N7HsOZXZSzd8/xYJwNaCwblucaMQZsb0tD+ISF0APKYh8Xe94SLaZidoKMujuKGFltO4EQIvKSOiYTNSCqanT23fpOSk4nwOme1IDFEGq5cJldErUYI3sxEmF0du6AUqcGio1P/GLUHtJESB6W6QcrqeR2i4pgShkwq3g8Utu1BEUOtNEsHKXff2oV2XtTMH/msaXe+wWJo+OTXh8+TUJq761q3uelbMeevyuAjJvmkZZAdXYCJsbspMrg6ujhkDCl08dBjI/WAYhAEgUl2SjXevyKmacy91AnIP9VlVGA3NNJ4jyX8h9jr25TtW4vaWCt2SWdWhSj0wGfpJEtN8MXsG6Tb/XZHegUzA1oWEh3Tq5tciGksJ7HmrNc6imeAKnHKRYWMmK4aeat8R595IKEK1Xx+Pv4xDjxodIX2zWa91lzFdWBo1K2MwczR7KXFnQYMgss/gMmJqW3Hj/zIyE4ul1+j9QAP/ddsnq2/2rwGo5nIceuEPKLBIOdKxhymOq/w5GP9yf1i1vORDH72lDyFOSY+JzuyR8zVNTR6opbJAgvD+3UOmGN3xHNbW/UXOUw+ggX5uuEGKox0Um0wIoN6VsoB0kvdkeKy3c24puzU1aCcPhoUf+B7tyN+rsgfPSvMdrFxrKdjth8qAgGfloLH1tZMwTISYDestd6z0slKkHWsm9k5a/9VGeJXu7MtTuoFzvYLsPCJI455PBepCKbnjhLiHC6KtOtvVz+4vTUCSutdh7YpI+otnu5wfci7zaU39lx3DVAHat9ot7DKFZlFDkVcoJcrEuGrHBsSiMwLUiQYbT6YcPC5AZY8EZrYPXGp6VD0NTkpcJsf/8PC/eI7XCdqd+giiZLyDZ5UhkGzmkoqL4oG7qYsaZ0QNht4QtVnTIPM5b9QKEaN+m7b9NBj8fphFP9vy8tkir7J2cjAOUcA7tZopHRjwa9Mk1VDrHKsXDa8TyFPE/Djf0NgY7v9SaFozNss9U2830w5kRYcqlMBMz5+34db4LVF8CZJGJqvdKI7jMs76YqlpdVpE6D5oBI6c5y2Xrp9fYKbVYrt8JPGYm+X7DGKdeSoWAXEBrDRIPifpSWl7PLn/jLfZFOFf1SDiA0fG+pH9ufRUL6S0G2xwcO6U32diMf2P/+ZpiQGk+wMsmToSLiyoQzG0eHT5+WdfxtYjoC+wNkxKC8cWxNZTBj+fpi5CsHsCd9rPz17ueK7VCZ9jnPAdSvDNfIJGgZ7CrwDHLt1mlGtfjtmY1IWziGEfH3ygxnwmxWtHJdt31UTiAbLNoYLsElKYy++67JryHIPbqbR1ciXvHjCupjwfBZ+i/LpDmYEY3Neawo56hEoSmxPJyShBGBUpRXLLdOv6w3siPy6vi9f8O22tC34tD1mzg576wmL9H5SzTzPmayHPaYkPMhLpuyshe4TZZ13c7la+V+Z7BJYVwXQ9GRu2cSXiowgi/FEofAYqEpUynVwBtlrzU2z6b2LpikEpP/ifkoanosFamG1NOmHruB7v8J/YCzjBejdLU7qRWnLnd1NqLQ4KkbJ86I2FCQ/MMZF10dp6RrzVuC8Sf/CQzTyy0szaRgAO6DVj5yXJoXiMEcGrwUICA8ayB12ylmGrwcsWlMyrejxEoDmqNN1AHQ2dX8VeMDkFQAt9pTo2GXPrA0YvBjT8HqVW2eYTjY0uEhKuajjDg8/n+NxK/fYFHwLa6sEMNannVWUGXhsfPc3CP/Muvhdirr1SH0Ksa7S+IR27LSE/EpUZ/VGJW0SaTd2ywqH4i6zb3fyKs2a+4qzSe2UTHDMa/qLLtxdAIS09DqOH2tIk+FHMSkI8nVENnOrFZJemSk3Kw82EAqLsBN/IzQ9JXRH3mP7BcGOhVPFo6wJPFsRTPUklIoV7sOBrAEi68qbNP/ECmAz4hlCYOOHVOgp6vjaY//dB+QmLyt+naeU+d9bas0DvmfkN4M5qnm9s6qd7GPs2bD9nOkz0Zbjg7g7gtNtVOiJcfGCU3Yetn/XwlsoDexl+Dq9zp01PEgk1+gxdA2cDY8PTxg9TdrkAsPvUxlbW/ZW4Ub++ObMHfPTeYC2AE4idx/FVYH8NXOYNpHRF0ZNJykUSvXMFi6+dKSw6G+j2BzEYIbryUKtHF1S8ET5J1vcnHX58ULZ9DlVhGjZ0haNHidZhWGn2SeO6YSUxEYrPFYRZbu58dmNMpsb5Dw7IL6i/9dkG58VnBP+e0pYwR4Q7PY82KYqHxfnKuAfKuB4KFzecyz7AvLGQkZrQQNP1gpdJ8GdiL82fL+/2DBXRxRuXtMsTL73Y1cjH8zHpGoydwPnPurtWvWHnHRLhB7CKQHu86CY+wRx9dOvY8grIXJcckDpnLM4HzH/4Doqp0n+JEjTkKzNyGm4v2bvocEYGAQbTz6FRflTXjxhhCdgPXL8hn7gyKRaZM59ugbSqdm+MOmxbtQz3S6UmgxVAB04ZBDozUGV1MJs/tSn+jArvvQE+N3AgrdAAXJesaR8CMWpA/ZWclJMsifC/NB0y2hBZrcgve+BpYsmVRfUh4AUz3n9pAkaL6tFVI16gYjMLzWQ+yaNh3cyaYalCSyU7U4I9yJYnmjnsOeVCz2XVHFl9sDvKAXVJztNzvxvfomy+77kqH45Bs89kAej9VH2feAO8rkJjCaCysOrFWyDgWIiz4YWG5m47nQruEqxWOqAV2TlJhOlO+7SNHO7nYnizIusCJcIPuCCmI8NySrsxMvUC117/u0vcA9hvuzoDB3oJHLNua71QhYknnYtOBKK9h98obLrfe6PVUTdPTI4UehpGK8Nf4+TqVGxt/f9YRkrlHFQLPUKTWTM1p/iK9L+70fZscGJsqGAAzC7OCDJB8dP1mEv7wg/TGKJQO+HU2X9OJnZqeRdxKoeCzBhGZxlxPdNhWPE2zAELWAX8ALJZ/VCMLmLLSx7zN4qxI/iYIj3WScKLpdaXqDIM4f85MAlKVPma759NTMaa/g2HRplFpS/8+HBDhiexfo6ylFjaeJXrOa/tTo+esviG2FYk/bcLMdVGqKR6t0gwdMh+gjmJDo0UkKCHgHCjivj1a/20kkpdl6xnOtNNG46/7wacclDm9Kw3WzX+O+4OglXFtU+ngxITNOE8OvKGmJC9wolzKKft+u7QrcrB70TQsJgjK7M95RzOnUBoq4qqBw4zicTrLojDJyZfTdPRxQFwFD15hj2ZP0c9ud6Tsy2kFrl3V8kl7a3jf+TGXhFR+ht+FxGkMKXgYUradYImeUTnQ95MY+maFyY0iXdAbet/wxUv9m8q8Bx1MIkLbZLq1ajfCM197+jjDdAmJraRqazPgw1AWfisa1wYwMUlSZ5LiaVl6dP/rrQLx+Ifb2L2QAAQFRvoDtByA2i5NQb+5XzPLWDQrSP+Vr/9sop5hDypHIsLUZfPDeLWTNDKhaJ1PtIxl9/eVv6iQOYZ/+4JqXoY3yx5Iu9zUHpo5QsdinIBpxMwZVt1QRl6tNfOiQyAGbV+kTRbafAFSpuEFJ55sMJCFypOSG4/5A1qwrLymeav1/l3KdD7lVPBoLXDFaYUMTdTYu6h8g8SlUIGwxCw2J3kYe9F8kwr5u/RXdyYCy4b+GcZ+z/SGINNfjDu70rmbwuzNr8osRpmAhAnkfauRgKand3Txi9Q+gOafAneLvG6+ulP8REz2VyJxIDkigrl6BhW8H41GYzyrncTfUk2d9jSn04bKRR4mW1iuYiizFALIAV9jzxlb/k7jr4IkisBCxHqSYEz96AtS/JX9XGTQe1BtWZagM2s3oifp1IRALhzo9r4pCCREo6TgxbSBCFS/3fZDxxMzWPO3y3DTX2JMkFKTDR99t0eMpDxwZ8+W6mMBabPrsR8OGgRevosNT9U9huDSvxYv9Zzop4SnpvYx21ZufiYoj+lrwjCw7AU7goFV8oM/na+IJuHmd5/2weiZmQ2+PfVztpXUgNRMPIYQwgmg70VEYGVPlJu5CK+DegPHOttdojVrKCixh3c7tSVXw2rqRmaYCLbIaQcZXXmgmAhEdiPLj9XOXo1Q2gY4hM+nyXtuCwwdFAQnHu1Clk4tzJKwg631PM3qkeWfY4iNpEYEbdoC5yjsDogJHtrM6FA8GuTvktet5aixycW+Da8urbDrutHJxS0+8Cm79BiLzRMGjSPk6wHoxGPqrnahay33E7TuPA+UUVCCWncOjkzFBi/otstuN5Radvx4teaWNDFZzls3viQISXNkiCyjWnJu7PEtpfXeLLAdQn2sYIZdzbfrWEpgLNwBWuF4MfCw/dg2t1CtZfYxd6lJ1vcCmvoUMzK+kXAWMSZCckxEMNVtEfW5vkPYhkAsVG8+oN6pg4fiYxn5ukE1qvGpMgDs2fxsV3agGLcWzN4wo6KhYeaLXfcf64e3iQyjGGQNL5WSdUM+7gzfG+I7ldh/9JyIK8DejEjWSunQnwehG3iur2+c0+XoVIU/t626f4cRamKnLYPVG2z9PqA9p/8lX3Y48BoxFvzG6ckJZ6+4h4/hcAo4AyTGTIMk1BE1OUR57BxZp+Yn7ymrljk/tBl+nxTj5Oy8Y0Jyvx3q5I7I44Ip3wrKBm7ZikhroMFtAfPr9gBXpqnnioyMiYAOyBwRpMKH2l0kBgETuKtsuB5CRdsXLYJgB/ZC/oAnAatyDmjSjeEN66xhLCxYbrapiKkx6ivOIE3G8n//eoxjL4/Ay5BIxWZPzOkwLeyevNCjdfki+5h9ZGkvnD/WafwWa/2j8bV4YZbfElsXW07zMN90V+uLJAhzCtAtix3qo4pA9uUvQ/3GdVdqK2/0CPjOY13Si+2Eyhf552YRR4BYO3v4c5PH9VbcXzxtOpbkgUrTbLbFNIINjxPR+ho0SLUGfF8qbE6zXrzSCNGaTKuZbKWWoIlEXY6UPM58vNwG0vjN9JqKRBuRoY8R9C07ASDsm96qQyIcCHUer1VIVe8Ej6tUdus1ncrAzBMZhGMjeUSLH/UepNCp9aBlW0dMGOFV8okJO5Jt8AobgaohDVntatfQX2vD0BbrOUPE7SmlUCGgwr+nC/kWx80sCekTsu74I3oTsWDaXnimTHgil5hfgNv50lwKq+5dRY7noiMEaI5MJEYDAtLhvQQtu1jj+t+UU/WKnL0vk/Wx9WxjgtStAW1i0ADvCBOsTeQv4VdTmVt5t0X87y6Z9UKsoiMRzpDBTsxEACtJE51oF0oZJLOKcshRgNoXafo9IsDe+t7dv+raRhAO8eacBzBqabW1VTKPcRFKX+ZQtMLNtsNQvN666O6JGs1BHazWZPbUCHGFWqk/xYq7tWtaeKLw5CqRyl5cR+6qyWgMEK4Jnyc60U980WPOcKOKo/x+nbPQ5aO4RBvp0MdAlFqRd8fK0WEk05opxWdYrysn3Sc0VKc0eqMAMC5jUGoQzozGQtg56NwtXbS++eVdW0dBwg1d4GVC38t/M27bblQgtAD/YwRr9eEcGt/yOZCk3x83rzIlLF53lyD84YuU4YC/H/+XxJS0EDAE61ml2JXTxZPzy+MAXVDtjsR8RdOZhTmItTKM/xcKgqc5RUnxO1IuhUAJMfPh14s9c7THzJRA7r/aKFeszJ/KfJbOJnZsyCpluDuNpmckfmUK+lUk+Y/QeRMhd77CH3sQlbw1Tk64Rt0Zx21G6tRfqt7sRuhnVyELDQItdMYcTKmk3pMQTxEHCnbNNSbTZcqFgpX/AFDxqea09QLRyw0+rSypEX0kOuNGJzdTHpUh79gpvjeiOTBt+yID57br1XPdazJ2Mrwl4FBnbo8Q/QVJRrBMzBfZm1odzsW5eUGUmXQhJwJbPOOsFPi+LGdwLgigh8S+EU7UM188Xx6Kwj+vg1raoLClkymtX5LZSP5sZGgclB4lOAqX5fhsY2n23Q5A2CAWYcq7X0zGcyzS6VAOj1PBx9y6QjGBhlHSHaIG1aXnjw3m2I52jZooZRovHs+l9gGXtjGHzMT6X5oQmqCxP8zLuawsDmg/RPf0VmkG3+AiidnESCmrD9xe1w0SwesW0PONI9djYJZ9W7EfHnGHl1FIGX+95TeS2qZvUiQt8CnChGq7trswiRERz9Q1S6sHBfKLOJpfWBAf/Po3ZcZzPqXhrlQrwx6sb4hFWwfaTOm+RlqGb7sbInWeji/AxUBcNTq4sLCq3SB/jppCFe90SccCqiYQI7wi3UANBOdr79OdGudlwlX8jhkYYEEIx20cl487BA9ojGewjXkJmmTdhVYPvewbd0P2R2SRrmGlUL/5/N8qoUmNKWYHCV7mprmVoNu/9RIwoRr+oDwblng4ZqUlVWXe0tZooRTqIr8e4HzmPC9LJEyq1silHUbLoHkSehCnEOlyGrdxRKqSlonW05Jdi2aQ3SP9WVJFqI2S1U9n9i4WTX3cYisdLJI6BNSse6H+hOY1yTh6NWefMp7c7r4HwT3pa4WlWUF6XgI40aAwn4NDkTdSe9JlNIDm8yxXDOdP9sNrDcrKMn4t6pE15eozBJVqkFRJO34IIGmSZ5ZbNlA9jIeEfvpRol66aqrpA5c/as38MfAVCDzZBb5xbfAN80fYC+cZ6C/3qNnRcnz4qzSKQVpSVBJucBz0u8IH6HHfIQFaP68AkTYbayxWPBph6lDsSdR2991+hm1Uw10ZJg7jReDC9WgAPgdAjxvcCDuNZNDKEBmTNvAk3fbISZ/2WuOjd6jWkecm7I6qXKmRtFuJu0tCjqicpRQ4wBkYrU+RzlASOUDoC0/bz6UjTLeVm87+kKNry+F+n0MgcTjvW7u8tDlJe6t3PRcM8qFzJ15gWk0WUWebcf+GQqTcvGHQc16l+4qqxKlavkifsP975aOwT2TFVb9fhNZum2pynxItD5VVi0sNbrYG2qXj04BmhxRVrJcxsxEVIitwoaWrjiXrYfdnCyhdv5Bzce1Cqetqe2dgTrgCMzXuAgkmbaChrG28TQ5rCkWnDfkNmaq6N5cPzeOE5qAejwtY0peYMkeOzy9xbL+QUGtAgp2d8HHK905v+n2tV8P9FnMpEZUby5wq0IfKMufboIAJyY/yP69od0eEGrbN9qEQHUxlyvHmb8oKGbnCRpM+GHVVsl7+DcsoHQsudKcfpjPRAsVAb/5dCHTR9wEzQqv/UyMTe3xABpT9tjpnyiT8Q1MvdH6nzpJ5UaXPnRoatDNIgq2l4QJ9RrRQwhX2/EckSYVL4s4iUHXm+a22Z4kva1801Ig5OJQa6qhfevJEMK0IAnh/NL5/EPc8faEHn+F12g/JvcVJZnL6VSgqZMLP8naGyAmClks3pLAw2gQYTuNnt8Atqdr6rmeuWRHEmjas4eQHGodDTFEDv3jROYnKmdB/JJ5ey4WF7PgGwaqf0iFBND0pTSUj/SiijIDoFekC3ZQd/17EWeF2a+nCHp6/h7wi6uCI9h2JbGuZj/uxmOsnK+zXWurtzygyyZPO2k8OZRYAdIijjwrmwqt4/NSaOtkL6GT90amDWZAoMYjEkUZ8+vaDVdSUyrsACLuHIefygOdgh2+R5jsmbL+s7X8fpEkV38hF+FKlRFdRHEdg4vc6xZjotbttJhUC+C94XvrNNKDxTirMjN6eq2+Q7McJQRNXeZdWF0ZSC8EAm8NQTCCV5IQSEZXGCRFpo3qzip3BfNrpsNNGSwLsrn+5BIFQm4EvqS0EF7kci2RwdqTCsblt1CQ2pZHRc/aop8P9wyWTTNG7JcbWMKJMJPdjvTEW+H9w1LmJLW9mEIK375TKWt9chmDcmz5eAg01n9SHHn3oj72o+mn6TzzCvsZFCkfIUlQwFH4Y7iljD0YIJ06Ar1XbIRo/GsZUwfI6gnKd05tO0ZP43MKItEzhCsQ9Z+XWpkHsw/riE/hZipyobv7ZgKl+iBa5aA2icXPcChs3MWWrhR3awoSkeP6hL6es2c64CXaofzfx1tzcT1B3XklX+l3VxEaTGvlsdQQBcVBt/sNWk4wbIwkMa+RZBJrnhyfO2aLjTt+XQHrMZiyCB9f7rndc5Ny2Tzn5WQJTafeHmkl1aPoVHqrGZ5WnJnjRcrk+bVwVx2MC2nhE+7yn6sEIwH8IaUwuh6okOBjcfPDL0Is/N9O9zwlmRTASMFQucuK/RRmZzvmZikztAztErV6gaQEjvDTtb7j0q9VH8ostEgETkU97ej5ngYTQ0NH4cXnbMBF+lnBmcx6MrvxG4KhK19giDFxZlDRB7iBagxjm7oAXrrFwgP7BA8ByT9+khHyg22h9jELbZ4UpIuuu614+yaO+MPcmiZJKBv71MltJTcQz/LBTx//uQqBL2MnBWgNMF289jyg7XiiJ1lQfnQb8b4bzoyuXzLNZYMqON2ZwV7jbe9yfEEwBzhM+NhLLoothbi/6yPU7+mPzZH/QwPQEDjbjFE6vs7VSiqVvVfbiKvjkwy5YYJ0k4WMetIdbRbknVu54UY5br202wx0Lf1/funtVrgIi5DnixNjWOzN1T2jrPyhd2BtxLJpANY/xsCZMDkp4fX3AYFKNa2TkLB45KIN32NvjPxgjSnEIqTWXCH+haCRgwoVWj2qH4GU0BaqawyGGVho7XIFlNaO2GAWckjUSFFSAIixCaN9itSrKBeAsGVplCvrSCX974qjArY9ky8SGue833HuoVKVCkI7EVA1Yk1dAbaQEXj5ZDyU5wkH7+/qiANI7a0VPP1LK1FgVL5JNn1/v/pPoIf/0qOacAJBQac0JUgXPGirxKchdjMc8WLOtfLEw2FUocjZtmVcPvqNnELxCO+JwKvvWdMBFe9oP3821f0txp+uvCu6dxnOrK43zAqEuq4Nfi78EJZNnPvEoPIugUjnr1YKiIuU3Xb9vPZ8i7/T4CnPK/8Fr5uWfZ/CocynebDaclrKojSpa01vTgaWA5byxQhgy97dJQsKnaDEgAFqoO8XdrC1bbC+9s74HHn6irLCri61xS4UjxWSMHV+PNIOBNHbJvSZHLIexT62VSRNkQc+7KP0U9eWoaX1hu7Xd8pBuxNbr0A6JOOKVXZxoLU9Hjr5qT39kEGdgJja1ijQkFDpwhdU6tK1haUf2YpbGQarTEQyP/t9Du0hzjJM4t1gkQsQ610096X/O4fRszsA+91J6sDczbuVv+zNl89TB7Qkv5DDgrgFfYcWFhfaTEVDZdC/WdZtxrKx83S8AOs4ezy2ueUG6Sjrw8Xq5T7WleT8l2E98ZBHPWW/KE0lrC5enp/7voUavowVLwcJ0peNRb8EZ/y6SZW0vr4CcxHCXjv2RBWnwXxHw5pDfRHwcgvRq2XSEQiVP8+/bABHbvjVNZjA2HGBiNChp3s49OneLsH0FWNnmDM5FTpgotyUOvOh30H4mgo5vNsnIHb7HPLUxa5aKGCcRQUQ8lXpjw3ekgfgy7A2IbISLPwfUqdClmJ6D0hiTQBdgUPbUsjq8CHxAkyk+ayGWnJOk284VD33fivPHRF4Gf8zBRtBFJvHbyrrH26wiWPVtmrPpulCESBVok/hl/PQhpu5evmxl+o/2j2YYc/s5MOi96/jEVhPpW/H7hRdrJAyv7wRZWvmjxjNbhNqCEip/BsXku0/Uft/ZfxtE8/xACAcJg4xF+4Bv/JTE60xX6fksTAgDI9L16noXcGcqrUiNv1TNAYdxctAgqwhUwT/hV+oOuzKhtQLCLK5ojehQIYFE0w2qIT1wLH2Jk66KvMD51lQTGV2KQZN068wWrAbH+vGsAQHlwQKaAat4RkA91hF1wFvvHtEC/QxvF9OvzExSei5/T5D7anAq1xI3DW99qTQ1spIdrtGwECTjRq2AmFi1Q//kQdWmEJpTEqKXRclKVdF76uQhExiCEklxHTtu2UcNMcyQtGv2vFVPIfzpwvwppmCewvIc3mP2dNME9GRDfRfBPi4NYv/8jmlDbKJyScqyrp6QSmBSaoaGpQEYpAPgc93vmPr2IxdzOO66CIhLxZzhfOiHaTxgRiNl2pdFayotmdYTO+HPXgY0KP4kXLcy8cjW7isQ1/yfwydyEAKOb+eiulRFOimpRNvQklud/LiuT9ZDetX0CxpS0y7ujLKMoxfFvylMZMcnuE3/KDw1IFN0HZegmwXbHzpABDRxUxIBlqPQ3bPPviV0HMYj4rQu5acm0X5juLkQKce89iGGYaA348lifhxB5Ocplzy3SRgEDaVHTzzGw4kZoYIBNKN1cH6AlqdtAK87FGZsHpRp0Oc/jw7WjwbGam1dxolK/n+4H11Um8POkL7pH1KePIesHaZR/kjNYV6jx5vGOv8vEnaiki5MAyJnD1tBNUgB4GMaJ4drQIWo6RETfupS3vcGwfZF9JD2Tpw9fsgVFW+MqNpbZgrmVjc3QC0jTW46eH+qQBtYhEDuDmGAVs6pm9ljxua8fjZ1qoX60fWdpvegFPCe/tyXzHaL5/5fsuAKfuXT/q0APHahnuLnLl/3W6sx28JOWoRI9aDOrGOPSQVYIjP2sbLeyiXjSrN8fOcOSSOVr6uXyIb+tllbzw7c01zfjbv96H,iv:2jIbgMhGa8GWlDQeQNuAOrxiC03V7sdfy8EorUcjP5M=,tag:8/owPwtrW4khSqCraE+PDQ==,type:str] +mathebau.aliases: ENC[AES256_GCM,data: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,iv:Bxtv/WP4akeJGDECL9QTkBpGsc/u82uPQ131wOnFOY4=,tag:/4iI+VhtzpafIiuBkgpjIg==,type:str] sops: kms: [] gcp_kms: [] @@ -41,8 +41,8 @@ sops: clA0eHg5bFNRU0lyUmRJcUpSZ0F2dmsKKm0EriU4LFfV2PWm2k9Q7T2gOgG540Jy rjfQny0dUNM1ofzYSLDXb+Kfm5/aVwNEX/Hl1Jya5ERFJswKbVlCgQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-02-25T17:40:56Z" - mac: ENC[AES256_GCM,data:5jtuwMlqF+0FFo/QWnogC+Gm4ADUrhZLFJ9qoLMxDfrY8c8AHPDV+rNk9e/zO+tmqWcNmktWsVrK8xhmCTD8cszTMHdGRxjtqvjVatd+xjAziBik5SFR4pWO7doVx25iD6DOItARW8yxRLk+yMhTgWpe6ozxFhnGH+YdEH/rVNQ=,iv:f3xIO/MSBVfIeAfGtMUzqhY9/U10we/fftRe3/88uCA=,tag:nBSRI/FpOIqrknmlos9Vvg==,type:str] + lastmodified: "2025-03-03T11:58:32Z" + mac: ENC[AES256_GCM,data:0IAwyE28bwU1PHKsLvgaOSdrsiNO7Uyxw+FRxEknddLBDzgH8oKNHc5HOJ1qLsIBrJcUbo0hIOf1c6HQTSN82G+69TuhUsrENN6w86EVcUkL4GZRFbn48mQrQAjowz7JAGIdjwykJWOE2Mdacvk+5Hhvh3yW80QZ5OkxTCewkVg=,iv:kzwY5jDvEAx3I7czURxoeBE/DjFqXo5OfqqOuksKQiI=,tag:/K9gmH2roTZ7B436PIxZbA==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.9.4 -- 2.39.5 From ceaaa3bcafee7c0c47c25bcb95c356f7d0c49b68 Mon Sep 17 00:00:00 2001 From: Gonne Date: Mon, 3 Mar 2025 14:49:42 +0100 Subject: [PATCH 12/13] Only set original sender for MAIL FROM --- nixos/modules/mail.nix | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 720df68..24d144c 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -214,9 +214,8 @@ in { ++ ["sieve.trusted.*"]; #for macros to be able to include our redirection script sieve.trusted = { scripts.redirects.contents = "%{file:/tmp/virt_aliases}%"; # generated redirect script - from-addr = "sender"; # set the from-address to the original sender as specified in the MAIL FROM. - from-name = "sender"; - return-path = "sender"; + return-path = "sender"; # set the outgoing MAIL FROM to the original sender as specified in the incoming MAIL FROM. + # If we are the sender, we sign the message with DKIM. Else we leave it alone. sign = [ { -- 2.39.5 From 19351ef31652e0c4184a4e948bd097df28c8670f Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 4 Mar 2025 07:39:36 +0100 Subject: [PATCH 13/13] Hack around sieve execution for multiple recipients. --- nixos/modules/mail.nix | 4 ++++ nixos/modules/mailman.nix | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 24d144c..88bc59e 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -184,6 +184,10 @@ in { } {"else" = false;} ]; + # The sieve script only handles the last RCPT TO command (https://stalw.art/docs/sieve/variables). + # Since we want it to run for every recipient, we need to accept them one at a time. :-( + # This setting throws a temporary error for the second RCPT TO command after which the HRZ retries in a new connection. + max-recipients = 1; }; data.script = "'redirects'"; }; diff --git a/nixos/modules/mailman.nix b/nixos/modules/mailman.nix index 1c8eaba..b090ef0 100644 --- a/nixos/modules/mailman.nix +++ b/nixos/modules/mailman.nix @@ -43,7 +43,11 @@ in { webHosts = [cfg.hostName]; serve.enable = true; # # Don't include confirmation tokens in reply addresses, because we would need to send them to HRZ otherwise. - settings.mta.verp_confirmations = "no"; + settings.mta = { + verp_confirmations = "no"; + max_recipients = "1"; # We can only send to one recipient at a time due to how forwarding currently works. See also the mail module. + max_sessions_per_connection = "1"; + }; }; }; -- 2.39.5