summaryrefslogtreecommitdiffstats
path: root/nixos/modules/services/mail/stalwart-mail.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services/mail/stalwart-mail.nix')
-rw-r--r--nixos/modules/services/mail/stalwart-mail.nix151
1 files changed, 90 insertions, 61 deletions
diff --git a/nixos/modules/services/mail/stalwart-mail.nix b/nixos/modules/services/mail/stalwart-mail.nix
index 68606698e59f..ed3c5389354c 100644
--- a/nixos/modules/services/mail/stalwart-mail.nix
+++ b/nixos/modules/services/mail/stalwart-mail.nix
@@ -7,6 +7,7 @@ let
configFormat = pkgs.formats.toml { };
configFile = configFormat.generate "stalwart-mail.toml" cfg.settings;
dataDir = "/var/lib/stalwart-mail";
+ useLegacyStorage = versionOlder config.system.stateVersion "24.11";
in {
options.services.stalwart-mail = {
@@ -30,79 +31,107 @@ in {
# Default config: all local
services.stalwart-mail.settings = {
- global.tracing.method = mkDefault "stdout";
- global.tracing.level = mkDefault "info";
+ tracer.stdout = {
+ type = mkDefault "stdout";
+ level = mkDefault "info";
+ ansi = mkDefault false; # no colour markers to journald
+ enable = mkDefault true;
+ };
queue.path = mkDefault "${dataDir}/queue";
report.path = mkDefault "${dataDir}/reports";
- store.db.type = mkDefault "sqlite";
- store.db.path = mkDefault "${dataDir}/data/index.sqlite3";
- store.blob.type = mkDefault "fs";
- store.blob.path = mkDefault "${dataDir}/data/blobs";
+ store = if useLegacyStorage then {
+ # structured data in SQLite, blobs on filesystem
+ db.type = mkDefault "sqlite";
+ db.path = mkDefault "${dataDir}/data/index.sqlite3";
+ fs.type = mkDefault "fs";
+ fs.path = mkDefault "${dataDir}/data/blobs";
+ } else {
+ # everything in RocksDB
+ db.type = mkDefault "rocksdb";
+ db.path = mkDefault "${dataDir}/db";
+ db.compression = mkDefault "lz4";
+ };
storage.data = mkDefault "db";
storage.fts = mkDefault "db";
storage.lookup = mkDefault "db";
- storage.blob = mkDefault "blob";
+ storage.blob = mkDefault (if useLegacyStorage then "fs" else "db");
+ directory.internal.type = mkDefault "internal";
+ directory.internal.store = mkDefault "db";
+ storage.directory = mkDefault "internal";
resolver.type = mkDefault "system";
resolver.public-suffix = lib.mkDefault [
"file://${pkgs.publicsuffix-list}/share/publicsuffix/public_suffix_list.dat"
];
};
- systemd.services.stalwart-mail = {
- wantedBy = [ "multi-user.target" ];
- after = [ "local-fs.target" "network.target" ];
-
- preStart = ''
- mkdir -p ${dataDir}/{queue,reports,data/blobs}
- '';
+ # This service stores a potentially large amount of data.
+ # Running it as a dynamic user would force chown to be run everytime the
+ # service is restarted on a potentially large number of files.
+ # That would cause unnecessary and unwanted delays.
+ users = {
+ groups.stalwart-mail = { };
+ users.stalwart-mail = {
+ isSystemUser = true;
+ group = "stalwart-mail";
+ };
+ };
- serviceConfig = {
- ExecStart =
- "${cfg.package}/bin/stalwart-mail --config=${configFile}";
-
- # Base from template resources/systemd/stalwart-mail.service
- Type = "simple";
- LimitNOFILE = 65536;
- KillMode = "process";
- KillSignal = "SIGINT";
- Restart = "on-failure";
- RestartSec = 5;
- StandardOutput = "journal";
- StandardError = "journal";
- SyslogIdentifier = "stalwart-mail";
-
- DynamicUser = true;
- User = "stalwart-mail";
- StateDirectory = "stalwart-mail";
-
- # Bind standard privileged ports
- AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
- CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
-
- # Hardening
- DeviceAllow = [ "" ];
- LockPersonality = true;
- MemoryDenyWriteExecute = true;
- PrivateDevices = true;
- PrivateUsers = false; # incompatible with CAP_NET_BIND_SERVICE
- ProcSubset = "pid";
- PrivateTmp = true;
- ProtectClock = true;
- ProtectControlGroups = true;
- ProtectHome = true;
- ProtectHostname = true;
- ProtectKernelLogs = true;
- ProtectKernelModules = true;
- ProtectKernelTunables = true;
- ProtectProc = "invisible";
- ProtectSystem = "strict";
- RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
- RestrictNamespaces = true;
- RestrictRealtime = true;
- RestrictSUIDSGID = true;
- SystemCallArchitectures = "native";
- SystemCallFilter = [ "@system-service" "~@privileged" ];
- UMask = "0077";
+ systemd = {
+ packages = [ cfg.package ];
+ services.stalwart-mail = {
+ wantedBy = [ "multi-user.target" ];
+ after = [ "local-fs.target" "network.target" ];
+
+ preStart = if useLegacyStorage then ''
+ mkdir -p ${dataDir}/{queue,reports,data/blobs}
+ '' else ''
+ mkdir -p ${dataDir}/{queue,reports,db}
+ '';
+
+ serviceConfig = {
+ ExecStart = [
+ ""
+ "${cfg.package}/bin/stalwart-mail --config=${configFile}"
+ ];
+
+ StandardOutput = "journal";
+ StandardError = "journal";
+
+ StateDirectory = "stalwart-mail";
+
+ # Bind standard privileged ports
+ AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
+ CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
+
+ # Hardening
+ DeviceAllow = [ "" ];
+ LockPersonality = true;
+ MemoryDenyWriteExecute = true;
+ PrivateDevices = true;
+ PrivateUsers = false; # incompatible with CAP_NET_BIND_SERVICE
+ ProcSubset = "pid";
+ PrivateTmp = true;
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ ProtectHome = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectProc = "invisible";
+ ProtectSystem = "strict";
+ RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ RestrictSUIDSGID = true;
+ SystemCallArchitectures = "native";
+ SystemCallFilter = [ "@system-service" "~@privileged" ];
+ UMask = "0077";
+ };
+ unitConfig.ConditionPathExists = [
+ ""
+ "${configFile}"
+ ];
};
};