diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/mail/stalwart-mail.nix')
-rw-r--r-- | nixpkgs/nixos/modules/services/mail/stalwart-mail.nix | 186 |
1 files changed, 95 insertions, 91 deletions
diff --git a/nixpkgs/nixos/modules/services/mail/stalwart-mail.nix b/nixpkgs/nixos/modules/services/mail/stalwart-mail.nix index c69a2ca400ba..ed3c5389354c 100644 --- a/nixpkgs/nixos/modules/services/mail/stalwart-mail.nix +++ b/nixpkgs/nixos/modules/services/mail/stalwart-mail.nix @@ -7,28 +7,13 @@ let configFormat = pkgs.formats.toml { }; configFile = configFormat.generate "stalwart-mail.toml" cfg.settings; dataDir = "/var/lib/stalwart-mail"; - stalwartAtLeast = versionAtLeast cfg.package.version; + useLegacyStorage = versionOlder config.system.stateVersion "24.11"; in { options.services.stalwart-mail = { enable = mkEnableOption "the Stalwart all-in-one email server"; - package = mkOption { - type = types.package; - description = '' - Which package to use for the Stalwart mail server. - - ::: {.note} - Upgrading from version 0.6.0 to version 0.7.0 or higher requires manual - intervention. See <https://github.com/stalwartlabs/mail-server/blob/main/UPGRADING.md> - for upgrade instructions. - ::: - ''; - default = pkgs.stalwart-mail_0_6; - defaultText = lib.literalExpression "pkgs.stalwart-mail_0_6"; - example = lib.literalExpression "pkgs.stalwart-mail"; - relatedPackages = [ "stalwart-mail_0_6" "stalwart-mail" ]; - }; + package = mkPackageOption pkgs "stalwart-mail" { }; settings = mkOption { inherit (configFormat) type; @@ -44,90 +29,109 @@ in { config = mkIf cfg.enable { - warnings = lib.optionals (!stalwartAtLeast "0.7.0") [ - '' - Versions of stalwart-mail < 0.7.0 will get deprecated in NixOS 24.11. - Please set services.stalwart-mail.package to pkgs.stalwart-mail to - upgrade to the latest version. - Please note that upgrading to version >= 0.7 requires manual - intervention, see <https://github.com/stalwartlabs/mail-server/blob/main/UPGRADING.md> - for upgrade instructions. - '' - ]; - # 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 = mkDefault ["https://publicsuffix.org/list/public_suffix_list.dat"]; + 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}" + ]; }; }; @@ -136,6 +140,6 @@ in { }; meta = { - maintainers = with maintainers; [ happysalada pacien ]; + maintainers = with maintainers; [ happysalada pacien onny ]; }; } |