diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-03-04 20:22:08 +0100 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-03-09 13:44:31 +0100 |
commit | d86f0cb1cdd1d3dd50e9d2a27b42895028044fdf (patch) | |
tree | bbcc86a3ac100c5b124f2f453fc1f6b5513af018 /modules/by-name/st | |
parent | modules/stalwart-mail: Select DKIM keys per-domain (diff) | |
download | nixos-server-d86f0cb1cdd1d3dd50e9d2a27b42895028044fdf.zip |
modules/stalwart-mail: Include full systemd service and set correct dependencies
This also starts `nginx` so that we can complete http-01 acme challenges.
Diffstat (limited to 'modules/by-name/st')
-rw-r--r-- | modules/by-name/st/stalwart-mail/module.nix | 130 |
1 files changed, 89 insertions, 41 deletions
diff --git a/modules/by-name/st/stalwart-mail/module.nix b/modules/by-name/st/stalwart-mail/module.nix index 3ef7d85..eb2703c 100644 --- a/modules/by-name/st/stalwart-mail/module.nix +++ b/modules/by-name/st/stalwart-mail/module.nix @@ -156,13 +156,59 @@ in { } ]; - services.stalwart-mail = { - # NOTE(@bpeetz): We do not use the nixos service, as it comes with too much - # bothersome default configuration and not really any useful config. - # However, this decision could obviously be reverse in the future. <2025-02-08> - enable = false; - inherit (cfg) package; - # dataDir = cfg.dataDirectory; + vhack.nginx.enable = true; + services = { + stalwart-mail = { + # NOTE(@bpeetz): We do not use the NixOS service, as it comes with too much + # bothersome default configuration and not really any useful configuration. + # However, this decision could obviously be reversed in the future. <2025-02-08> + enable = false; + inherit (cfg) package; + # dataDir = cfg.dataDirectory; + }; + + # FIXME(@bpeetz): This is currently needed for a successful acme http-01 challenge. + # We could also use the DNS challenge. <2025-03-01> + nginx.virtualHosts."${cfg.fqdn}" = { + enableACME = false; + extraConfig = + # This is copied directly from the nixos nginx module. + # Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx) + # We use ^~ here, so that we don't check any regexes (which could + # otherwise easily override this intended match accidentally). + '' + location ^~ /.well-known/acme-challenge/ { + root ${config.security.acme.certs.${cfg.fqdn}.webroot}; + auth_basic off; + auth_request off; + } + ''; + }; + + redis = { + servers = { + "stalwart-mail" = { + enable = true; + + user = "stalwart-mail"; + + # Disable TCP listening. (We have a UNIX socket) + port = 0; + bind = null; + + settings = { + protected-mode = true; + enable-protected-configs = false; + enable-debug-command = false; + enable-module-command = false; + + supervised = "systemd"; + stop-writes-on-bgsave-error = true; + sanitize-dump-payload = "clients"; + }; + }; + }; + }; }; security.acme.certs = { "${cfg.fqdn}" = { @@ -202,31 +248,6 @@ in { } ]; - services.redis = { - servers = { - "stalwart-mail" = { - enable = true; - - user = "stalwart-mail"; - - # Disable TCP listening. (We have a UNIX socket) - port = 0; - bind = null; - - settings = { - protected-mode = true; - enable-protected-configs = false; - enable-debug-command = false; - enable-module-command = false; - - supervised = "systemd"; - stop-writes-on-bgsave-error = true; - sanitize-dump-payload = "clients"; - }; - }; - }; - }; - # This service stores a potentially large amount of data. # Running it as a dynamic user would force chown to be run every time the # service is restarted on a potentially large number of files. @@ -244,13 +265,31 @@ in { ]; systemd = { - packages = [cfg.package]; services.stalwart-mail = { wantedBy = ["multi-user.target"]; + requires = [ + "redis-stalwart-mail.service" + "network-online.target" + "acme-${cfg.fqdn}.service" + ]; after = [ "local-fs.target" "network.target" + "network-online.target" + "redis-stalwart-mail.service" + "acme-${cfg.fqdn}.service" + ]; + conflicts = [ + "postfix.service" + "sendmail.service" + "exim4.service" ]; + description = "Stalwart Mail Server"; + + environment = { + SSL_CERT_FILE = "/etc/ssl/certs/ca-certificates.crt"; + NIX_SSL_CERT_FILE = "/etc/ssl/certs/ca-certificates.crt"; + }; preStart = let esa = lib.strings.escapeShellArg; @@ -271,10 +310,18 @@ in { + (builtins.concatStringsSep "\n" storageDirectories); serviceConfig = { - ExecStart = [ - "" - "${cfg.package}/bin/stalwart-mail --config=$CACHE_DIRECTORY/mutable_config_file.toml" - ]; + ExecStart = pkgs.writers.writeDash "start-stalwart-mail" '' + ${lib.getExe cfg.package} --config="$CACHE_DIRECTORY/mutable_config_file.toml" + ''; + + Restart = "on-failure"; + RestartSec = 5; + + KillMode = "process"; + KillSignal = "SIGINT"; + + Type = "simple"; + LimitNOFILE = 65536; StandardOutput = "journal"; StandardError = "journal"; @@ -285,6 +332,11 @@ in { CacheDirectory = "stalwart-mail"; StateDirectory = "stalwart-mail"; + User = "stalwart-mail"; + Group = "stalwart-mail"; + + SyslogIdentifier = "stalwart-mail"; + # Bind standard privileged ports AmbientCapabilities = ["CAP_NET_BIND_SERVICE"]; CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"]; @@ -321,10 +373,6 @@ in { ]; UMask = "0077"; }; - unitConfig.ConditionPathExists = [ - "" - "${configFile}" - ]; }; }; |