diff options
Diffstat (limited to 'os')
-rw-r--r-- | os/common/configuration.nix | 5 | ||||
-rw-r--r-- | os/common/modules/stalwart-mail.nix | 163 | ||||
-rw-r--r-- | os/common/pkgs/stalwart-mail-config.nix | 43 | ||||
-rw-r--r-- | os/kay/modules/mail.nix | 107 | ||||
-rw-r--r-- | os/kay/modules/matrix-sliding-sync.nix | 22 | ||||
-rw-r--r-- | os/kay/modules/www.nix | 6 | ||||
-rw-r--r-- | os/kay/secrets.yaml | 6 |
7 files changed, 82 insertions, 270 deletions
diff --git a/os/common/configuration.nix b/os/common/configuration.nix index 44afc1a..74c4f9b 100644 --- a/os/common/configuration.nix +++ b/os/common/configuration.nix @@ -3,18 +3,15 @@ in { disabledModules = [ "services/networking/pppd.nix" - "services/mail/stalwart-mail.nix" ]; imports = [ ./modules/nix.nix ./modules/user.nix ./modules/environment.nix - ./modules/pppd.nix - ./modules/stalwart-mail.nix ]; - system.stateVersion = "24.11"; + system.stateVersion = "24.05"; time.timeZone = "Asia/Kolkata"; networking.useDHCP = false; diff --git a/os/common/modules/stalwart-mail.nix b/os/common/modules/stalwart-mail.nix deleted file mode 100644 index 68e8400..0000000 --- a/os/common/modules/stalwart-mail.nix +++ /dev/null @@ -1,163 +0,0 @@ -{ config, lib, pkgs, ... }: let - cfg = config.services.stalwart-mail; - configFormat = pkgs.formats.toml { }; - configFile = configFormat.generate "stalwart-mail.toml" cfg.settings; - dataDir = "/var/lib/stalwart-mail"; - - readTOML = - path: - builtins.fromTOML (builtins.unsafeDiscardStringContext (lib.readFile path)); - recursiveUpdateList = - attrList: - lib.lists.foldr (a1: a2: lib.attrsets.recursiveUpdate a1 a2) {} attrList; - mkOverrideRec = - priority: - content: - if lib.isAttrs content then - lib.mapAttrs (_: v: mkOverrideRec priority v) content - else - lib.mkOverride priority content; - mkOptionDefaultRec = mkOverrideRec 1500; - - cfgPkg = pkgs.callPackage ../pkgs/stalwart-mail-config.nix {}; - cfgFiles = (readTOML "${cfgPkg}/config.toml").include.files; - settingsDefault = recursiveUpdateList (map (path: readTOML path) cfgFiles); -in { - options.services.stalwart-mail = { - enable = lib.mkEnableOption "the Stalwart all-in-one email server"; - package = lib.mkPackageOption pkgs "stalwart-mail" { }; - - loadCredential = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = []; - example = [ "dkim.private:/path/to/stalwart.private" ]; - description = '' - This can be used to pass secrets to the systemd service without adding them to - the nix store. - See the LoadCredential section of systemd.exec manual for more information. - ''; - }; - - settings = lib.mkOption { - inherit (configFormat) type; - default = { }; - description = '' - Configuration options for the Stalwart email server. - See <https://stalw.art/docs/category/configuration> for available options. - - By default, the module is configured to store everything locally. - ''; - }; - }; - - config = lib.mkIf cfg.enable { - # set the default upstream settings - # assumptions - # 1. ./config.toml exists and only containts include.files and macros - # 2. no other files containts include.files - services.stalwart-mail.settings = mkOptionDefaultRec - (lib.attrsets.recursiveUpdate settingsDefault { - macros.base_path = dataDir; - server.run-as.user = {}; - server.run-as.group = {}; - global.tracing.method = "stdout"; - # outliers as of v0.6.0 - acme."letsencrypt".cache = "${cfg.settings.macros.base_path}/acme"; - }); - - assertions = let - m = cfg.settings.macros; - - mkMacroMessage = - opt: - "config.stalwart-mail.settings.macros.${opt} can not be empty"; - in [ - { - assertion = m ? host - && m.host != "" - && m.host != null; - message = mkMacroMessage "host"; - } - { - assertion = m ? default_domain - && m.default_domain != "" - && m.default_domain != null; - message = mkMacroMessage "default_domain"; - } - { - assertion = m ? default_directory - && m.default_directory != "" - && m.default_directory != null; - message = mkMacroMessage "default_directory"; - } - { - assertion = m ? default_store && - m.default_store != "" - && m.default_store != null; - message = mkMacroMessage "default_store"; - } - ]; - - systemd.services.stalwart-mail = { - wantedBy = [ "multi-user.target" ]; - after = [ "local-fs.target" "network.target" ]; - - 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"; - LoadCredential = cfg.loadCredential; - - # 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"; - }; - }; - - # Make admin commands available in the shell - environment.systemPackages = [ cfg.package cfgPkg ]; - }; - - meta = { - maintainers = with lib.maintainers; [ happysalada pacien ]; - }; -} diff --git a/os/common/pkgs/stalwart-mail-config.nix b/os/common/pkgs/stalwart-mail-config.nix deleted file mode 100644 index 77fc366..0000000 --- a/os/common/pkgs/stalwart-mail-config.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ lib, - stdenvNoCC, - fetchzip, - stalwart-mail, -}: - -stdenvNoCC.mkDerivation { - pname = stalwart-mail.pname + "-config"; - version = stalwart-mail.version; - - src = let - rev = stalwart-mail.src.rev; - owner = stalwart-mail.src.owner; - repo = stalwart-mail.src.repo; - in fetchzip { - url = "https://github.com/${owner}/${repo}/raw/${rev}/resources/config.zip"; - # gives us a chance to manually verify config changes, if not use - # stalwart-mail.src - hash = "sha256-ji7+f3BGzVEb9gp5BXCStPR4/Umy93OTMA+DhYI/azk="; - }; - - outputs = [ "out" ]; - patchPhase = '' - # TODO: remove me - # toml spec violation, author said this will be fixed on the next realase - sed -e 's/\[storage.fts\]//g' -e 's/default-language = "en"//g' \ - -i ./common/store.toml - - # outliers as of 0.6.0 - # smtp/signature.toml:#public-key = "file://%{BASE_PATH}%/etc/dkim/%{DEFAULT_DOMAIN}%.cert" - # smtp/signature.toml:private-key = "file://%{BASE_PATH}%/etc/dkim/%{DEFAULT_DOMAIN}%.key" - # common/tls.toml:cache = "%{BASE_PATH}%/etc/acme" - find -type f \ - -name '*.toml' \ - -exec sed 's=%{BASE_PATH}%/etc=${placeholder "out"}=g' -i {} \; - ''; - installPhase = "cp -r ./ $out"; - - meta = stalwart-mail.meta // { - description = "Configs for" + stalwart-mail.meta.description; - maintainers = with lib.maintainers; [ sinanmohd ]; - }; -} diff --git a/os/kay/modules/mail.nix b/os/kay/modules/mail.nix index ee91f78..5c8cb96 100644 --- a/os/kay/modules/mail.nix +++ b/os/kay/modules/mail.nix @@ -1,9 +1,7 @@ { config, ... }: let ipv6 = "2001:470:ee65::1337"; domain = config.global.userdata.domain; - username = config.global.userdata.name; - secret = "$argon2i$v=19$m=4096,t=3,p=1$SWV5aWU3YWUgZWFTNm9oc28gTGFvdDdlRG8ga2FTaWVjaDYgYWV0aDFHb28$O/sDv7oy9wUxFjvKoxB5o8ZnPvjYJo9DjX0C/AZQFF0"; email = [ "${username}@${domain}" "official@${domain}" @@ -14,76 +12,99 @@ credentials_directory = "/run/credentials/stalwart-mail.service"; in { - networking.firewall.allowedTCPPorts = [ - 25 # smto - 465 # submission - 587 # submissions - 993 # imap ssl - 4190 # managesieve - ]; - security.acme.certs.${domain}.postRun = "systemctl restart stalwart-mail.service"; sops.secrets = { "mail.${domain}/dkim_rsa" = {}; "mail.${domain}/dkim_ed25519" = {}; + "mail.${domain}/password" = {}; }; - services.stalwart-mail = { - enable = true; - loadCredential = [ - "dkim_rsa:${config.sops.secrets."mail.${domain}/dkim_rsa".path}" - "dkim_ed25519:${config.sops.secrets."mail.${domain}/dkim_ed25519".path}" + systemd.services.stalwart-mail.serviceConfig.loadCredential = [ + "password:${config.sops.secrets."mail.${domain}/password".path}" - "cert:${config.security.acme.certs.${domain}.directory}/fullchain.pem" - "key:${config.security.acme.certs.${domain}.directory}/key.pem" - ]; + "dkim_rsa:${config.sops.secrets."mail.${domain}/dkim_rsa".path}" + "dkim_ed25519:${config.sops.secrets."mail.${domain}/dkim_ed25519".path}" - settings = { - macros = { - host = "mail.${domain}"; - default_domain = domain; - default_directory = "in-memory"; - default_store = "sqlite"; - }; + "cert:${config.security.acme.certs.${domain}.directory}/fullchain.pem" + "key:${config.security.acme.certs.${domain}.directory}/key.pem" + ]; + services.stalwart-mail = { + enable = false; + openFirewall = true; + + settings = { queue.outbound = { ip-strategy = "ipv6_then_ipv4"; source-ip.v6 = "['${ipv6}']"; tls.starttls = "optional"; }; + server.listener = { - smtp.bind = [ "[${ipv6}]:25" "0.0.0.0:25" ]; - jmap.bind = [ "[::]:8034" ]; + smtp = { + bind = [ "[${ipv6}]:25" "0.0.0.0:25" ]; + protocol = "smtp"; + }; + submission = { + bind = "[::]:587"; + protocol = "smtp"; + }; + submissions = { + bind = "[::]:465"; + protocol = "smtp"; + tls.implicit = true; + }; + imaptls = { + bind = "[::]:993"; + protocol = "imap"; + }; + http = { + bind = "[::]:8085"; + protocol = "http"; + }; }; signature = { rsa = { - private-key = "file://${credentials_directory}/dkim_rsa"; + private-key = "%{file:/${credentials_directory}/dkim_rsa}%"; + inherit domain; selector = "rsa"; - set-body-length = true; + headers = ["From" "To" "Date" "Subject" "Message-ID"]; + algorithm = "rsa-sha-256"; + canonicalization = "relaxed/relaxed"; # what + + expire = "10d"; + report = true; }; ed25519 = { - public-key = "EHk924AruF9Y0Xaf009rpRl+yGusjmjT1Zeho67BnDU="; - private-key = "file://${credentials_directory}/dkim_ed25519"; - domain = "%{DEFAULT_DOMAIN}%"; + private-key = "%{file:/${credentials_directory}/dkim_ed25519}%"; + inherit domain; selector = "ed25519"; - headers = [ "From" "To" "Date" "Subject" "Message-ID" ]; + headers = ["From" "To" "Date" "Subject" "Message-ID"]; algorithm = "ed25519-sha256"; - canonicalization = "relaxed/relaxed"; - set-body-length = true; + canonicalization = "relaxed/relaxed"; # what + + expire = "10d"; report = true; }; }; certificate."default" = { - cert = "file://${credentials_directory}/cert"; - private-key = "file://${credentials_directory}/key"; + cert = "%{file:/${credentials_directory}/cert}%"; + private-key = "%{file:/${credentials_directory}/key}%"; }; - storage.blob = "fs"; - store = { - fs.disable = false; - sqlite.disable = false; + storage = { + data = "rocksdb"; + fts = "rocksdb"; + blob = "rocksdb"; + lookup = "rocksdb"; + directory = "in-memory"; + }; + store.rocksdb = { + type = "rocksdb"; + path = "rocksdb"; + compression = "lz4"; }; directory."in-memory" = { @@ -93,13 +114,13 @@ in { principals = [ { inherit email; - inherit secret; + secret = "%{file:/${credentials_directory}/password}%"; name = username; type = "admin"; } { # for mta-sts & dmarc reports email = "reports${domain}"; - inherit secret; + secret = "%{file:/${credentials_directory}/password}%"; name = "reports"; type = "individual"; } diff --git a/os/kay/modules/matrix-sliding-sync.nix b/os/kay/modules/matrix-sliding-sync.nix index 03ab9fc..a4438c6 100644 --- a/os/kay/modules/matrix-sliding-sync.nix +++ b/os/kay/modules/matrix-sliding-sync.nix @@ -4,15 +4,15 @@ let domain = config.global.userdata.domain; in { - sops.secrets."matrix-${domain}/sliding_sync" = {}; - - services.matrix-sliding-sync = { - enable = true; - environmentFile = config.sops.secrets."matrix-${domain}/sliding_sync".path; - - settings = { - SYNCV3_LOG_LEVEL = "warn"; - SYNCV3_SERVER = "http://127.0.0.1:${toString config.services.dendrite.httpPort}"; - }; - }; + # sops.secrets."matrix-${domain}/sliding_sync" = {}; + # + # services.matrix-sliding-sync = { + # enable = true; + # environmentFile = config.sops.secrets."matrix-${domain}/sliding_sync".path; + # + # settings = { + # SYNCV3_LOG_LEVEL = "warn"; + # SYNCV3_SERVER = "http://127.0.0.1:${toString config.services.dendrite.httpPort}"; + # }; + # }; } diff --git a/os/kay/modules/www.nix b/os/kay/modules/www.nix index 594d9b9..04181d0 100644 --- a/os/kay/modules/www.nix +++ b/os/kay/modules/www.nix @@ -58,7 +58,7 @@ in "/.well-known/matrix/client".return = '' 200 '${builtins.toJSON { "m.homeserver".base_url = "https://${domain}"; - "org.matrix.msc3575.proxy".url = "https://${domain}"; + # "org.matrix.msc3575.proxy".url = "https://${domain}"; }}' ''; @@ -66,8 +66,8 @@ in config.services.dendrite.httpPort }"; - "/_matrix/client/unstable/org.matrix.msc3575/sync".proxyPass = - "http://${config.services.matrix-sliding-sync.settings.SYNCV3_BINDADDR}"; + # "/_matrix/client/unstable/org.matrix.msc3575/sync".proxyPass = + # "http://${config.services.matrix-sliding-sync.settings.SYNCV3_BINDADDR}"; }; }; diff --git a/os/kay/secrets.yaml b/os/kay/secrets.yaml index dae9fe0..7346605 100644 --- a/os/kay/secrets.yaml +++ b/os/kay/secrets.yaml @@ -13,7 +13,7 @@ matrix-sinanmohd.com: mail.sinanmohd.com: dkim_rsa: ENC[AES256_GCM,data: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,iv:dPnpNUPSDiq5C14YzDM2K4mFHNRFgc6p+X3Zu33OH60=,tag:MhgfV3z1wcbAfpwZmVWczw==,type:str] dkim_ed25519: ENC[AES256_GCM,data:bberg3vGG9M3iPH1aLA+wIU6KNnxHRZxpGU5zT5Gqo9lohQa1wBDXCwsP0JaSfg56dhh9ZxF5HFd4V0nUzL6QMIeiExGkZmtdluaqki3fwFCssILch9pWOuM71Q1d7vi1eIN5PrAuX+6m8bmQBd1JIR+Kbz8dQ==,iv:C7wEFU7/xCh8LzyKXHSzgTX/L9OkmGWTnl5A94GLogw=,tag:j+sYtzzGN9guWa6T+ZUzbw==,type:str] - sinan: ENC[AES256_GCM,data:F3lhwjf6dZpDSmU=,iv:TCIzQeUBqgjqc+/z3Hh1tYpm3OeLGLpVUDeo6ufP7/4=,tag:TXUI8noaK5jyLpo8D+94jQ==,type:str] + password: ENC[AES256_GCM,data:w8kc2CJwab7qTFQeejXCjUBkfHSKhec9YTpCPjT8,iv:lj634vQoWcrJlc+lh9GL+Co/T+QPln8NHOZoT3ky3EU=,tag:gAeD4EjE4uQFCRM4I5ZakQ==,type:str] misc: wireguard: ENC[AES256_GCM,data:kbUtxJv3xSmikJWgtu87TSo5N8tUb2BiH3dH3oOV36waYyXI3bp2aBeAl1k=,iv:yB4UIyMDNRS+JmSnt9XuBhNRTLz+k0FqkK4ofjosRto=,tag:BDSD9SfQuQppKT4+6Cu65w==,type:str] sops: @@ -40,8 +40,8 @@ sops: OXgwSml4bkc1dnloNUFsRGFFcXFHc2cK26l2eiKbZUkogmAXoha6HTUs3YFKixYz bTkpKKyOAIIin3YM975wwvkCuWNG4tbnHBHQFh5JGK2OEyLDXuV7Pg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-11-22T16:14:24Z" - mac: ENC[AES256_GCM,data:KPA/xxdhEO7yY9AQZmC9oslMP04RTj8RsJPNAei8UPfMCoZIp9Hyzsa7qsej+ivl/GBFT0r/4PWrxbwMTSoS4N5SiSF0MxF7eRy9UZg8EynRp1R/duImpWgUcK3wtxsDw+XtgQv5NWFrfJQvKUrRGlKACfk3Ci+tiHBVYX0AbZQ=,iv:Djje4ORwIHMvdNJd9MGRs2rVwIZ1pd94OLG/IrO59Ik=,tag:V3Em/dWJs1gyo9Z7lCK3GQ==,type:str] + lastmodified: "2025-01-05T11:34:39Z" + mac: ENC[AES256_GCM,data:gWDUFmyZceCJsQQfyUot5D50KLh9+/wDjsxw4btkq1r7kWOQmYlkwdfAr3ZAHWWP1uhzq0cvP7VuucG3dK5KY/q8j6bkIG4O8RYhecpx7Qnc87z55kt+xUoz/shYJ238iwcX5MpbmL97HHUy4Uqkyi0Fz8vOqoGMsiLcp0OTj2s=,iv:6QeEwCUPCxaUZ445oSrxpe0DkATc/mRjnEWRZcFWE/c=,tag:pf9iU2vp0pcF/2kdKdVy9g==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.8.1 |