aboutsummaryrefslogtreecommitdiffstats
path: root/modules/vhack/st
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--modules/vhack/st/stalwart-mail/module.nix (renamed from modules/by-name/st/stalwart-mail/module.nix)94
-rw-r--r--modules/vhack/st/stalwart-mail/settings.nix (renamed from modules/by-name/st/stalwart-mail/settings.nix)60
2 files changed, 105 insertions, 49 deletions
diff --git a/modules/by-name/st/stalwart-mail/module.nix b/modules/vhack/st/stalwart-mail/module.nix
index 6905005..f7e44d8 100644
--- a/modules/by-name/st/stalwart-mail/module.nix
+++ b/modules/vhack/st/stalwart-mail/module.nix
@@ -18,7 +18,7 @@ in {
options.vhack.stalwart-mail = {
enable = lib.mkEnableOption "starwart-mail";
- package = lib.mkPackageOption vhackPackages "stalwart-mail-free" {};
+ package = lib.mkPackageOption pkgs "stalwart-mail" {};
admin = lib.mkOption {
description = ''
@@ -41,8 +41,8 @@ in {
};
principals = lib.mkOption {
- default = [];
- type = lib.types.listOf (lib.types.submodule {
+ default = null;
+ type = lib.types.nullOr (lib.types.listOf (lib.types.submodule {
options = {
name = lib.mkOption {
type = lib.types.str;
@@ -61,7 +61,32 @@ in {
};
secret = lib.mkOption {
- type = lib.types.str;
+ type = let
+ prefix = pre: lib.types.strMatching "^${lib.strings.escapeRegex pre}.*";
+ in
+ lib.types.oneOf [
+ (prefix "$argon2")
+ (prefix "$pbkdf2")
+ (prefix "$scrypt")
+ (prefix "$2") # bcrypt
+ (prefix "$6$") # sha-512
+ (prefix "$5$") # sha-256
+ (prefix "$sha1")
+ (prefix "$1") # md5
+ (prefix "_") # BSDi crypt
+ (prefix "{SHA}") # base64 sha
+ (prefix "{SSHA}") # base64 salted sha
+
+ # unix crypt
+ (prefix "{CRYPT}")
+ (prefix "{crypt}")
+
+ # Plain text
+ (prefix "{PLAIN}")
+ (prefix "{plain}")
+ (prefix "{CLEAR}")
+ (prefix "{clear}")
+ ];
description = ''
Sets the password for the user account.
Passwords can be stored hashed or in plain text (not recommended).
@@ -77,7 +102,7 @@ in {
'';
};
};
- });
+ }));
};
dataDirectory = lib.mkOption {
@@ -160,25 +185,16 @@ in {
# 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;
- }
- '';
+ locations."/" = {
+ proxyPass = "http://${builtins.elemAt config.services.stalwart-mail.settings.server.listener.http.bind 0}";
+ recommendedProxySettings = true;
+ };
+
+ useACMEHost = "${cfg.fqdn}";
+ forceSSL = true;
};
redis = {
@@ -209,7 +225,7 @@ in {
security.acme.certs = {
"${cfg.fqdn}" = {
domain = cfg.fqdn;
- group = "stalwart-mail";
+ group = "stalwart-mail-certificates";
};
};
@@ -239,7 +255,7 @@ in {
{
directory = "${config.services.redis.servers."stalwart-mail".settings.dir}";
user = "stalwart-mail";
- group = "redis";
+ group = "redis-stalwart-mail";
mode = "0770";
}
];
@@ -249,10 +265,31 @@ in {
# 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";
+ groups = {
+ stalwart-mail = {
+ gid = config.vhack.constants.ids.gids.stalwart-mail;
+ };
+ stalwart-mail-certificates = {
+ gid = config.vhack.constants.ids.gids.stalwart-mail-certificates;
+ };
+ redis-stalwart-mail = {
+ gid = config.vhack.constants.ids.gids.redis-stalwart-mail;
+ };
+ };
+ users = {
+ nginx = {
+ extraGroups = ["stalwart-mail-certificates"];
+ };
+ stalwart-mail = {
+ isSystemUser = true;
+ group = "stalwart-mail";
+ uid = config.vhack.constants.ids.uids.stalwart-mail;
+ extraGroups = ["stalwart-mail-certificates"];
+ };
+ redis-stalwart-mail = {
+ group = "redis-stalwart-mail";
+ uid = config.vhack.constants.ids.uids.redis-stalwart-mail;
+ };
};
};
@@ -311,8 +348,7 @@ in {
${lib.getExe cfg.package} --config="$CACHE_DIRECTORY/mutable_config_file.toml"
'';
- Restart = "on-failure";
- RestartSec = 5;
+ Restart = "no";
KillMode = "process";
KillSignal = "SIGINT";
diff --git a/modules/by-name/st/stalwart-mail/settings.nix b/modules/vhack/st/stalwart-mail/settings.nix
index 7032ae0..dfaf63d 100644
--- a/modules/by-name/st/stalwart-mail/settings.nix
+++ b/modules/vhack/st/stalwart-mail/settings.nix
@@ -18,8 +18,13 @@
if cfg.security != null
then cfg.security.verificationMode
else "disable";
+
+ directory =
+ if cfg.principals == null
+ then "internal"
+ else "in-memory";
in {
- config.services.stalwart-mail.settings = lib.mkIf cfg.enable {
+ config.services.stalwart.settings = lib.mkIf cfg.enable {
# https://www.rfc-editor.org/rfc/rfc6376.html#section-3.3
signature = let
signatures =
@@ -192,7 +197,7 @@ in {
# Fetch the newest spam-filter rules not from github, but from the nix
# package.
- resource = "file://${cfg.package.passthru.spamfilter}/spam-filter.toml";
+ resource = "file://${cfg.package.passthru.spam-filter}/spam-filter.toml";
auto-update = false;
};
@@ -219,7 +224,7 @@ in {
require = true;
};
rcpt = {
- directory = "'in-memory'";
+ directory = "'${directory}'";
catch-all = true;
subaddressing = true;
};
@@ -236,7 +241,7 @@ in {
};
auth = {
mechanisms = ["LOGIN" "PLAIN"];
- directory = "'in-memory'";
+ directory = "'${directory}'";
require = true;
must-match-sender = true;
errors = {
@@ -339,13 +344,13 @@ in {
hostname = cfg.fqdn;
listener = {
- # TODO(@bpeetz): Add this <2025-02-08>
- # # HTTP (used for jmap)
- # "http" = {
- # bind = ["[::]:8080"];
- # protocol = "http";
- # tls.implicit = true;
- # };
+ # HTTP (used for jmap)
+ "http" = {
+ bind = ["127.0.0.1:8112"];
+ protocol = "http";
+ # handled by ngnix
+ tls.implicit = false;
+ };
# IMAP
"imap" = {
@@ -401,11 +406,12 @@ in {
certificate = "default";
};
- # TODO(@bpeetz): Configure that <2025-02-07>
- # http = {
- # url = "";
- # allowed-endpoint = ["404"];
- # };
+ http = {
+ url = "protocol + '://' + config_get('server.hostname') + ':' + local_port";
+
+ # We are behind a nginx proxy, and can thus trust this header.
+ use-x-forwarded = true;
+ };
auto-ban = {
# Ban if the same IP fails to login 10 times in a day
@@ -467,6 +473,14 @@ in {
# Perform “maintenance” every day at 3 am local time.
purge.frequency = "0 3 *";
};
+ "rocksdb-directory" = lib.mkIf (cfg.principals == null) {
+ type = "rocksdb";
+ path = "${cfg.dataDirectory}/storage/directory";
+ compression = "lz4";
+
+ # Perform “maintenance” every day at 1 am local time.
+ purge.frequency = "0 1 *";
+ };
"rocksdb-full-text-search" = {
type = "rocksdb";
path = "${cfg.dataDirectory}/storage/full-text-search";
@@ -505,7 +519,7 @@ in {
full-text.default-language = "en";
fts = "rocksdb-full-text-search";
- directory = "in-memory";
+ directory = "${directory}";
lookup = "redis";
@@ -516,9 +530,15 @@ in {
encryption.enable = false;
};
- directory."in-memory" = {
- type = "memory";
- inherit (cfg) principals;
+ directory = {
+ "in-memory" = lib.mkIf (cfg.principals != null) {
+ type = "memory";
+ inherit (cfg) principals;
+ };
+ "internal" = lib.mkIf (cfg.principals == null) {
+ type = "internal";
+ store = "rocksdb-directory";
+ };
};
certificate = {