aboutsummaryrefslogtreecommitdiffstats
path: root/modules/by-name/st/stalwart-mail
diff options
context:
space:
mode:
Diffstat (limited to 'modules/by-name/st/stalwart-mail')
-rw-r--r--modules/by-name/st/stalwart-mail/module.nix130
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}"
- ];
};
};