diff options
Diffstat (limited to 'services/email.nix')
| -rw-r--r-- | services/email.nix | 246 |
1 files changed, 134 insertions, 112 deletions
diff --git a/services/email.nix b/services/email.nix index d3f60ab..5fbd04a 100644 --- a/services/email.nix +++ b/services/email.nix @@ -1,142 +1,164 @@ -{config, pkgs, lib, ...}: +{ config, lib, ... }: let - cfg = config.wilkuu.services.stalwart; - hostname = config.networking.hostName; -in + cfg = config.wilkuu.services.stalwart; + hostname = config.networking.hostName; +in { options.wilkuu.services.stalwart = with lib; { domain = mkOption { - type = types.str; - default = "mail.${hostname}.local"; - example = "mail.wilkuu.xyz"; - description = "Domain for http connections."; - }; + type = types.str; + default = "mail.${hostname}.local"; + example = "mail.wilkuu.xyz"; + description = "Domain for http connections."; + }; wellKnownDomains = mkOption { - type = types.listOf types.str; - default = [ "${hostname}.local" ]; - example = [ "wilkuu.xyz"] ; + type = types.listOf types.str; + default = [ "${hostname}.local" ]; + example = [ "wilkuu.xyz" ]; description = "Domain for well-known items"; }; doACME = mkEnableOption "Enable ACME for stalwart here"; - enable = mkEnableOption "Enable the email service"; - dataDir = mkOption { - type = types.path; - description = "Storage localtion for Stalwart user data"; - default = "/srv/data/stalwart"; - example = "/srv/data/stalwart"; - }; - }; + enable = mkEnableOption "Enable the email service"; + dataDir = mkOption { + type = types.path; + description = "Storage localtion for Stalwart user data"; + default = "/srv/data/stalwart"; + example = "/srv/data/stalwart"; + }; + }; - config = lib.mkIf cfg.enable (let - sopsPath = ../secrets/${hostname}/stalwart.yaml; - secrets = ["user_admin_password"]; - toSops = (sname: "stalwart/${sname}"); - toCredfilePath = (name: config.sops.secrets.${toSops name}.path); + config = lib.mkIf cfg.enable ( + let + sopsPath = ../secrets/${hostname}/stalwart.yaml; + secrets = [ "user_admin_password" ]; + toSops = (sname: "stalwart/${sname}"); + toCredfilePath = (name: config.sops.secrets.${toSops name}.path); toStalwartCred = name: "%{file:/run/credentials/stalwart-mail.service/${name}}%"; - - basicListener = proto: port: tls: { - bind = ["[::]:${toString port}"]; - protocol = proto; - tls.implicit = tls; - }; - proxyWellKnown = names: let - uris = map (n: "/.well-known/${n}") names; - in (lib.genAttrs uris (uri: { - proxyPass = "http://localhost:3080${uri}"; - recommendedProxySettings = true; - })); + basicListener = proto: port: tls: { + bind = [ "[::]:${toString port}" ]; + protocol = proto; + tls.implicit = tls; + }; + + proxyWellKnown = + names: + let + uris = map (n: "/.well-known/${n}") names; + in + (lib.genAttrs uris (uri: { + proxyPass = "http://localhost:3080${uri}"; + recommendedProxySettings = true; + })); - makeHttpRedirect = target: https: { return = "302 ${if https then "https" else "http"}://${target}";}; + makeHttpRedirect = target: https: { + return = "302 ${if https then "https" else "http"}://${target}"; + }; - in { - networking.hosts = { - "127.0.0.1" = [cfg.domain]; - }; + in + { + networking.hosts = { + "127.0.0.1" = [ cfg.domain ]; + }; - # Need this bc otherwise sops will complain for some reason - users = { + # Need this bc otherwise sops will complain for some reason + users = { groups.stalwart-mail = { }; users.stalwart-mail = { isSystemUser = true; group = "stalwart-mail"; }; - }; - - - # TODO: Move this into a util function or option; - sops.secrets = - (lib.genAttrs (map toSops secrets) - (name: { - sopsFile = sopsPath; - mode = "0440"; - owner = "stalwart-mail"; - })); + }; + # TODO: Move this into a util function or option; + sops.secrets = ( + lib.genAttrs (map toSops secrets) (_name: { + sopsFile = sopsPath; + mode = "0440"; + owner = "stalwart-mail"; + }) + ); - services.nginx.virtualHosts = (lib.genAttrs cfg.wellKnownDomains ( - (wdomain: { - locations = (proxyWellKnown ["jmap" "mta-sts.txt" "mail-v1.xml" "autoconfig/mail"]) - // (lib.genAttrs ["/.well_known/caldav" "/.well_known/webdav" ] (uri: (makeHttpRedirect "${cfg.domain}${uri}") cfg.doACME )); - }))) - // + services.nginx.virtualHosts = + (lib.genAttrs cfg.wellKnownDomains ( + (_wdomain: { + locations = + (proxyWellKnown [ + "jmap" + "mta-sts.txt" + "mail-v1.xml" + "autoconfig/mail" + ]) + // (lib.genAttrs [ "/.well_known/caldav" "/.well_known/webdav" ] ( + uri: (makeHttpRedirect "${cfg.domain}${uri}") cfg.doACME + )); + }) + )) + // - (lib.genAttrs (map (x: "${x}${cfg.domain}") ["" "autodiscover." "autoconfig."]) (domain: { - addSSL = cfg.doACME; - enableACME = cfg.doACME; - serverName = "${domain}"; - locations."/" = { - proxyPass = "http://localhost:3080"; - recommendedProxySettings = true; - }; - })); + (lib.genAttrs + (map (x: "${x}${cfg.domain}") [ + "" + "autodiscover." + "autoconfig." + ]) + (domain: { + addSSL = cfg.doACME; + enableACME = cfg.doACME; + serverName = "${domain}"; + locations."/" = { + proxyPass = "http://localhost:3080"; + recommendedProxySettings = true; + }; + }) + ); - - services.stalwart-mail = { - enable = true; - dataDir = cfg.dataDir; - openFirewall = false; - credentials = lib.genAttrs secrets toCredfilePath; - settings = { - server.listener = { - smtp = basicListener "smtp" 25 false; - submission = basicListener "smtp" 465 true; - imaptls = basicListener "imap" 993 true; - imap = basicListener "imap" 143 true; - webdav = basicListener "http" 3080 false; - jmap = basicListener "http" 3080 false; - http = basicListener "http" 3080 false; - }; + services.stalwart-mail = { + enable = true; + dataDir = cfg.dataDir; + openFirewall = false; + credentials = lib.genAttrs secrets toCredfilePath; + settings = { + server.listener = { + smtp = basicListener "smtp" 25 false; + submission = basicListener "smtp" 465 true; + imaptls = basicListener "imap" 993 true; + imap = basicListener "imap" 143 true; + webdav = basicListener "http" 3080 false; + jmap = basicListener "http" 3080 false; + http = basicListener "http" 3080 false; + }; - store.rocksdb = { - type = "rocksdb"; - path = cfg.dataDir; - compression = "lz4"; - }; + store.rocksdb = { + type = "rocksdb"; + path = cfg.dataDir; + compression = "lz4"; + }; - directory.internal = { - type = "internal"; - store = "rocksdb"; - }; + directory.internal = { + type = "internal"; + store = "rocksdb"; + }; - storage = { - data = "rocksdb"; - fts = "rocksdb"; - blob = "rocksdb"; - lookup = "rocksdb"; - directory = "internal"; - }; + storage = { + data = "rocksdb"; + fts = "rocksdb"; + blob = "rocksdb"; + lookup = "rocksdb"; + directory = "internal"; + }; - authentication.fallback-admin = { - user = "admin"; - secret = toStalwartCred "user_admin_password"; - }; + authentication.fallback-admin = { + user = "admin"; + secret = toStalwartCred "user_admin_password"; + }; - http = { - use-x-forwarded = true; - url = "protocol + \"${cfg.domain}\""; - }; + http = { + use-x-forwarded = true; + url = "protocol + \"${cfg.domain}\""; + }; + }; }; - }; - }); + } + ); } |
