From 95f66f6210ac2ce4056d6f8f31bbb3efe14ccdd2 Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Feb 2025 16:09:44 +0100 Subject: [PATCH 1/8] Add mail forwarding based on alias files --- flake-module.nix | 6 ++ nixos/machines/kaalut/configuration.nix | 41 ++++++++++ nixos/machines/kaalut/koma.aliases.yaml | 48 +++++++++++ nixos/machines/kaalut/mathebau.aliases.yaml | 48 +++++++++++ nixos/machines/kaalut/mathechor.aliases.yaml | 48 +++++++++++ nixos/modules/mail.nix | 84 ++++++++++++++++++++ 6 files changed, 275 insertions(+) create mode 100644 nixos/machines/kaalut/koma.aliases.yaml create mode 100644 nixos/machines/kaalut/mathebau.aliases.yaml create mode 100644 nixos/machines/kaalut/mathechor.aliases.yaml diff --git a/flake-module.nix b/flake-module.nix index c30fff4..7bc32ef 100644 --- a/flake-module.nix +++ b/flake-module.nix @@ -53,6 +53,12 @@ _module.args.pkgs = import inputs.nixpkgs { inherit system; config.permittedInsecurePackages = ["jitsi-meet-1.0.8043"]; + + overlays = [ + (_: _: { + alias-to-sieve = inputs.alias-to-sieve.packages.x86_64-linux.default; # add custom package to convert alias files to sieve scripts on the stalwart machine + }) + ]; }; }; diff --git a/nixos/machines/kaalut/configuration.nix b/nixos/machines/kaalut/configuration.nix index ac9a08b..1b84e50 100644 --- a/nixos/machines/kaalut/configuration.nix +++ b/nixos/machines/kaalut/configuration.nix @@ -12,6 +12,28 @@ enable = true; # see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH 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; + virt_aliases = config.sops.secrets."mathebau.aliases".path; + } + { + domain = "mathechor.de"; + allowlistPass = config.sops.secrets."allowlistPass/mathechor".path; + virt_aliases = config.sops.secrets."mathechor.aliases".path; + } + { + domain = "koma89.tu-darmstadt.de"; + allowlistPass = config.sops.secrets."allowlistPass/koma".path; + virt_aliases = config.sops.secrets."koma.aliases".path; + } + ]; }; networking.hostName = "kaalut"; @@ -19,6 +41,25 @@ system.stateVersion = "24.05"; sops.secrets = { + # Virtual alias file + "mathebau.aliases" = { + sopsFile = ./mathebau.aliases.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0440"; + }; + "mathechor.aliases" = { + sopsFile = ./mathechor.aliases.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0440"; + }; + "koma.aliases" = { + sopsFile = ./koma.aliases.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0440"; + }; backupKey = { sopsFile = ./backupKey.yaml; owner = "root"; diff --git a/nixos/machines/kaalut/koma.aliases.yaml b/nixos/machines/kaalut/koma.aliases.yaml new file mode 100644 index 0000000..07329a4 --- /dev/null +++ b/nixos/machines/kaalut/koma.aliases.yaml @@ -0,0 +1,48 @@ +koma.aliases: ENC[AES256_GCM,data:8wzWdsJKBE4HdsBCVXrK460460aruzre8Eo/fXpTynxG4PpFK6TTSkRpD8JnkBuZO2+bB40bWe+vbT2tBXQxLvCiKR1QlwL3i1nJyIylMFYuRWn6yvxpW6wFF8Fqf9aw7FQ02NxG5ysdhUthgNkihF1B31uM9IpghQ==,iv:Cy6Axz1yFZbAn87HQTqg80yz8+PlVjrN5iGR1n5pQdU=,tag:gC2b8hg/hSNvPKaTehNH9Q==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBS283ZTdKVTVLaDRDV1N5 + SGhJQjJWdXJzc1l5OWtCWVdueTJMdjZpUjJzCmtUZFRYR0JXTW15Z0NyMktEbW5w + dkk1TjF0dVQ3MlFhNUFTbU0vMFdySWcKLS0tIDZPQmxSVGYzT2dDM244ek95dk9n + SnhtQWJic3B2YTM1ZlE3SHVRSjl1YVkKgUXW7JW3WSM5EusBoxQMsBRGwIqqi7Lo + DgWLq/P1rruuqRAS8hl4cht3jz6PlCJgVh2xpaM/kfkFS8ZuhVFw4g== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKdmcyM3hSUFdlM25UUndu + RUhzdEhsakdEdytBUGRyRTFXRzdYK2RBR0dnCmJqOTlvYkZkeld3eDYvRmRmUU5u + aHArR0FkZWRtT0hoNTZpS1JmaTRHencKLS0tIGVVSWN0NWQyQWdrcXdQUnQxUjdu + MWFZWVQ3RmZZS3FnRkJPdDRrOTZrWG8KVgFqfeBLw5gTBKugfnC4a5OLwOhosSgy + 3hXbGMrJiBDwOS+70H3L+IwiNSoJ6mL+ufShCTq8wER2L9GTteI8gg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzamM5TDVQM0hnZklsbncx + SlBMM0NpcnBBai94czV5WE1Md21EeE1kVXpFClpDVTRqYm5rWFhjVjRPQm1IVWxW + WTNlZFo4Y3VVNjZhckZ0RFVlQlV0OEEKLS0tIGJOR3k0OUorYTNXL01KQWJBUzVD + V0xidWR0SnBDM01hRlkrTlY4eEIrc1EK1Hye/jrQebkEDQ8muJpgHqBLefjnEJPF + GxdANetJLuZeeiOUjaUcbP6tecqZpiWN8fFEXrjNL4vnrHvJ+bR1aA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqQURCeGJBYytCdlhrWjF5 + c1ZrbEFENDF5bTNMaE52SE5CS1dVdWJCNlFzClZtK1QxOWY0dEVRRWY4MEtlZ1N1 + eGlaYXVLMUJiUi9FckdNcllBRCt4cmMKLS0tIEZuOTZQTm9vWHQ4Y3Z6RVloT0VL + OW5ZQWIvU2x1OEN6OW84K0dqRmhGNUUKOA3ugnG/ZD7m1DKrFjpZ8opPnjPtLaQx + t8qgGuQIoX6KeUb+YybRAOAPPzl51/m9GSUB43Eanm/tVJpdaew7/g== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-02-20T23:22:30Z" + mac: ENC[AES256_GCM,data:1Ts4BBsXZAfLyQiw0V0hipEClmCBI27IZe4p9cIKB7YpTxdHnoJs/k+Gb8QdEBiiud3quA7LwHeKCb0pMaCgC4/vyRYd8PuVH7fnP9ycVXGz71Kw3kt2qxq/M+lEco1V8he9fvRtipb+hWbpVi+9fGMrtX9d1yHK8xVauc9nYJw=,iv:/5UqWrCP9kJ4K47sZNneLLgJ/e8kio0cNvRO0rQFyDw=,tag:+tKB8o/h7lAcr3uEMLysNw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.4 diff --git a/nixos/machines/kaalut/mathebau.aliases.yaml b/nixos/machines/kaalut/mathebau.aliases.yaml new file mode 100644 index 0000000..f8fa3ed --- /dev/null +++ b/nixos/machines/kaalut/mathebau.aliases.yaml @@ -0,0 +1,48 @@ +mathebau.aliases: ENC[AES256_GCM,data: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,iv:gMs8Nq2+e7nrBSdeXz7Qp6MrtkvN6gYwLXuP1nm/Hy0=,tag:MLB5QxP2A7E6GwgZlI71FA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzQmE1dlVQSi9MRzZ1WGpR + dFYzZU8rR1V1VnQzUHB0VnFOckpIL2tvMzB3CnpXQXk0S0JNSkpNN0FMclBOdjFy + cFZYTjcrN2djbzBkZUFmNCtXS3lRM0EKLS0tIFB2V2FoMU5rZzlxQW5SSHhlZkNx + c1BCVEV4dEU4aE5YeDZMRlFyVHYyQ1EK+znjkJ/JuE5VgYUpkCfDCZV5mFmSXUxU + MtByksmGshA8oyk0SH6B+qg07yDh+jRn4gtvnTxxudtqcVf5EX0vcg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0MUhyeCs3Qjl6RmIwVHN1 + cHBQMFEvQU1ZTFE0d0lESXgya3FZRW01cjJJCnNPNGgrVmhYeWhlOTZMYjdyd0Fm + QzJwQ25IOUJOeXpxbC85YlJlTElia00KLS0tIHdHL20yakxaNy9CZmUyaHVUSmxZ + SkZhM3ByQ2o3a0pVZnV2M2lob2xRU1UK14PKZz5blclSkUVJwUFm+A9G5nPD0U0h + AH2kt/kdSxj+0I6uWrD+0KHh8KA0Tgp9Auyv/UF1dB9MoiuQPG15vg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrOVFHcloyYW5OK2d1eXJt + NWxLWitrUWdwd0J6R1phaFA1Z2FUV0ROdFhNClg4bG5WSW8zWTdsWGhQUGFySS8w + UFpjK3dzYjdPVTNsbFg0YVl0UnQ3WmMKLS0tIFhBODRqK25TVWpabTVteTRtSURO + NTdYNkFuSm9xVi9QME5DMkRqOUpJYk0KK0e8LjmPqPQD1FzXyAuoUY1d8u//WHvT + S4ijZF8udwPzKTIHd5OiQVfCdmVughKmmRwQEHdFC69fjn6wOqLJhw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUa2VYR0RZa0pOSFljVzgz + TS9aRW9OZ2hEV3pWbncyNlp2c0REZk1GRndvClk5U3l5b0dlcktkRXZBa3VPaWpU + ZmVuS3UwV3RmbzdQWC9qYXpCNnJpODQKLS0tIGNabjdpYXp4d2VyMEcxSXhHdGNr + Y21YcmlWTkJDRUh3czJEUWVGaG44cXMKoibsYSOYv329WNzktBVJ18aGAMXCxz3B + c9938x3U7BCsSatnNch/cTbxPFYt8GhgAXXZb8/vsT9URH+9/K2iuA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-01-05T13:45:59Z" + mac: ENC[AES256_GCM,data:wESfYT9AJDcOKI4QSzXLi844ILNtDa1APlcvhNHfu80mS6JFXifUgbOV8YW9D6TA7X/NIhdpiIiDt2bdmK9GJbSrbNJH1yz5Pm4nEabVdHCU5aJKtlagxkNwzfHfDaRznM6NQTdIFDqsaSSokKYyZiycNOMdisQ5JpbYYig/KTM=,iv:GaYceaZ0drzimn/TTXPBP2Zt81w6YPLNf1oqRtkWt/8=,tag:ptEQRoIsBVSBqSdg1XdLsA==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.2 diff --git a/nixos/machines/kaalut/mathechor.aliases.yaml b/nixos/machines/kaalut/mathechor.aliases.yaml new file mode 100644 index 0000000..55872b1 --- /dev/null +++ b/nixos/machines/kaalut/mathechor.aliases.yaml @@ -0,0 +1,48 @@ +mathechor.aliases: ENC[AES256_GCM,data:VKEGY6KVtgKApnV7N2e2cqy9erDWQ2fb88Gwcpp5th/t0VGp16KGDtGiuQXhY80j6dDIcQMd9bLHzqAzc4+i/WhmEPhiXUkGiEKuarMfvqNl1LBlXFCoIrUXMMSIqab9q+fE3ignVQapE/YZt9aniyvg1prcmBcwIy9rDoHkiTY006ux5CM+vX0F60ADX8Nf6Qmn/JncPxXgq2jYsBxjXPj7BwJaair/+nxrbVf0,iv:Elj1NDeR1fdIIjIbjvkV3BmcVAKjwdMfknuNxMXJsa4=,tag:AkXWQ8sTMLsd7a+MfRcF/w==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjMlRsWnkrREVaQitsWHMy + WHZFVG1qN25QbWFHcUxNS1Z0SFRDd1oxeG5RCi8wNUhkeWh2VjI4ZGowM1ExaExh + SE1yVGFTUHZadUdDL3pxaGdKTHQ0VTgKLS0tIHVNM2xlOFNNS3dFalJqZUtPODRn + b2NOTHpXSUVyaFRJNG5ONCt0TTVjOEkKYld7KN995QxdrGBVRYgCxO7kGwsiq+cp + iQJTjMdoFygIrTkgE5Rj89/GCiVe0+yAWJuQF7PEnC3cyq0M1g+fzw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPRFJCeXhwQVFSWmgzNHBu + SHlTTGtiRkI5bmhKa1B0QTZMY3FERmlUd0FBCk1vOUpydEFZUExpR2hpWm9mRHpE + dk9MQ042K0FpSVJ3dUlQcktGT2k1VjAKLS0tIHpGRmwzNE01YkV1TW94RkNmMjN4 + YnNXZUlta3NMVW9Cc3V2T0t4R01RSlkKNTW3gnF49BuPwF3jwciOYThJe+gJa0a6 + WKYt+aJuHi0a4y5rS/wfttij+hS5vYVNOrgfJ5bGinkNuAygA2hMOg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6MjZOR1dwb3RjZnlNNW4v + SzJnT1BRVktWNDI5S2Z2NnhQQzdNeS9ralI0CnN0SU9ESEV3ZCtRQmpZK3VZOGYx + Y3FVUy9zY3RZcGxyVmttVzFJL1haYWsKLS0tIENGRW1KZkpUdldOZWgzSXVoenpX + dTVpNUpWallSTzJ3cEZJTXk3c2t1czgKzJCwhMspzAsjzwSRdSPUoseEAsKp8HFy + cL9if92ar68HMHTdoy0Zvy+5AbxKUxgXZ2t8cDgkL8bNG5Ri2xYaUA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtNm5xUGkrK1dYd2ZtamFW + NXpNMEtvNTl3U3MzeVNSbVJOdGdlWGsxRHlZCllQVmNtYzBJNDc2Y0dmUlNsbTF5 + RHB4QWZ1VGNFVkx1Q0hNK3FDTTRrUlkKLS0tIG9hbldDeHk0YmVZV2IwMXNpYStU + Q29uVHBCb2pTeWVJVmVXbWpycnFneWMKnDmu5917dddV8vjO0L8OP3wXMjDi46Ro + b9eOY8l74jm4sTxyKNvnkEjD6iHn1t7f8J7HAbWrpZY+J0i77nrzQw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-23T09:05:51Z" + mac: ENC[AES256_GCM,data:Xnulo0681LtgH9SZt9DL3nd9bSDH+TCQDvbKdggVBJ66rxBiKmlbu5MAblAWqxbdZ6EelldaVeX9OaL2rYJoYbTWxzw2iuPieldp3Ah3PsTI2C8W+UD9KVHcB+3AMOmVmJZzFlZvTwyfPfZRNNb0HAijkN97P3fP0r1Iqf3YjiI=,iv:vhu38HM4e+PyyChXvI87LWSGtKQQiXUr4MKrI7kotzk=,tag:eNuQD74kUO+duqEXNbLJBw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index d4fa331..45db3e1 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -1,4 +1,6 @@ /* +* Forwarding mails: Update the Sops-secrets in the machine directory, rebuild on the VM and deploy. +* Everything else should happen automatically but new redirects might take up to two hours due HRZ infrastructure. * Using the web admin interface: Set your SSH to do portforwarding of some local port to port 80 of the VM and * and use your personal admin account or create one using the fallback admin password. * Create users with mail boxes: Go to the admin interface and create them. @@ -9,6 +11,7 @@ { config, lib, + pkgs, ... }: let inherit @@ -26,6 +29,25 @@ in { type = str; description = "String containing the hashed fallback admin password"; }; + domains = mkOption { + type = listOf (lib.types.submodule { + options = { + domain = mkOption { + description = "Domain name that we serve. We also push its addresses to HRZ."; + type = strMatching "^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$"; #Regex from https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch08s15.html + }; + allowlistPass = mkOption { + description = "Password file for the HRZ API that gets a list of mailaddresses that we serve"; + type = path; + }; + virt_aliases = mkOption { + description = "File path to a virtual alias file applicable for this domain"; + type = path; + default = "/dev/null"; # there might not be an alias file and reading an empty one works with our implementation + }; + }; + }); + }; }; config = mkIf cfg.enable { @@ -127,6 +149,32 @@ in { ]; }; + # 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 + # 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. + config.local-keys = + [ + "store.*" + "directory.*" + "tracer.*" + "server.*" + "!server.blocked-ip.*" + "authentication.fallback-admin.*" + "cluster.node-id" + "storage.data" + "storage.blob" + "storage.lookup" + "storage.fts" + "storage.directory" + "lookup.default.hostname" + "certificate.*" + ] # the default ones + ++ ["sieve.trusted.scripts.*"]; #for macros to be able to include our redirection script + sieve.trusted.scripts.redirects.contents = "%{file:/tmp/virt_aliases}%"; # generated redirect script + session.data.script = "'redirects'"; + authentication.fallback-admin = { user = "admin"; # see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH @@ -149,6 +197,42 @@ in { files = ["/root/.ssh/known_hosts"]; # for the backup server bragi }; + systemd = { + services = { + "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 + }; + "virt-aliases-generator" = { + description = "Virtual Aliases Generator: Generate a sieve script from the virtual alias file"; + script = lib.strings.concatStringsSep "" (["${pkgs.alias-to-sieve}/bin/alias_to_sieve "] ++ map (x: "${x.virt_aliases} ${x.domain} ") cfg.domains ++ ["> /tmp/virt_aliases"]); + wantedBy = ["stalwart-mail.service"]; # Rerun on stalwart restart because forwardings may have changed. + serviceConfig = { + Type = "oneshot"; + User = "stalwart-mail"; + NoNewPrivileges = true; + # See https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html + PrivateTmp = false; + ProtectHome = true; + ReadOnlyPaths = "/"; + ReadWritePaths = "/tmp"; + InaccessiblePaths = "-/lost+found"; + PrivateDevices = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + }; + }; + }; + }; # Backups services.borgbackup.jobs.mail = { paths = [ From 14ee694ed6cc167097c62c7c9f42aad006824018 Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Feb 2025 16:16:12 +0100 Subject: [PATCH 2/8] Post mailaddresses to HRZ allowlist --- nixos/machines/kaalut/allowlistPass.yaml | 52 +++++++++++++++++++++ nixos/machines/kaalut/configuration.nix | 22 ++++++++- nixos/machines/kaalut/stalwartAdmin.yaml | 48 ++++++++++++++++++++ nixos/modules/mail.nix | 57 ++++++++++++++++++++++++ 4 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 nixos/machines/kaalut/allowlistPass.yaml create mode 100644 nixos/machines/kaalut/stalwartAdmin.yaml diff --git a/nixos/machines/kaalut/allowlistPass.yaml b/nixos/machines/kaalut/allowlistPass.yaml new file mode 100644 index 0000000..4d60823 --- /dev/null +++ b/nixos/machines/kaalut/allowlistPass.yaml @@ -0,0 +1,52 @@ +allowlistPass: + matheball: ENC[AES256_GCM,data:4y83ZJ4=,iv:+B1hTSGs5cskmUA9gLpRHPjhxzvwOrplB+lIbNUKtz4=,tag:ZsKA2A4ltbI3px1Z16EgvA==,type:str] + mathebau: ENC[AES256_GCM,data:ZlIv0MrCVtsyF3t9Gr/zcg==,iv:ZdBlnx4/zQZjT75ssB0osfDlWVerUe6yvwbMxlXpHZs=,tag:ytlNq7zP2WtPafcSQFZ6RQ==,type:str] + mathechor: ENC[AES256_GCM,data:d5KyoD/P8/j+poJSGF1nDA==,iv:ayKtvj4EEqUtMLi/7njbxuUql1A58WNi729svHtZju4=,tag:JqWoxxMN5mVN+gaQTmBv1Q==,type:str] + koma: ENC[AES256_GCM,data:bB7px1n5q1+++sctsmIMJg==,iv:DIJGpC9+JyFv3SU9dBVLdnEkRlZzY7DBRAL4zXSbpec=,tag:WaZUGvYtm+5ys2RsBNILog==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpWW9FZHEwejRaRER1MHJQ + VXgyaE1GQmhhNFh1dEtBNjRnZXVqWm5hV25vCjliank4KzFobEZtbitzaXBhT1F6 + cCtqeVorS1BLMmMzZkVVOEN6NERFdDAKLS0tIGkzUUt1NnBUWUJWTy9Pd2FIeTF0 + cDVaUHowSEpoRjR3Zm81Z1p5NlYzV1kKMRvC7+3TS5EKjWg/NPnbwvVIikxf+Bpa + zNo9jhw3GREMScBXOiarm+xgMZ1e2SRrLrUwfR4DiXI4uvg1Jk/tPg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRYk1LQTVDNGhHWXJZSmsy + NEZ0WTNlek4yVnRwL3BKNXYrcm84SzIvNlRZCjlDdXU1a2NRNUVHZmkyK2ltZ3pE + bmtmVE5TR1hBcVNhaTBGK2F6VWZ1d2MKLS0tIDVKcXhDbjBncFlsR3FzanRhWWQv + Um1jcExjN2RWbHhzY2ZpcWVTWE1IbHMKfRSAmfbk+JDWdhSTSg9GZ+lws5DOHv9T + ZO9nQV37X9zFD6sXDWaspG3sf4kJZUCbWjCTKyQL/xmh4+E8+CAXYw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzOXBwTUF3ZXJCTFJOQjVC + bGplRDRCQVhtUEJPcnhENEF3UVVnbmVKNnprCjFOZW94ajI2d21RamZKT0xFMmtZ + ZzZFYjg3WDBmOVhlaFZyOW83M1NYVXcKLS0tIGltWUJGczNJS0pWTmxaZHU5Wi9t + TDRCdStocXRvLzBPUTd2blZFV0IyblkKjufZg39n/TI6BhGhIFNz4jplUx6u3/bo + NMbr9uJy/I1sdlfGNaheG/TIGOgFG1KqGkGdwpisU3gUD9uMUo1dvw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzdDdsdW44ZlQyMzdJNmsv + aTIzVWRoSDhzamlqTDFOemZlc1JQMFdZbFJNCmVZbDVVaDBSVi8yTkdOQ1UySy9X + MlhXTzRvNWtqUzQxTlNqQ2RlN2J1OXMKLS0tIC9aZEZMVkFybnRTQmhpM1dzc1lt + bDdvdHc3Y1NmeE5WUzl3cXVRc3pmOUkK+9WueS1wDQDJlenec4jJCfynbPnuOFYR + HFsWmvEZJ+XhH6N9Q0phCHQgZGiR67FH6CHkCblmb6ZfZcWSEe1oTg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-01-05T13:49:19Z" + mac: ENC[AES256_GCM,data:i7t/Hb5aW0lIvPLk84geQ792uUGP25vX8FC7kK/3H19tz5i4zsIcvl1d+oB5gJ004gP5pRogcuKL1xHUUl+A0UXXNzRpxc0BBVZaxnIhjfPunORbmZeJQRP298tQpvYYqI/pGhjrlit37U9jecGf1l12Cgv97sGW42d2F+S2Soc=,iv:My21fMF3SEr6mg2+eh8KA6B8tzmQVEDy2BG3hfkafrU=,tag:xdU6j8ti8Z68rbiRxkj7Pw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.2 diff --git a/nixos/machines/kaalut/configuration.nix b/nixos/machines/kaalut/configuration.nix index 1b84e50..2134b42 100644 --- a/nixos/machines/kaalut/configuration.nix +++ b/nixos/machines/kaalut/configuration.nix @@ -10,6 +10,7 @@ # System configuration here services.mathebau-mail = { enable = true; + stalwartAdmin = config.sops.secrets.stalwartAdmin.path; # see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH stalwartAdminHash = "$argon2i$v=19$m=4096,t=3,p=1$d0hYOTkzclpzSmFTZUplWnhVeWE$I7q9uB19RWL0oZKaPlMPSlGfFp6FQ/vrx80FFKCsalg"; domains = [ @@ -40,7 +41,19 @@ vmNetwork.ipv4 = "192.168.0.17"; system.stateVersion = "24.05"; - sops.secrets = { + sops.secrets = let + allowlistSops = { + sopsFile = ./allowlistPass.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0400"; + }; + in { + # Password for the HRZ API that gets a list of mailaddresses that we serve + "allowlistPass/matheball" = allowlistSops; + "allowlistPass/mathebau" = allowlistSops; + "allowlistPass/mathechor" = allowlistSops; + "allowlistPass/koma" = allowlistSops; # Virtual alias file "mathebau.aliases" = { sopsFile = ./mathebau.aliases.yaml; @@ -60,6 +73,13 @@ 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.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0400"; + }; backupKey = { sopsFile = ./backupKey.yaml; owner = "root"; diff --git a/nixos/machines/kaalut/stalwartAdmin.yaml b/nixos/machines/kaalut/stalwartAdmin.yaml new file mode 100644 index 0000000..9fb24d8 --- /dev/null +++ b/nixos/machines/kaalut/stalwartAdmin.yaml @@ -0,0 +1,48 @@ +stalwartAdmin: ENC[AES256_GCM,data:4vpvxtFa2KiF3ojl+cw3ic/MI7UM9JQCQn76bidYvbW31zgF,iv:DtLAi68oQRf3U69uFK0Cz4qHMkxM6NnB3lVYft/DtqQ=,tag:HYm2mdpTuXNHdQIv2Rkwig==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxcTRqZXRoNTJCdFhQUG9o + Qmx2cVl0TWdaQzZZUThTOEpQdjIxVFh3eHhzCjlHWHhSYmM1ajYrdjl3Nm90TkRh + YWE3c0hJYzdFWXpZUGI0cHBQdThSWWsKLS0tIFh5M20wV2ZZbzllS1BNOGtaRUVF + MFN3bENrZ0tDMllJM1E5MWkyZ2thZEkKfZlUzE5t8K0oHZYOSVItvRJZP2MJlA7N + SLozGlpwCoZKWP6qAqP5jisTG/npQRhcqwkd7P39EytO2HXU9m8sJA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkVldRVmtPUzFxV0ltK0d2 + SHRqbXZCTW5wZUtZM0ZkL3lXOEJmVXdjMXdZCjE5MUUrSEhnWHRSOVhtWWQxdndv + ckUzTFl4ZXM5VHBTRlY3SzVsZWpxNUEKLS0tIEtpbTBhaWR1c3RhSW5nclZvMTdO + eTBYL1Q5cXNvTGkvQzJMWHZHaEZseVUK5w2MPZMquT0luq+tl2owLrrSBx9KPskS + FupcAZTcCo+YsemKLjJ6GlHch5x8Mw98NHS5h1AKxwZYtcfwg3lfbQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpUitNeHNWOTVjWkF4YWhB + MnEwWDFnT0wyNUx3VmlQMmZTRmZRbXBGOVFvCmpoOHZZSXRweUtZaHZ6azF2Q3dK + NFBwa242U3JSVjhtOUlRTUZuakhkcXcKLS0tIEN5TGhMRFphdEpvcU5zTmVlTTJN + d2JRc2p4YmpuUHAycUoxc1FuZmxhemcKOgGyieFVS57tsvUtVooahqswYZH0Fi6+ + jxM6Ga/tIM/bZ/qSwYrNlNiz0XHm8/XFH2s8sxypDZ+NHGLs3zGjsw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBERTdvSTZ3eEVNbEZpUnQ2 + ZC85blRQVzgrckljcnZPeVhZWUxGd01tankwCjBCZHdWRnpoZkdRQWdoK0VmOFVy + VmpiOFkvNisrWmp2NE1kalB4dUhzdWsKLS0tIEJ6T1FsTFlIMUVWd3FwbEtldmlC + UjFHWHNZci8zRlFXNVpNNk5oSUNvaTQKW9T88GflSysJwqMnBrc/jZVwL/fRdg2a + 5XysXb/dCo4uNxLQit/KNSpINj7rAkf4Pk819DO6SKiIiuIJDXw9cA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-23T11:43:23Z" + mac: ENC[AES256_GCM,data:GZ1Q67n43WU3fDQd6SGsD2EZgoaq1mzh5biy42cx6FQWlveK5lhb0F2HUuWWv5zSHKpslEPD6odvkQmMNCRY8NsvT3+KBAnHHU0aHzM9AEV27cDL4x6oBvO52EMxsNCMm+fXPD1CubQxfbfvx/aIuqb1sovgKGgwf4u6yqIrHJ0=,iv:ExX+ySMXhF/c1w2IP7y8mdlcy8W9Zxiy6X67b2f4AeY=,tag:shxQJdaW3HsG6sNY+zDNCA==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 45db3e1..77b058a 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -25,6 +25,10 @@ in { options.services.mathebau-mail = { enable = mkEnableOption "mathebau mail service"; + stalwartAdmin = mkOption { + type = path; + description = "Path to a file that contains the stalwart fallback admin password encoded for HTTP Basic Auth"; + }; stalwartAdminHash = mkOption { type = str; description = "String containing the hashed fallback admin password"; @@ -198,7 +202,60 @@ in { }; systemd = { + timers."mailAllowlist" = { + wantedBy = ["timers.target"]; + timerConfig = { + OnBootSec = "1h"; # Run every hour + OnUnitActiveSec = "1h"; + RandomizedDelaySec = "10m"; # prevent overload on regular intervals + Unit = "mailAllowlist.service"; + }; + }; services = { + "mailAllowlist" = { + description = "Allowlist update: Post the mail addresses to the HRZ allowllist"; + script = let + scriptTemplate = { + domain, + allowlistPass, + ... + }: '' + 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. + ${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 + # 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 + ${pkgs.curl}/bin/curl -s https://www-cgi.hrz.tu-darmstadt.de/mail/whitelist-update.php -F emaildomain=${domain} -F password=$(cat ${allowlistPass}) -F emailliste=@/tmp/addresses -F meldungen=voll + # Cleanup submission file + rm /tmp/addresses + ''; + in + lib.strings.concatStringsSep "" (map scriptTemplate cfg.domains); + serviceConfig = { + Type = "oneshot"; + User = "stalwart-mail"; + NoNewPrivileges = true; + # See https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html + PrivateTmp = false; # allow access to sieve script + ProtectHome = true; + ReadOnlyPaths = "/"; + ReadWritePaths = "/tmp"; + InaccessiblePaths = "-/lost+found"; + PrivateDevices = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + }; + }; "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 From 76726f588fcf2a0a8cb2890a3012a018abe2d5b5 Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Feb 2025 16:19:10 +0100 Subject: [PATCH 3/8] Add patch to allow alias files to redirect to their sender --- flake-module.nix | 38 ++++++++++++++++++++++++++++++++++++-- nixos/modules/mail.nix | 4 ++++ patches/sieve-rs.patch | 27 +++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 patches/sieve-rs.patch diff --git a/flake-module.nix b/flake-module.nix index 7bc32ef..7559834 100644 --- a/flake-module.nix +++ b/flake-module.nix @@ -1,4 +1,8 @@ -{inputs, ...}: { +{ + inputs, + lib, + ... +}: { # debug = true; # We only define machines config in this flake yet, so we only include # the module that builds these. This file might get fuller, if we need to @@ -55,8 +59,38 @@ config.permittedInsecurePackages = ["jitsi-meet-1.0.8043"]; overlays = [ - (_: _: { + (_: prev: { alias-to-sieve = inputs.alias-to-sieve.packages.x86_64-linux.default; # add custom package to convert alias files to sieve scripts on the stalwart machine + stalwart-mail = assert lib.assertMsg (prev.stalwart-mail.version == "0.11.6-unstable-2025-02-04") '' + 1. If the bug https://github.com/stalwartlabs/sieve/issues/11 is resolved to our satisfaction, try to remove this overlay. + 2. Check whether sieve-rs recieved new updates that our patch needs to be rebased upon. + 3. Check whether the sieve-rs patch below that exchanges the dependency needs updates. + 4. Then update the version comparison in this assert statement. + 5. Update the `cargoHash` by setting it to `lib.fakeHash` and then inserting the result. + 6. Check if we can get rid of alias-to-sieve when stalwart-mail has a builtin alias feature. + ''; + prev.stalwart-mail.override ( + let + rp = pkgs.rustPlatform; + in { + rustPlatform = + rp + // { + buildRustPackage = args: + rp.buildRustPackage ( + args + // rec { + cargoPatches = [ + # Let stalwart-mail depend on our own version of the sieve crate that does not have some “loop prevention” that disables redirects to the original sender. + # We want to redirect to sender if we simulate alias files and not doing so barely prevents loops in my opinion. + ./patches/sieve-rs.patch + ]; + cargoHash = "sha256-gb2oFlVA/vE6DoWWW8SCFA3l7rtV2RuosPUY+6IcKNM="; + } + ); + }; + } + ); }) ]; }; diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 77b058a..f1861a2 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -1,4 +1,8 @@ /* +* Building: We patch our version of stalwart and thus need to built it locally. +* Be aware that this needs some hours, about 12Gb RAM and a few Gb free space in /tmp. +* If you only want to deploy configuration changes and no software updates, consider building on the target VM. +* It has stalwart in its nix store and does not need to rebuild it. * Forwarding mails: Update the Sops-secrets in the machine directory, rebuild on the VM and deploy. * Everything else should happen automatically but new redirects might take up to two hours due HRZ infrastructure. * Using the web admin interface: Set your SSH to do portforwarding of some local port to port 80 of the VM and diff --git a/patches/sieve-rs.patch b/patches/sieve-rs.patch new file mode 100644 index 0000000..b706d03 --- /dev/null +++ b/patches/sieve-rs.patch @@ -0,0 +1,27 @@ +diff --git a/Cargo.lock b/Cargo.lock +index be36759b..b4316639 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -6404,8 +6404,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] + name = "sieve-rs" + version = "0.6.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "15ac54053752c25a0e545dd1953de716abcc80b12cfe0b6c2f2c1c73759d4f45" ++source = "git+https://gitea.mathebau.de/fachschaft/sieve-rs.git#71324550504c0f84fe3e814d05cbe22f90a3b228" + dependencies = [ + "ahash 0.8.11", + "bincode", +diff --git a/Cargo.toml b/Cargo.toml +index f055474f..2b64c9ac 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -63,3 +63,7 @@ incremental = false + debug-assertions = false + overflow-checks = false + rpath = false ++ ++ ++[patch.crates-io] ++sieve-rs = { git = 'https://gitea.mathebau.de/fachschaft/sieve-rs.git' } + From f5374c3e8005b8447679d59e96826185e6ab98ab Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Feb 2025 16:22:31 +0100 Subject: [PATCH 4/8] Submit mailing list mails to correct vm based on port forwarding and run allowlist job less often --- nixos/modules/mailman.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nixos/modules/mailman.nix b/nixos/modules/mailman.nix index 5cfa63d..f4ecd0e 100644 --- a/nixos/modules/mailman.nix +++ b/nixos/modules/mailman.nix @@ -35,7 +35,7 @@ in { proxy_interfaces = "130.83.2.184"; smtputf8_enable = "no"; # HRZ does not know SMTPUTF8 }; - relayHost = "192.168.0.24"; # Relay to eihort which relays to HRZ (see https://www.hrz.tu-darmstadt.de/services/it_services/email_infrastruktur/index.de.jsp) + 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) }; mailman = { enable = true; @@ -64,9 +64,9 @@ in { systemd.timers."mailAllowlist" = { wantedBy = ["timers.target"]; timerConfig = { - OnBootSec = "5m"; # Run every 5 minutes - OnUnitActiveSec = "5m"; - RandomizedDelaySec = "2m"; # prevent overload on regular intervals + OnBootSec = "1h"; # Run every hour + OnUnitActiveSec = "1h"; + RandomizedDelaySec = "10m"; # prevent overload on regular intervals Unit = "mailAllowlist.service"; }; }; From 8e909b497d7c30c52c328118eb1e2bf43424a4fd Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Feb 2025 16:09:44 +0100 Subject: [PATCH 5/8] Add mail forwarding based on alias files --- flake-module.nix | 6 ++ nixos/machines/kaalut/configuration.nix | 41 ++++++++++ nixos/machines/kaalut/koma.aliases.yaml | 48 +++++++++++ nixos/machines/kaalut/mathebau.aliases.yaml | 48 +++++++++++ nixos/machines/kaalut/mathechor.aliases.yaml | 48 +++++++++++ nixos/modules/mail.nix | 84 ++++++++++++++++++++ 6 files changed, 275 insertions(+) create mode 100644 nixos/machines/kaalut/koma.aliases.yaml create mode 100644 nixos/machines/kaalut/mathebau.aliases.yaml create mode 100644 nixos/machines/kaalut/mathechor.aliases.yaml diff --git a/flake-module.nix b/flake-module.nix index c30fff4..7bc32ef 100644 --- a/flake-module.nix +++ b/flake-module.nix @@ -53,6 +53,12 @@ _module.args.pkgs = import inputs.nixpkgs { inherit system; config.permittedInsecurePackages = ["jitsi-meet-1.0.8043"]; + + overlays = [ + (_: _: { + alias-to-sieve = inputs.alias-to-sieve.packages.x86_64-linux.default; # add custom package to convert alias files to sieve scripts on the stalwart machine + }) + ]; }; }; diff --git a/nixos/machines/kaalut/configuration.nix b/nixos/machines/kaalut/configuration.nix index ac9a08b..1b84e50 100644 --- a/nixos/machines/kaalut/configuration.nix +++ b/nixos/machines/kaalut/configuration.nix @@ -12,6 +12,28 @@ enable = true; # see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH 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; + virt_aliases = config.sops.secrets."mathebau.aliases".path; + } + { + domain = "mathechor.de"; + allowlistPass = config.sops.secrets."allowlistPass/mathechor".path; + virt_aliases = config.sops.secrets."mathechor.aliases".path; + } + { + domain = "koma89.tu-darmstadt.de"; + allowlistPass = config.sops.secrets."allowlistPass/koma".path; + virt_aliases = config.sops.secrets."koma.aliases".path; + } + ]; }; networking.hostName = "kaalut"; @@ -19,6 +41,25 @@ system.stateVersion = "24.05"; sops.secrets = { + # Virtual alias file + "mathebau.aliases" = { + sopsFile = ./mathebau.aliases.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0440"; + }; + "mathechor.aliases" = { + sopsFile = ./mathechor.aliases.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0440"; + }; + "koma.aliases" = { + sopsFile = ./koma.aliases.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0440"; + }; backupKey = { sopsFile = ./backupKey.yaml; owner = "root"; diff --git a/nixos/machines/kaalut/koma.aliases.yaml b/nixos/machines/kaalut/koma.aliases.yaml new file mode 100644 index 0000000..bd3dd9d --- /dev/null +++ b/nixos/machines/kaalut/koma.aliases.yaml @@ -0,0 +1,48 @@ +koma.aliases: ENC[AES256_GCM,data:r9dJzjUrv9BBr6emtHuIm71OamwTQdxdAbWuh62ZPG/tbvg8YimMvUno1WXn6EXn+0q2Gf+r4UiB6RJLD62D+JU+lEAKg9LKfX+578M4eCIbwRqkHWQYAtT/V3nB8L7/dqcvdatF90+50w==,iv:SL13OY8XUNdVBkZlKBfqwzT5LTtZcykyGIK+nHHOa10=,tag:Yyu2/ZqLotmFD+cMwtXYlA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBS283ZTdKVTVLaDRDV1N5 + SGhJQjJWdXJzc1l5OWtCWVdueTJMdjZpUjJzCmtUZFRYR0JXTW15Z0NyMktEbW5w + dkk1TjF0dVQ3MlFhNUFTbU0vMFdySWcKLS0tIDZPQmxSVGYzT2dDM244ek95dk9n + SnhtQWJic3B2YTM1ZlE3SHVRSjl1YVkKgUXW7JW3WSM5EusBoxQMsBRGwIqqi7Lo + DgWLq/P1rruuqRAS8hl4cht3jz6PlCJgVh2xpaM/kfkFS8ZuhVFw4g== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKdmcyM3hSUFdlM25UUndu + RUhzdEhsakdEdytBUGRyRTFXRzdYK2RBR0dnCmJqOTlvYkZkeld3eDYvRmRmUU5u + aHArR0FkZWRtT0hoNTZpS1JmaTRHencKLS0tIGVVSWN0NWQyQWdrcXdQUnQxUjdu + MWFZWVQ3RmZZS3FnRkJPdDRrOTZrWG8KVgFqfeBLw5gTBKugfnC4a5OLwOhosSgy + 3hXbGMrJiBDwOS+70H3L+IwiNSoJ6mL+ufShCTq8wER2L9GTteI8gg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzamM5TDVQM0hnZklsbncx + SlBMM0NpcnBBai94czV5WE1Md21EeE1kVXpFClpDVTRqYm5rWFhjVjRPQm1IVWxW + WTNlZFo4Y3VVNjZhckZ0RFVlQlV0OEEKLS0tIGJOR3k0OUorYTNXL01KQWJBUzVD + V0xidWR0SnBDM01hRlkrTlY4eEIrc1EK1Hye/jrQebkEDQ8muJpgHqBLefjnEJPF + GxdANetJLuZeeiOUjaUcbP6tecqZpiWN8fFEXrjNL4vnrHvJ+bR1aA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqQURCeGJBYytCdlhrWjF5 + c1ZrbEFENDF5bTNMaE52SE5CS1dVdWJCNlFzClZtK1QxOWY0dEVRRWY4MEtlZ1N1 + eGlaYXVLMUJiUi9FckdNcllBRCt4cmMKLS0tIEZuOTZQTm9vWHQ4Y3Z6RVloT0VL + OW5ZQWIvU2x1OEN6OW84K0dqRmhGNUUKOA3ugnG/ZD7m1DKrFjpZ8opPnjPtLaQx + t8qgGuQIoX6KeUb+YybRAOAPPzl51/m9GSUB43Eanm/tVJpdaew7/g== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-02-25T17:41:29Z" + mac: ENC[AES256_GCM,data:lZ9AXtJzVuc8Jg9L0aGhS18cs8pTjOG/xNP2tG25/7/PEdEV1SNwbxubGQOFAHrNbiDbmJMKJq96mhV8e3tHszlrzQnU1uyu9MrWiAYwV3CjmwSqC4J9ezSm/AY9e9+OWKn6sb4RVsz9A7aDGUhhoZMycnPNRKlpTuzdTIJK98o=,iv:LxSsZoHkJ2HFXBLWkw+SUb/LYW2ciE1DtzpoV4YLOwQ=,tag:QeYmreRGZk4PqlLWJLLD8g==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.4 diff --git a/nixos/machines/kaalut/mathebau.aliases.yaml b/nixos/machines/kaalut/mathebau.aliases.yaml new file mode 100644 index 0000000..a4d15fa --- /dev/null +++ b/nixos/machines/kaalut/mathebau.aliases.yaml @@ -0,0 +1,48 @@ +mathebau.aliases: ENC[AES256_GCM,data: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,iv:2jIbgMhGa8GWlDQeQNuAOrxiC03V7sdfy8EorUcjP5M=,tag:8/owPwtrW4khSqCraE+PDQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzQmE1dlVQSi9MRzZ1WGpR + dFYzZU8rR1V1VnQzUHB0VnFOckpIL2tvMzB3CnpXQXk0S0JNSkpNN0FMclBOdjFy + cFZYTjcrN2djbzBkZUFmNCtXS3lRM0EKLS0tIFB2V2FoMU5rZzlxQW5SSHhlZkNx + c1BCVEV4dEU4aE5YeDZMRlFyVHYyQ1EK+znjkJ/JuE5VgYUpkCfDCZV5mFmSXUxU + MtByksmGshA8oyk0SH6B+qg07yDh+jRn4gtvnTxxudtqcVf5EX0vcg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0MUhyeCs3Qjl6RmIwVHN1 + cHBQMFEvQU1ZTFE0d0lESXgya3FZRW01cjJJCnNPNGgrVmhYeWhlOTZMYjdyd0Fm + QzJwQ25IOUJOeXpxbC85YlJlTElia00KLS0tIHdHL20yakxaNy9CZmUyaHVUSmxZ + SkZhM3ByQ2o3a0pVZnV2M2lob2xRU1UK14PKZz5blclSkUVJwUFm+A9G5nPD0U0h + AH2kt/kdSxj+0I6uWrD+0KHh8KA0Tgp9Auyv/UF1dB9MoiuQPG15vg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrOVFHcloyYW5OK2d1eXJt + NWxLWitrUWdwd0J6R1phaFA1Z2FUV0ROdFhNClg4bG5WSW8zWTdsWGhQUGFySS8w + UFpjK3dzYjdPVTNsbFg0YVl0UnQ3WmMKLS0tIFhBODRqK25TVWpabTVteTRtSURO + NTdYNkFuSm9xVi9QME5DMkRqOUpJYk0KK0e8LjmPqPQD1FzXyAuoUY1d8u//WHvT + S4ijZF8udwPzKTIHd5OiQVfCdmVughKmmRwQEHdFC69fjn6wOqLJhw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUa2VYR0RZa0pOSFljVzgz + TS9aRW9OZ2hEV3pWbncyNlp2c0REZk1GRndvClk5U3l5b0dlcktkRXZBa3VPaWpU + ZmVuS3UwV3RmbzdQWC9qYXpCNnJpODQKLS0tIGNabjdpYXp4d2VyMEcxSXhHdGNr + Y21YcmlWTkJDRUh3czJEUWVGaG44cXMKoibsYSOYv329WNzktBVJ18aGAMXCxz3B + c9938x3U7BCsSatnNch/cTbxPFYt8GhgAXXZb8/vsT9URH+9/K2iuA== + -----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] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.4 diff --git a/nixos/machines/kaalut/mathechor.aliases.yaml b/nixos/machines/kaalut/mathechor.aliases.yaml new file mode 100644 index 0000000..55872b1 --- /dev/null +++ b/nixos/machines/kaalut/mathechor.aliases.yaml @@ -0,0 +1,48 @@ +mathechor.aliases: ENC[AES256_GCM,data:VKEGY6KVtgKApnV7N2e2cqy9erDWQ2fb88Gwcpp5th/t0VGp16KGDtGiuQXhY80j6dDIcQMd9bLHzqAzc4+i/WhmEPhiXUkGiEKuarMfvqNl1LBlXFCoIrUXMMSIqab9q+fE3ignVQapE/YZt9aniyvg1prcmBcwIy9rDoHkiTY006ux5CM+vX0F60ADX8Nf6Qmn/JncPxXgq2jYsBxjXPj7BwJaair/+nxrbVf0,iv:Elj1NDeR1fdIIjIbjvkV3BmcVAKjwdMfknuNxMXJsa4=,tag:AkXWQ8sTMLsd7a+MfRcF/w==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjMlRsWnkrREVaQitsWHMy + WHZFVG1qN25QbWFHcUxNS1Z0SFRDd1oxeG5RCi8wNUhkeWh2VjI4ZGowM1ExaExh + SE1yVGFTUHZadUdDL3pxaGdKTHQ0VTgKLS0tIHVNM2xlOFNNS3dFalJqZUtPODRn + b2NOTHpXSUVyaFRJNG5ONCt0TTVjOEkKYld7KN995QxdrGBVRYgCxO7kGwsiq+cp + iQJTjMdoFygIrTkgE5Rj89/GCiVe0+yAWJuQF7PEnC3cyq0M1g+fzw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPRFJCeXhwQVFSWmgzNHBu + SHlTTGtiRkI5bmhKa1B0QTZMY3FERmlUd0FBCk1vOUpydEFZUExpR2hpWm9mRHpE + dk9MQ042K0FpSVJ3dUlQcktGT2k1VjAKLS0tIHpGRmwzNE01YkV1TW94RkNmMjN4 + YnNXZUlta3NMVW9Cc3V2T0t4R01RSlkKNTW3gnF49BuPwF3jwciOYThJe+gJa0a6 + WKYt+aJuHi0a4y5rS/wfttij+hS5vYVNOrgfJ5bGinkNuAygA2hMOg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6MjZOR1dwb3RjZnlNNW4v + SzJnT1BRVktWNDI5S2Z2NnhQQzdNeS9ralI0CnN0SU9ESEV3ZCtRQmpZK3VZOGYx + Y3FVUy9zY3RZcGxyVmttVzFJL1haYWsKLS0tIENGRW1KZkpUdldOZWgzSXVoenpX + dTVpNUpWallSTzJ3cEZJTXk3c2t1czgKzJCwhMspzAsjzwSRdSPUoseEAsKp8HFy + cL9if92ar68HMHTdoy0Zvy+5AbxKUxgXZ2t8cDgkL8bNG5Ri2xYaUA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtNm5xUGkrK1dYd2ZtamFW + NXpNMEtvNTl3U3MzeVNSbVJOdGdlWGsxRHlZCllQVmNtYzBJNDc2Y0dmUlNsbTF5 + RHB4QWZ1VGNFVkx1Q0hNK3FDTTRrUlkKLS0tIG9hbldDeHk0YmVZV2IwMXNpYStU + Q29uVHBCb2pTeWVJVmVXbWpycnFneWMKnDmu5917dddV8vjO0L8OP3wXMjDi46Ro + b9eOY8l74jm4sTxyKNvnkEjD6iHn1t7f8J7HAbWrpZY+J0i77nrzQw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-23T09:05:51Z" + mac: ENC[AES256_GCM,data:Xnulo0681LtgH9SZt9DL3nd9bSDH+TCQDvbKdggVBJ66rxBiKmlbu5MAblAWqxbdZ6EelldaVeX9OaL2rYJoYbTWxzw2iuPieldp3Ah3PsTI2C8W+UD9KVHcB+3AMOmVmJZzFlZvTwyfPfZRNNb0HAijkN97P3fP0r1Iqf3YjiI=,iv:vhu38HM4e+PyyChXvI87LWSGtKQQiXUr4MKrI7kotzk=,tag:eNuQD74kUO+duqEXNbLJBw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index d4fa331..45db3e1 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -1,4 +1,6 @@ /* +* Forwarding mails: Update the Sops-secrets in the machine directory, rebuild on the VM and deploy. +* Everything else should happen automatically but new redirects might take up to two hours due HRZ infrastructure. * Using the web admin interface: Set your SSH to do portforwarding of some local port to port 80 of the VM and * and use your personal admin account or create one using the fallback admin password. * Create users with mail boxes: Go to the admin interface and create them. @@ -9,6 +11,7 @@ { config, lib, + pkgs, ... }: let inherit @@ -26,6 +29,25 @@ in { type = str; description = "String containing the hashed fallback admin password"; }; + domains = mkOption { + type = listOf (lib.types.submodule { + options = { + domain = mkOption { + description = "Domain name that we serve. We also push its addresses to HRZ."; + type = strMatching "^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$"; #Regex from https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch08s15.html + }; + allowlistPass = mkOption { + description = "Password file for the HRZ API that gets a list of mailaddresses that we serve"; + type = path; + }; + virt_aliases = mkOption { + description = "File path to a virtual alias file applicable for this domain"; + type = path; + default = "/dev/null"; # there might not be an alias file and reading an empty one works with our implementation + }; + }; + }); + }; }; config = mkIf cfg.enable { @@ -127,6 +149,32 @@ in { ]; }; + # 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 + # 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. + config.local-keys = + [ + "store.*" + "directory.*" + "tracer.*" + "server.*" + "!server.blocked-ip.*" + "authentication.fallback-admin.*" + "cluster.node-id" + "storage.data" + "storage.blob" + "storage.lookup" + "storage.fts" + "storage.directory" + "lookup.default.hostname" + "certificate.*" + ] # the default ones + ++ ["sieve.trusted.scripts.*"]; #for macros to be able to include our redirection script + sieve.trusted.scripts.redirects.contents = "%{file:/tmp/virt_aliases}%"; # generated redirect script + session.data.script = "'redirects'"; + authentication.fallback-admin = { user = "admin"; # see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH @@ -149,6 +197,42 @@ in { files = ["/root/.ssh/known_hosts"]; # for the backup server bragi }; + systemd = { + services = { + "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 + }; + "virt-aliases-generator" = { + description = "Virtual Aliases Generator: Generate a sieve script from the virtual alias file"; + script = lib.strings.concatStringsSep "" (["${pkgs.alias-to-sieve}/bin/alias_to_sieve "] ++ map (x: "${x.virt_aliases} ${x.domain} ") cfg.domains ++ ["> /tmp/virt_aliases"]); + wantedBy = ["stalwart-mail.service"]; # Rerun on stalwart restart because forwardings may have changed. + serviceConfig = { + Type = "oneshot"; + User = "stalwart-mail"; + NoNewPrivileges = true; + # See https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html + PrivateTmp = false; + ProtectHome = true; + ReadOnlyPaths = "/"; + ReadWritePaths = "/tmp"; + InaccessiblePaths = "-/lost+found"; + PrivateDevices = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + }; + }; + }; + }; # Backups services.borgbackup.jobs.mail = { paths = [ From 2fc102e57fd683d0a3b3fda170b4390b54a5b6e2 Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Feb 2025 16:16:12 +0100 Subject: [PATCH 6/8] Post mailaddresses to HRZ allowlist --- nixos/machines/kaalut/allowlistPass.yaml | 52 +++++++++++++++++++++ nixos/machines/kaalut/configuration.nix | 22 ++++++++- nixos/machines/kaalut/stalwartAdmin.yaml | 48 ++++++++++++++++++++ nixos/modules/mail.nix | 57 ++++++++++++++++++++++++ 4 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 nixos/machines/kaalut/allowlistPass.yaml create mode 100644 nixos/machines/kaalut/stalwartAdmin.yaml diff --git a/nixos/machines/kaalut/allowlistPass.yaml b/nixos/machines/kaalut/allowlistPass.yaml new file mode 100644 index 0000000..4d60823 --- /dev/null +++ b/nixos/machines/kaalut/allowlistPass.yaml @@ -0,0 +1,52 @@ +allowlistPass: + matheball: ENC[AES256_GCM,data:4y83ZJ4=,iv:+B1hTSGs5cskmUA9gLpRHPjhxzvwOrplB+lIbNUKtz4=,tag:ZsKA2A4ltbI3px1Z16EgvA==,type:str] + mathebau: ENC[AES256_GCM,data:ZlIv0MrCVtsyF3t9Gr/zcg==,iv:ZdBlnx4/zQZjT75ssB0osfDlWVerUe6yvwbMxlXpHZs=,tag:ytlNq7zP2WtPafcSQFZ6RQ==,type:str] + mathechor: ENC[AES256_GCM,data:d5KyoD/P8/j+poJSGF1nDA==,iv:ayKtvj4EEqUtMLi/7njbxuUql1A58WNi729svHtZju4=,tag:JqWoxxMN5mVN+gaQTmBv1Q==,type:str] + koma: ENC[AES256_GCM,data:bB7px1n5q1+++sctsmIMJg==,iv:DIJGpC9+JyFv3SU9dBVLdnEkRlZzY7DBRAL4zXSbpec=,tag:WaZUGvYtm+5ys2RsBNILog==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpWW9FZHEwejRaRER1MHJQ + VXgyaE1GQmhhNFh1dEtBNjRnZXVqWm5hV25vCjliank4KzFobEZtbitzaXBhT1F6 + cCtqeVorS1BLMmMzZkVVOEN6NERFdDAKLS0tIGkzUUt1NnBUWUJWTy9Pd2FIeTF0 + cDVaUHowSEpoRjR3Zm81Z1p5NlYzV1kKMRvC7+3TS5EKjWg/NPnbwvVIikxf+Bpa + zNo9jhw3GREMScBXOiarm+xgMZ1e2SRrLrUwfR4DiXI4uvg1Jk/tPg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRYk1LQTVDNGhHWXJZSmsy + NEZ0WTNlek4yVnRwL3BKNXYrcm84SzIvNlRZCjlDdXU1a2NRNUVHZmkyK2ltZ3pE + bmtmVE5TR1hBcVNhaTBGK2F6VWZ1d2MKLS0tIDVKcXhDbjBncFlsR3FzanRhWWQv + Um1jcExjN2RWbHhzY2ZpcWVTWE1IbHMKfRSAmfbk+JDWdhSTSg9GZ+lws5DOHv9T + ZO9nQV37X9zFD6sXDWaspG3sf4kJZUCbWjCTKyQL/xmh4+E8+CAXYw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzOXBwTUF3ZXJCTFJOQjVC + bGplRDRCQVhtUEJPcnhENEF3UVVnbmVKNnprCjFOZW94ajI2d21RamZKT0xFMmtZ + ZzZFYjg3WDBmOVhlaFZyOW83M1NYVXcKLS0tIGltWUJGczNJS0pWTmxaZHU5Wi9t + TDRCdStocXRvLzBPUTd2blZFV0IyblkKjufZg39n/TI6BhGhIFNz4jplUx6u3/bo + NMbr9uJy/I1sdlfGNaheG/TIGOgFG1KqGkGdwpisU3gUD9uMUo1dvw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzdDdsdW44ZlQyMzdJNmsv + aTIzVWRoSDhzamlqTDFOemZlc1JQMFdZbFJNCmVZbDVVaDBSVi8yTkdOQ1UySy9X + MlhXTzRvNWtqUzQxTlNqQ2RlN2J1OXMKLS0tIC9aZEZMVkFybnRTQmhpM1dzc1lt + bDdvdHc3Y1NmeE5WUzl3cXVRc3pmOUkK+9WueS1wDQDJlenec4jJCfynbPnuOFYR + HFsWmvEZJ+XhH6N9Q0phCHQgZGiR67FH6CHkCblmb6ZfZcWSEe1oTg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-01-05T13:49:19Z" + mac: ENC[AES256_GCM,data:i7t/Hb5aW0lIvPLk84geQ792uUGP25vX8FC7kK/3H19tz5i4zsIcvl1d+oB5gJ004gP5pRogcuKL1xHUUl+A0UXXNzRpxc0BBVZaxnIhjfPunORbmZeJQRP298tQpvYYqI/pGhjrlit37U9jecGf1l12Cgv97sGW42d2F+S2Soc=,iv:My21fMF3SEr6mg2+eh8KA6B8tzmQVEDy2BG3hfkafrU=,tag:xdU6j8ti8Z68rbiRxkj7Pw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.2 diff --git a/nixos/machines/kaalut/configuration.nix b/nixos/machines/kaalut/configuration.nix index 1b84e50..2134b42 100644 --- a/nixos/machines/kaalut/configuration.nix +++ b/nixos/machines/kaalut/configuration.nix @@ -10,6 +10,7 @@ # System configuration here services.mathebau-mail = { enable = true; + stalwartAdmin = config.sops.secrets.stalwartAdmin.path; # see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH stalwartAdminHash = "$argon2i$v=19$m=4096,t=3,p=1$d0hYOTkzclpzSmFTZUplWnhVeWE$I7q9uB19RWL0oZKaPlMPSlGfFp6FQ/vrx80FFKCsalg"; domains = [ @@ -40,7 +41,19 @@ vmNetwork.ipv4 = "192.168.0.17"; system.stateVersion = "24.05"; - sops.secrets = { + sops.secrets = let + allowlistSops = { + sopsFile = ./allowlistPass.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0400"; + }; + in { + # Password for the HRZ API that gets a list of mailaddresses that we serve + "allowlistPass/matheball" = allowlistSops; + "allowlistPass/mathebau" = allowlistSops; + "allowlistPass/mathechor" = allowlistSops; + "allowlistPass/koma" = allowlistSops; # Virtual alias file "mathebau.aliases" = { sopsFile = ./mathebau.aliases.yaml; @@ -60,6 +73,13 @@ 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.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0400"; + }; backupKey = { sopsFile = ./backupKey.yaml; owner = "root"; diff --git a/nixos/machines/kaalut/stalwartAdmin.yaml b/nixos/machines/kaalut/stalwartAdmin.yaml new file mode 100644 index 0000000..9fb24d8 --- /dev/null +++ b/nixos/machines/kaalut/stalwartAdmin.yaml @@ -0,0 +1,48 @@ +stalwartAdmin: ENC[AES256_GCM,data:4vpvxtFa2KiF3ojl+cw3ic/MI7UM9JQCQn76bidYvbW31zgF,iv:DtLAi68oQRf3U69uFK0Cz4qHMkxM6NnB3lVYft/DtqQ=,tag:HYm2mdpTuXNHdQIv2Rkwig==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxcTRqZXRoNTJCdFhQUG9o + Qmx2cVl0TWdaQzZZUThTOEpQdjIxVFh3eHhzCjlHWHhSYmM1ajYrdjl3Nm90TkRh + YWE3c0hJYzdFWXpZUGI0cHBQdThSWWsKLS0tIFh5M20wV2ZZbzllS1BNOGtaRUVF + MFN3bENrZ0tDMllJM1E5MWkyZ2thZEkKfZlUzE5t8K0oHZYOSVItvRJZP2MJlA7N + SLozGlpwCoZKWP6qAqP5jisTG/npQRhcqwkd7P39EytO2HXU9m8sJA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkVldRVmtPUzFxV0ltK0d2 + SHRqbXZCTW5wZUtZM0ZkL3lXOEJmVXdjMXdZCjE5MUUrSEhnWHRSOVhtWWQxdndv + ckUzTFl4ZXM5VHBTRlY3SzVsZWpxNUEKLS0tIEtpbTBhaWR1c3RhSW5nclZvMTdO + eTBYL1Q5cXNvTGkvQzJMWHZHaEZseVUK5w2MPZMquT0luq+tl2owLrrSBx9KPskS + FupcAZTcCo+YsemKLjJ6GlHch5x8Mw98NHS5h1AKxwZYtcfwg3lfbQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpUitNeHNWOTVjWkF4YWhB + MnEwWDFnT0wyNUx3VmlQMmZTRmZRbXBGOVFvCmpoOHZZSXRweUtZaHZ6azF2Q3dK + NFBwa242U3JSVjhtOUlRTUZuakhkcXcKLS0tIEN5TGhMRFphdEpvcU5zTmVlTTJN + d2JRc2p4YmpuUHAycUoxc1FuZmxhemcKOgGyieFVS57tsvUtVooahqswYZH0Fi6+ + jxM6Ga/tIM/bZ/qSwYrNlNiz0XHm8/XFH2s8sxypDZ+NHGLs3zGjsw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBERTdvSTZ3eEVNbEZpUnQ2 + ZC85blRQVzgrckljcnZPeVhZWUxGd01tankwCjBCZHdWRnpoZkdRQWdoK0VmOFVy + VmpiOFkvNisrWmp2NE1kalB4dUhzdWsKLS0tIEJ6T1FsTFlIMUVWd3FwbEtldmlC + UjFHWHNZci8zRlFXNVpNNk5oSUNvaTQKW9T88GflSysJwqMnBrc/jZVwL/fRdg2a + 5XysXb/dCo4uNxLQit/KNSpINj7rAkf4Pk819DO6SKiIiuIJDXw9cA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-23T11:43:23Z" + mac: ENC[AES256_GCM,data:GZ1Q67n43WU3fDQd6SGsD2EZgoaq1mzh5biy42cx6FQWlveK5lhb0F2HUuWWv5zSHKpslEPD6odvkQmMNCRY8NsvT3+KBAnHHU0aHzM9AEV27cDL4x6oBvO52EMxsNCMm+fXPD1CubQxfbfvx/aIuqb1sovgKGgwf4u6yqIrHJ0=,iv:ExX+ySMXhF/c1w2IP7y8mdlcy8W9Zxiy6X67b2f4AeY=,tag:shxQJdaW3HsG6sNY+zDNCA==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 45db3e1..77b058a 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -25,6 +25,10 @@ in { options.services.mathebau-mail = { enable = mkEnableOption "mathebau mail service"; + stalwartAdmin = mkOption { + type = path; + description = "Path to a file that contains the stalwart fallback admin password encoded for HTTP Basic Auth"; + }; stalwartAdminHash = mkOption { type = str; description = "String containing the hashed fallback admin password"; @@ -198,7 +202,60 @@ in { }; systemd = { + timers."mailAllowlist" = { + wantedBy = ["timers.target"]; + timerConfig = { + OnBootSec = "1h"; # Run every hour + OnUnitActiveSec = "1h"; + RandomizedDelaySec = "10m"; # prevent overload on regular intervals + Unit = "mailAllowlist.service"; + }; + }; services = { + "mailAllowlist" = { + description = "Allowlist update: Post the mail addresses to the HRZ allowllist"; + script = let + scriptTemplate = { + domain, + allowlistPass, + ... + }: '' + 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. + ${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 + # 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 + ${pkgs.curl}/bin/curl -s https://www-cgi.hrz.tu-darmstadt.de/mail/whitelist-update.php -F emaildomain=${domain} -F password=$(cat ${allowlistPass}) -F emailliste=@/tmp/addresses -F meldungen=voll + # Cleanup submission file + rm /tmp/addresses + ''; + in + lib.strings.concatStringsSep "" (map scriptTemplate cfg.domains); + serviceConfig = { + Type = "oneshot"; + User = "stalwart-mail"; + NoNewPrivileges = true; + # See https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html + PrivateTmp = false; # allow access to sieve script + ProtectHome = true; + ReadOnlyPaths = "/"; + ReadWritePaths = "/tmp"; + InaccessiblePaths = "-/lost+found"; + PrivateDevices = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + }; + }; "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 From a3890b1e80545203eebe9ce0ca82464a8169bac8 Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Feb 2025 16:19:10 +0100 Subject: [PATCH 7/8] Add patch to allow alias files to redirect to their sender --- flake-module.nix | 38 ++++++++++++++++++++++++++++++++++++-- nixos/modules/mail.nix | 4 ++++ patches/sieve-rs.patch | 27 +++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 patches/sieve-rs.patch diff --git a/flake-module.nix b/flake-module.nix index 7bc32ef..7559834 100644 --- a/flake-module.nix +++ b/flake-module.nix @@ -1,4 +1,8 @@ -{inputs, ...}: { +{ + inputs, + lib, + ... +}: { # debug = true; # We only define machines config in this flake yet, so we only include # the module that builds these. This file might get fuller, if we need to @@ -55,8 +59,38 @@ config.permittedInsecurePackages = ["jitsi-meet-1.0.8043"]; overlays = [ - (_: _: { + (_: prev: { alias-to-sieve = inputs.alias-to-sieve.packages.x86_64-linux.default; # add custom package to convert alias files to sieve scripts on the stalwart machine + stalwart-mail = assert lib.assertMsg (prev.stalwart-mail.version == "0.11.6-unstable-2025-02-04") '' + 1. If the bug https://github.com/stalwartlabs/sieve/issues/11 is resolved to our satisfaction, try to remove this overlay. + 2. Check whether sieve-rs recieved new updates that our patch needs to be rebased upon. + 3. Check whether the sieve-rs patch below that exchanges the dependency needs updates. + 4. Then update the version comparison in this assert statement. + 5. Update the `cargoHash` by setting it to `lib.fakeHash` and then inserting the result. + 6. Check if we can get rid of alias-to-sieve when stalwart-mail has a builtin alias feature. + ''; + prev.stalwart-mail.override ( + let + rp = pkgs.rustPlatform; + in { + rustPlatform = + rp + // { + buildRustPackage = args: + rp.buildRustPackage ( + args + // rec { + cargoPatches = [ + # Let stalwart-mail depend on our own version of the sieve crate that does not have some “loop prevention” that disables redirects to the original sender. + # We want to redirect to sender if we simulate alias files and not doing so barely prevents loops in my opinion. + ./patches/sieve-rs.patch + ]; + cargoHash = "sha256-gb2oFlVA/vE6DoWWW8SCFA3l7rtV2RuosPUY+6IcKNM="; + } + ); + }; + } + ); }) ]; }; diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix index 77b058a..f1861a2 100644 --- a/nixos/modules/mail.nix +++ b/nixos/modules/mail.nix @@ -1,4 +1,8 @@ /* +* Building: We patch our version of stalwart and thus need to built it locally. +* Be aware that this needs some hours, about 12Gb RAM and a few Gb free space in /tmp. +* If you only want to deploy configuration changes and no software updates, consider building on the target VM. +* It has stalwart in its nix store and does not need to rebuild it. * Forwarding mails: Update the Sops-secrets in the machine directory, rebuild on the VM and deploy. * Everything else should happen automatically but new redirects might take up to two hours due HRZ infrastructure. * Using the web admin interface: Set your SSH to do portforwarding of some local port to port 80 of the VM and diff --git a/patches/sieve-rs.patch b/patches/sieve-rs.patch new file mode 100644 index 0000000..b706d03 --- /dev/null +++ b/patches/sieve-rs.patch @@ -0,0 +1,27 @@ +diff --git a/Cargo.lock b/Cargo.lock +index be36759b..b4316639 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -6404,8 +6404,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] + name = "sieve-rs" + version = "0.6.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "15ac54053752c25a0e545dd1953de716abcc80b12cfe0b6c2f2c1c73759d4f45" ++source = "git+https://gitea.mathebau.de/fachschaft/sieve-rs.git#71324550504c0f84fe3e814d05cbe22f90a3b228" + dependencies = [ + "ahash 0.8.11", + "bincode", +diff --git a/Cargo.toml b/Cargo.toml +index f055474f..2b64c9ac 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -63,3 +63,7 @@ incremental = false + debug-assertions = false + overflow-checks = false + rpath = false ++ ++ ++[patch.crates-io] ++sieve-rs = { git = 'https://gitea.mathebau.de/fachschaft/sieve-rs.git' } + From f6f3464582505bba9c45bc6af43ba83451c556c6 Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Feb 2025 16:22:31 +0100 Subject: [PATCH 8/8] Submit mailing list mails to correct vm based on port forwarding and run allowlist job less often --- nixos/modules/mailman.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nixos/modules/mailman.nix b/nixos/modules/mailman.nix index 5cfa63d..f4ecd0e 100644 --- a/nixos/modules/mailman.nix +++ b/nixos/modules/mailman.nix @@ -35,7 +35,7 @@ in { proxy_interfaces = "130.83.2.184"; smtputf8_enable = "no"; # HRZ does not know SMTPUTF8 }; - relayHost = "192.168.0.24"; # Relay to eihort which relays to HRZ (see https://www.hrz.tu-darmstadt.de/services/it_services/email_infrastruktur/index.de.jsp) + 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) }; mailman = { enable = true; @@ -64,9 +64,9 @@ in { systemd.timers."mailAllowlist" = { wantedBy = ["timers.target"]; timerConfig = { - OnBootSec = "5m"; # Run every 5 minutes - OnUnitActiveSec = "5m"; - RandomizedDelaySec = "2m"; # prevent overload on regular intervals + OnBootSec = "1h"; # Run every hour + OnUnitActiveSec = "1h"; + RandomizedDelaySec = "10m"; # prevent overload on regular intervals Unit = "mailAllowlist.service"; }; };