summaryrefslogtreecommitdiffstats
path: root/nixos/modules/services/mail
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services/mail')
-rw-r--r--nixos/modules/services/mail/mailman.nix11
-rw-r--r--nixos/modules/services/mail/roundcube.nix7
-rw-r--r--nixos/modules/services/mail/stalwart-mail.nix158
3 files changed, 104 insertions, 72 deletions
diff --git a/nixos/modules/services/mail/mailman.nix b/nixos/modules/services/mail/mailman.nix
index 7e7ca7e4060e..180c9800d734 100644
--- a/nixos/modules/services/mail/mailman.nix
+++ b/nixos/modules/services/mail/mailman.nix
@@ -534,14 +534,11 @@ in {
hyperkittyApiKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64)
secretKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64)
- mailmanWebCfgTmp=$(mktemp)
- jq -n '.MAILMAN_ARCHIVER_KEY=$archiver_key | .SECRET_KEY=$secret_key' \
+ install -m 0440 -o root -g mailman \
+ <(jq -n '.MAILMAN_ARCHIVER_KEY=$archiver_key | .SECRET_KEY=$secret_key' \
--arg archiver_key "$hyperkittyApiKey" \
- --arg secret_key "$secretKey" \
- >"$mailmanWebCfgTmp"
- chown root:mailman "$mailmanWebCfgTmp"
- chmod 440 "$mailmanWebCfgTmp"
- mv -n "$mailmanWebCfgTmp" "$mailmanWebCfg"
+ --arg secret_key "$secretKey") \
+ "$mailmanWebCfg"
fi
hyperkittyApiKey="$(jq -r .MAILMAN_ARCHIVER_KEY "$mailmanWebCfg")"
diff --git a/nixos/modules/services/mail/roundcube.nix b/nixos/modules/services/mail/roundcube.nix
index 4499532ace89..78f627d33e2d 100644
--- a/nixos/modules/services/mail/roundcube.nix
+++ b/nixos/modules/services/mail/roundcube.nix
@@ -7,7 +7,7 @@ let
fpm = config.services.phpfpm.pools.roundcube;
localDB = cfg.database.host == "localhost";
user = cfg.database.username;
- phpWithPspell = pkgs.php81.withExtensions ({ enabled, all }: [ all.pspell ] ++ enabled);
+ phpWithPspell = pkgs.php83.withExtensions ({ enabled, all }: [ all.pspell ] ++ enabled);
in
{
options.services.roundcube = {
@@ -247,14 +247,15 @@ in
(mkIf (cfg.database.host == "localhost") {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
- path = [ config.services.postgresql.package ];
})
{
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
+
+ path = [ config.services.postgresql.package ];
script = let
- psql = "${lib.optionalString (!localDB) "PGPASSFILE=${cfg.database.passwordFile}"} ${pkgs.postgresql}/bin/psql ${lib.optionalString (!localDB) "-h ${cfg.database.host} -U ${cfg.database.username} "} ${cfg.database.dbname}";
+ psql = "${lib.optionalString (!localDB) "PGPASSFILE=${cfg.database.passwordFile}"} psql ${lib.optionalString (!localDB) "-h ${cfg.database.host} -U ${cfg.database.username} "} ${cfg.database.dbname}";
in
''
version="$(${psql} -t <<< "select value from system where name = 'roundcube-version';" || true)"
diff --git a/nixos/modules/services/mail/stalwart-mail.nix b/nixos/modules/services/mail/stalwart-mail.nix
index 9cc919fd117d..ed3c5389354c 100644
--- a/nixos/modules/services/mail/stalwart-mail.nix
+++ b/nixos/modules/services/mail/stalwart-mail.nix
@@ -7,10 +7,12 @@ 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 = {
enable = mkEnableOption "the Stalwart all-in-one email server";
+
package = mkPackageOption pkgs "stalwart-mail" { };
settings = mkOption {
@@ -26,78 +28,110 @@ in {
};
config = mkIf cfg.enable {
+
# 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.blob = mkDefault "blob";
+ storage.lookup = mkDefault "db";
+ 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"
+ ];
+ };
+
+ # 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";
+ };
};
- systemd.services.stalwart-mail = {
- wantedBy = [ "multi-user.target" ];
- after = [ "local-fs.target" "network.target" ];
+ systemd = {
+ packages = [ cfg.package ];
+ services.stalwart-mail = {
+ wantedBy = [ "multi-user.target" ];
+ after = [ "local-fs.target" "network.target" ];
- preStart = ''
- mkdir -p ${dataDir}/{queue,reports,data/blobs}
- '';
+ 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" ];
- 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";
+ # 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}"
+ ];
};
};
@@ -106,6 +140,6 @@ in {
};
meta = {
- maintainers = with maintainers; [ happysalada pacien ];
+ maintainers = with maintainers; [ happysalada pacien onny ];
};
}