From 7796b7aa00f2c275b45921879a037fdb33003b2e Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Feb 2025 16:09:44 +0100 Subject: [PATCH] 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 = [