From b9c0f24035481819f2f22edd5559a9dc5d1d7a44 Mon Sep 17 00:00:00 2001 From: Gonne Date: Wed, 10 Jul 2024 22:56:46 +0200 Subject: [PATCH] First try to install Stalwart as a mail software --- .sops.yaml | 7 + flake.lock | 32 ++-- nixos/machines/kaalut/configuration.nix | 45 +++++ .../kaalut/hardware-configuration.nix | 30 ++++ nixos/modules/mail.nix | 161 ++++++++++++++++++ 5 files changed, 259 insertions(+), 16 deletions(-) create mode 100644 nixos/machines/kaalut/configuration.nix create mode 100644 nixos/machines/kaalut/hardware-configuration.nix create mode 100644 nixos/modules/mail.nix diff --git a/.sops.yaml b/.sops.yaml index bc5cfc6..e112b48 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -5,6 +5,7 @@ keys: - &nyarlathotep age1s99d0vlj5qlm287n98jratql5fypvjrxxal0k5jl2aw9dcc8kyvqw5yyt4 - &bragi age1lqvgpmlemyg9095ujck64u59ma29656zs7a4yxgz4s6u5cld2ccss69jwe - &lobon age12nz7dtc0m5wasxm4r9crtkgwnzvauyfp0xh0n8z8jld0arn9ea9qe0agvn + - &kaalut age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj creation_rules: - path_regex: nixos/machines/nyarlathotep/.* @@ -25,6 +26,12 @@ creation_rules: - *nerf - *gonne - *lobon + - path_regex: nixos/machines/kaalut/.* + key_groups: + - age: + - *nerf + - *gonne + - *kaalut # this is the catchall clause if nothing above machtes. Encrypt to users but not # to machines - key_groups: diff --git a/flake.lock b/flake.lock index 96ee64c..461b4b5 100644 --- a/flake.lock +++ b/flake.lock @@ -21,11 +21,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1719877454, - "narHash": "sha256-g5N1yyOSsPNiOlFfkuI/wcUjmtah+nxdImJqrSATjOU=", + "lastModified": 1719994518, + "narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "4e3583423212f9303aa1a6337f8dffb415920e4f", + "rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7", "type": "github" }, "original": { @@ -71,11 +71,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1719848872, - "narHash": "sha256-H3+EC5cYuq+gQW8y0lSrrDZfH71LB4DAf+TDFyvwCNA=", + "lastModified": 1720957393, + "narHash": "sha256-oedh2RwpjEa+TNxhg5Je9Ch6d3W1NKi7DbRO1ziHemA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "00d80d13810dbfea8ab4ed1009b09100cca86ba8", + "rev": "693bc46d169f5af9c992095736e82c3488bf7dbb", "type": "github" }, "original": { @@ -114,16 +114,16 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1719663039, - "narHash": "sha256-tXlrgAQygNIy49LDVFuPXlWD2zTQV9/F8pfoqwwPJyo=", + "lastModified": 1720915306, + "narHash": "sha256-6vuViC56+KSr+945bCV8akHK+7J5k6n/epYg/W3I5eQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "4a1e673523344f6ccc84b37f4413ad74ea19a119", + "rev": "74348da2f3a312ee25cea09b98cdba4cb9fa5d5d", "type": "github" }, "original": { "owner": "NixOS", - "ref": "release-23.11", + "ref": "release-24.05", "repo": "nixpkgs", "type": "github" } @@ -136,11 +136,11 @@ "nixpkgs-stable": [] }, "locked": { - "lastModified": 1719259945, - "narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=", + "lastModified": 1721042469, + "narHash": "sha256-6FPUl7HVtvRHCCBQne7Ylp4p+dpP3P/OYuzjztZ4s70=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07", + "rev": "f451c19376071a90d8c58ab1a953c6e9840527fd", "type": "github" }, "original": { @@ -167,11 +167,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1719873517, - "narHash": "sha256-D1dxZmXf6M2h5lNE1m6orojuUawVPjogbGRsqSBX+1g=", + "lastModified": 1720926522, + "narHash": "sha256-eTpnrT6yu1vp8C0B5fxHXhgKxHoYMoYTEikQx///jxY=", "owner": "Mic92", "repo": "sops-nix", - "rev": "a11224af8d824935f363928074b4717ca2e280db", + "rev": "0703ba03fd9c1665f8ab68cc3487302475164617", "type": "github" }, "original": { diff --git a/nixos/machines/kaalut/configuration.nix b/nixos/machines/kaalut/configuration.nix new file mode 100644 index 0000000..d840c0f --- /dev/null +++ b/nixos/machines/kaalut/configuration.nix @@ -0,0 +1,45 @@ +{ + imports = [ + ./hardware-configuration.nix + ../../modules/mail.nix + ../../roles + ../../roles/vm.nix + ../../modules/vmNetwork.nix + ]; + + # System configuration here + + services.mathebau-mail = { + enable = true; + fqdn = "fb04184.mathematik.tu-darmstadt.de"; + domain = "koma89.tu-darmstadt.de"; + siteOwner = "root@mathebau.de"; + }; + + networking.hostName = "kaalut"; + vmNetwork.ipv4 = "192.168.0.17"; + system.stateVersion = "24.05"; + + sops.secrets = { + /* + allowlistPass = { + sopsFile = ./allowlistPass.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0400"; + }; + backupKey = { + sopsFile = ./backupKey.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0400"; + }; + */ + fallbackadmin = { + sopsFile = ./fallbackadmin.yaml; + owner = "stalwart-mail"; + group = "stalwart-mail"; + mode = "0400"; + }; + }; +} diff --git a/nixos/machines/kaalut/hardware-configuration.nix b/nixos/machines/kaalut/hardware-configuration.nix new file mode 100644 index 0000000..ce7112d --- /dev/null +++ b/nixos/machines/kaalut/hardware-configuration.nix @@ -0,0 +1,30 @@ +{ + lib, + pkgs, + ... +}: { + imports = []; + + fileSystems."/" = { + device = "root"; + fsType = "tmpfs"; + options = ["size=1G" "mode=755"]; + }; + fileSystems."/persist" = { + device = "/dev/disk/by-label/nixos"; + fsType = "btrfs"; + options = ["subvol=persist"]; + neededForBoot = true; + }; + fileSystems."/boot" = { + device = "/dev/disk/by-label/boot"; + fsType = "ext4"; + }; + fileSystems."/nix" = { + device = "/dev/disk/by-label/nixos"; + fsType = "btrfs"; + options = ["subvol=nix"]; + }; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/nixos/modules/mail.nix b/nixos/modules/mail.nix new file mode 100644 index 0000000..ba75746 --- /dev/null +++ b/nixos/modules/mail.nix @@ -0,0 +1,161 @@ +{ + config, + lib, + # pkgs, + ... +}: let + inherit + (lib) + mkIf + mkEnableOption + mkOption + ; + inherit (lib.types) str; + cfg = config.services.mathebau-mail; +in { + options.services.mathebau-mail = { + enable = mkEnableOption "mathebau mail service"; + fqdn = mkOption { + type = str; + }; + domain = mkOption { + type = str; + }; + siteOwner = mkOption { + type = str; + }; + }; + + config = mkIf cfg.enable { + services = { + stalwart-mail = { + enable = true; + openFirewall = true; + settings = { + # TODO TLS + server = { + hostname = cfg.fqdn; + listener = { + "smtp" = { + bind = ["[::]:25"]; + protocol = "smtp"; + tls.implicit = false; + }; + "submissions" = { + bind = ["[::]:465"]; + protocol = "smtp"; + tls.implicit = true; + }; + "imaptls" = { + bind = ["[::]:993"]; + protocol = "imap"; + tls.implicit = true; + }; + "management" = { + bind = ["127.0.0.1:8080"]; + protocol = "http"; + }; + }; + tls = { + certificate = cfg.fqdn; + enable = true; + implicit = false; + }; + }; + queue.outbound = { + # see https://stalw.art/docs/smtp/outbound/routing/ relay host example + next-hop = ["relay"]; + tls.mta-sts = "disable"; + tls.dane = "disable"; + }; + queue."relay" = { + address = "192.168.0.24"; #TODO mailout.hrz… + port = 25; + protocol = "smtp"; + tls.implicit = false; + tls.allow-invalid-certs = false; + }; + }; + }; + }; + environment.persistence.${config.impermanence.name} = { + directories = [ + "/var/lib/acme" # Persist TLS keys and account + "/var/lib/stalwart-mail" + ]; + files = ["/root/.ssh/known_hosts"]; # for the backup server bragi + }; + + security.acme.defaults.email = cfg.siteOwner; + security.acme.acceptTerms = true; + + # Update HRZ allowlist + # For account details see https://www-cgi.hrz.tu-darmstadt.de/mail/ + # will stop working if no valid TUIDs are associated to our domain. + /* + systemd.timers."mailAllowlist" = { + wantedBy = ["timers.target"]; + timerConfig = { + OnBootSec = "5m"; # Run every 5 minutes + OnUnitActiveSec = "5m"; + RandomizedDelaySec = "2m"; # prevent overload on regular intervals + Unit = "mailAllowlist.service"; + }; + }; + systemd.services."mailAllowlist" = { + description = "Allowlist update: Post the mail addresses to the HRZ allowllist"; + script = '' + # Get the mail addresses' local-part + #TODO + # Post local-parts to HRZ + ${pkgs.curl}/bin/curl https://www-cgi.hrz.tu-darmstadt.de/mail/whitelist-update.php -F emaildomain=${cfg.domain} -F password=$(cat /run/secrets/allowlistPass) -F emailliste=@/tmp/addresses -F meldungen=voll + # Cleanup + rm /tmp/addresses + ''; + serviceConfig = { + Type = "oneshot"; + User = "stalwart-mail"; + NoNewPrivileges = true; + # See https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html + PrivateTmp = true; + 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 = [ + "/var/lib/stalwart-mail" + ]; + encryption.mode = "none"; # Otherwise the key is next to the backup or we have human interaction. + environment = { + BORG_RSH = "ssh -i /run/secrets/backupKey"; + # “Borg ensures that backups are not created on random drives that ‘just happen’ to contain a Borg repository.” + # https://borgbackup.readthedocs.io/en/stable/deployment/automated-local.html + # We don't want this in order to not need to persist borg cache and simplify new deployments. + BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK = "yes"; + }; + repo = "borg@192.168.1.11:kaluut"; # TODO for https://gitea.mathebau.de/Fachschaft/nixConfig/issues/33 + startAt = "daily"; + user = "root"; + group = "root"; + }; + */ + }; +}