From fbcd590bfe6327748aff33ba0e0b20ef58f561a3 Mon Sep 17 00:00:00 2001 From: Kaare Hoff Skovgaard Date: Wed, 30 Jul 2025 11:07:45 +0200 Subject: [PATCH 1/3] Final attempt at getting stalwart working before revert Non working parts: 1. OIDC login, stalwart assumes the entire token is base64 encoded, which it is not. 2. Apparently there's no support for mixed directories, allowing both logins from ldap and from internal database. I want this in order to support accounts for services as well as persons. --- .../nixos/infrastructure/mailserver/acme.nix | 1 + .../infrastructure/mailserver/default.nix | 35 +++++++-- .../nixos/infrastructure/mailserver/dkim.nix | 4 + .../nixos/infrastructure/mailserver/ldap.nix | 3 + .../mailserver/openid-connect.nix | 74 ++++++++++--------- .../mailserver/package/nixos-module.nix | 15 +++- .../infrastructure/mailserver/prometheus.nix | 7 +- .../mx.kaareskovgaard.net/default.nix | 2 + 8 files changed, 95 insertions(+), 46 deletions(-) diff --git a/nix/modules/nixos/infrastructure/mailserver/acme.nix b/nix/modules/nixos/infrastructure/mailserver/acme.nix index c13d0ca..ba54139 100644 --- a/nix/modules/nixos/infrastructure/mailserver/acme.nix +++ b/nix/modules/nixos/infrastructure/mailserver/acme.nix @@ -19,6 +19,7 @@ in services.stalwart-mail.settings = { certificate.default = { cert = "%{file:${acmeDir}/fullchain.pem}%"; + default = true; private-key = "%{file:${config.security.acme.certs.${fqdn}.directory}/key.pem}%"; }; }; diff --git a/nix/modules/nixos/infrastructure/mailserver/default.nix b/nix/modules/nixos/infrastructure/mailserver/default.nix index a4b7289..9e5bc73 100644 --- a/nix/modules/nixos/infrastructure/mailserver/default.nix +++ b/nix/modules/nixos/infrastructure/mailserver/default.nix @@ -36,8 +36,34 @@ in enable = true; package = pkgs.callPackage ./package/package.nix { }; settings = { + config = { + local-keys = + # defaults + [ + "store.*" + "directory.*" + "tracer.*" + "!server.blocked-ip.*" + "!server.allowed-ip.*" + "server.*" + "authentication.fallback-admin.*" + "cluster.*" + "config.local-keys.*" + "storage.data" + "storage.blob" + "storage.lookup" + "storage.fts" + "storage.directory" + "certificate.*" + ] + # KHS addded + ++ [ + "http.*" + "lookup.default.*" + ]; + }; http = { - url = "https://${fqdn}"; + url = "'https://${fqdn}'"; use-x-forwarded = true; }; server = { @@ -63,13 +89,9 @@ in protocol = "imap"; tls.implicit = true; }; - jmap = { - bind = "[::]:8080"; - url = "https://${fqdn}"; - protocol = "jmap"; - }; management = { bind = "[::]:8080"; + url = "https://${fqdn}"; protocol = "http"; }; }; @@ -78,7 +100,6 @@ in hostname = fqdn; domain = "kaareskovgaard.net"; }; - spam-filter.resource = "${config.services.stalwart-mail.package.spam-filter}/spam-filter.toml"; }; }; # TODO: Include a similiar rule for openstack diff --git a/nix/modules/nixos/infrastructure/mailserver/dkim.nix b/nix/modules/nixos/infrastructure/mailserver/dkim.nix index 894c6e5..68ddd50 100644 --- a/nix/modules/nixos/infrastructure/mailserver/dkim.nix +++ b/nix/modules/nixos/infrastructure/mailserver/dkim.nix @@ -213,6 +213,10 @@ in ]) cfg.domains ); services.stalwart-mail.settings = { + config.local-keys = [ + "auth.*" + "signature.*" + ]; auth.dkim = { sign = authDkim ++ [ (otherwise false) diff --git a/nix/modules/nixos/infrastructure/mailserver/ldap.nix b/nix/modules/nixos/infrastructure/mailserver/ldap.nix index c009b5a..ed1c0ed 100644 --- a/nix/modules/nixos/infrastructure/mailserver/ldap.nix +++ b/nix/modules/nixos/infrastructure/mailserver/ldap.nix @@ -17,6 +17,9 @@ in config = lib.mkIf cfg.enable { services.stalwart-mail.settings = { + config.local-keys = [ + "storage.ldap.*" + ]; storage = { directory = "ldap"; }; diff --git a/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix b/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix index 43c383f..2fe2075 100644 --- a/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix +++ b/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix @@ -5,41 +5,43 @@ let in { config = lib.mkIf cfg.enable { - # khscodes.services.vault-agent.templates = [ - # { - # contents = '' - # {{- with secret "kanidm/data/apps/dovecot" -}} - # scope = email openid profile - # username_attribute = username - # debug = yes - # introspection_url = https://dovecot:{{ .Data.data.basic_secret }}@login.kaareskovgaard.net/oauth2/token/introspect - # introspection_mode = post - # {{- end -}} - # ''; - # destination = oauthConfigFile; - # perms = "0600"; - # owner = "root"; - # group = "root"; - # restartUnits = [ "dovecot2.service" ]; - # } - # ]; - # services.dovecot2.extraConfig = '' - # auth_mechanisms = $auth_mechanisms oauthbearer xoauth2 - - # passdb { - # driver = oauth2 - # mechanisms = xoauth2 oauthbearer - # args = ${oauthConfigFile} - # } - # ''; - # systemd.services.dovecot2 = { - # serviceConfig.ReadOnlyPaths = [ - # oauthConfigFile - # ]; - # unitConfig.ConditionPathExists = [ - # oauthConfigFile - # ]; - # }; - + services.stalwart-mail.settings = { + tracer.stdout.level = "trace"; + directory.oidc = { + type = "oidc"; + url = "ldaps://login.kaareskovgaard.net"; + timeout = "1s"; + endpoint.url = "https://login.kaareskovgaard.net/oauth2/openid/dovecot/userinfo"; + endpoint.method = "userinfo"; + auth.method = "user-token"; + auth.username = "dovecot"; + auth.secret = "%{file:${oauthConfigFile}}%"; + fields.email = "email"; + fields.username = "preferred_username"; + fields.full-name = "name"; + }; + }; + khscodes.services.vault-agent.templates = [ + { + contents = '' + {{- with secret "kanidm/data/apps/dovecot" -}} + {{ .Data.data.basic_secret }}@login.kaareskovgaard.net/oauth2/token/introspect + {{- end -}} + ''; + destination = oauthConfigFile; + perms = "0600"; + owner = "stalwart-mail"; + group = "stalwart-mail"; + restartUnits = [ "stalwart-mail.service" ]; + } + ]; + systemd.services.stalwart-mail = { + serviceConfig.ReadOnlyPaths = [ + oauthConfigFile + ]; + unitConfig.ConditionPathExists = [ + oauthConfigFile + ]; + }; }; } diff --git a/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix b/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix index 5d4160c..9aa349f 100644 --- a/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix +++ b/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix @@ -1,4 +1,5 @@ -# This file contains patches for Nixos 25.05 to be compatible with new stalwart mail +# This file contains patches for Nixos 25.05 to be compatible with new stalwart mail. +# Also some minor patches to avoid having warnings on startup { lib, config, @@ -10,6 +11,17 @@ let configFile = configFormat.generate "stalwart-mail.toml" config.services.stalwart-mail.settings; in { + services.stalwart-mail.settings = { + config.local-keys = [ + "spam-filter.resource" + ] + ++ [ + # I think these maybe should be added to nixpkgs? + "resolver.*" + "webadmin.*" + ]; + spam-filter.resource = "file://${config.services.stalwart-mail.package.spam-filter}/spam-filter.toml"; + }; systemd.services.stalwart-mail = lib.mkIf config.services.stalwart-mail.enable { serviceConfig = { User = "stalwart-mail"; @@ -18,6 +30,7 @@ in "" "${lib.getExe config.services.stalwart-mail.package} --config=${configFile}" ]; + ReadOnlyPaths = [ "${config.services.stalwart-mail.package.spam-filter}/spam-filter.toml" ]; }; }; } diff --git a/nix/modules/nixos/infrastructure/mailserver/prometheus.nix b/nix/modules/nixos/infrastructure/mailserver/prometheus.nix index 9c1e7f5..51d9dcf 100644 --- a/nix/modules/nixos/infrastructure/mailserver/prometheus.nix +++ b/nix/modules/nixos/infrastructure/mailserver/prometheus.nix @@ -5,8 +5,11 @@ let in { config = lib.mkIf cfg.enable { - services.stalwart-mail.settings.metrics.prometheus = { - enable = true; + services.stalwart-mail.settings = { + config.local-keys = [ "metrics.prometheus.*" ]; + metrics.prometheus = { + enable = true; + }; }; # Don't expose the endpoint khscodes.services.nginx.virtualHosts."${fqdn}".locations."=/metrics/prometheus" = { diff --git a/nix/systems/aarch64-linux/mx.kaareskovgaard.net/default.nix b/nix/systems/aarch64-linux/mx.kaareskovgaard.net/default.nix index 737fa57..0d92018 100644 --- a/nix/systems/aarch64-linux/mx.kaareskovgaard.net/default.nix +++ b/nix/systems/aarch64-linux/mx.kaareskovgaard.net/default.nix @@ -74,6 +74,8 @@ $config['oauth_identity_uri'] = 'https://login.kaareskovgaard.net/oauth2/openid/dovecot/userinfo'; $config['oauth_identity_fields'] = ['preferred_username']; $config['oauth_scope'] = 'email openid profile'; + # Don't show login dialog, just redirect to oauth login page + # $config['oauth_login_redirect'] = true; ''; }; khscodes.services.nginx = { From ad84cfae7e507b823557a1c03600e0e0dfeba4fe Mon Sep 17 00:00:00 2001 From: Kaare Hoff Skovgaard Date: Wed, 30 Jul 2025 11:11:14 +0200 Subject: [PATCH 2/3] Revert "Final attempt at getting stalwart working before revert" This reverts commit fbcd590bfe6327748aff33ba0e0b20ef58f561a3. --- .../nixos/infrastructure/mailserver/acme.nix | 1 - .../infrastructure/mailserver/default.nix | 35 ++------- .../nixos/infrastructure/mailserver/dkim.nix | 4 - .../nixos/infrastructure/mailserver/ldap.nix | 3 - .../mailserver/openid-connect.nix | 74 +++++++++---------- .../mailserver/package/nixos-module.nix | 15 +--- .../infrastructure/mailserver/prometheus.nix | 7 +- .../mx.kaareskovgaard.net/default.nix | 2 - 8 files changed, 46 insertions(+), 95 deletions(-) diff --git a/nix/modules/nixos/infrastructure/mailserver/acme.nix b/nix/modules/nixos/infrastructure/mailserver/acme.nix index ba54139..c13d0ca 100644 --- a/nix/modules/nixos/infrastructure/mailserver/acme.nix +++ b/nix/modules/nixos/infrastructure/mailserver/acme.nix @@ -19,7 +19,6 @@ in services.stalwart-mail.settings = { certificate.default = { cert = "%{file:${acmeDir}/fullchain.pem}%"; - default = true; private-key = "%{file:${config.security.acme.certs.${fqdn}.directory}/key.pem}%"; }; }; diff --git a/nix/modules/nixos/infrastructure/mailserver/default.nix b/nix/modules/nixos/infrastructure/mailserver/default.nix index 9e5bc73..a4b7289 100644 --- a/nix/modules/nixos/infrastructure/mailserver/default.nix +++ b/nix/modules/nixos/infrastructure/mailserver/default.nix @@ -36,34 +36,8 @@ in enable = true; package = pkgs.callPackage ./package/package.nix { }; settings = { - config = { - local-keys = - # defaults - [ - "store.*" - "directory.*" - "tracer.*" - "!server.blocked-ip.*" - "!server.allowed-ip.*" - "server.*" - "authentication.fallback-admin.*" - "cluster.*" - "config.local-keys.*" - "storage.data" - "storage.blob" - "storage.lookup" - "storage.fts" - "storage.directory" - "certificate.*" - ] - # KHS addded - ++ [ - "http.*" - "lookup.default.*" - ]; - }; http = { - url = "'https://${fqdn}'"; + url = "https://${fqdn}"; use-x-forwarded = true; }; server = { @@ -89,9 +63,13 @@ in protocol = "imap"; tls.implicit = true; }; - management = { + jmap = { bind = "[::]:8080"; url = "https://${fqdn}"; + protocol = "jmap"; + }; + management = { + bind = "[::]:8080"; protocol = "http"; }; }; @@ -100,6 +78,7 @@ in hostname = fqdn; domain = "kaareskovgaard.net"; }; + spam-filter.resource = "${config.services.stalwart-mail.package.spam-filter}/spam-filter.toml"; }; }; # TODO: Include a similiar rule for openstack diff --git a/nix/modules/nixos/infrastructure/mailserver/dkim.nix b/nix/modules/nixos/infrastructure/mailserver/dkim.nix index 68ddd50..894c6e5 100644 --- a/nix/modules/nixos/infrastructure/mailserver/dkim.nix +++ b/nix/modules/nixos/infrastructure/mailserver/dkim.nix @@ -213,10 +213,6 @@ in ]) cfg.domains ); services.stalwart-mail.settings = { - config.local-keys = [ - "auth.*" - "signature.*" - ]; auth.dkim = { sign = authDkim ++ [ (otherwise false) diff --git a/nix/modules/nixos/infrastructure/mailserver/ldap.nix b/nix/modules/nixos/infrastructure/mailserver/ldap.nix index ed1c0ed..c009b5a 100644 --- a/nix/modules/nixos/infrastructure/mailserver/ldap.nix +++ b/nix/modules/nixos/infrastructure/mailserver/ldap.nix @@ -17,9 +17,6 @@ in config = lib.mkIf cfg.enable { services.stalwart-mail.settings = { - config.local-keys = [ - "storage.ldap.*" - ]; storage = { directory = "ldap"; }; diff --git a/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix b/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix index 2fe2075..43c383f 100644 --- a/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix +++ b/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix @@ -5,43 +5,41 @@ let in { config = lib.mkIf cfg.enable { - services.stalwart-mail.settings = { - tracer.stdout.level = "trace"; - directory.oidc = { - type = "oidc"; - url = "ldaps://login.kaareskovgaard.net"; - timeout = "1s"; - endpoint.url = "https://login.kaareskovgaard.net/oauth2/openid/dovecot/userinfo"; - endpoint.method = "userinfo"; - auth.method = "user-token"; - auth.username = "dovecot"; - auth.secret = "%{file:${oauthConfigFile}}%"; - fields.email = "email"; - fields.username = "preferred_username"; - fields.full-name = "name"; - }; - }; - khscodes.services.vault-agent.templates = [ - { - contents = '' - {{- with secret "kanidm/data/apps/dovecot" -}} - {{ .Data.data.basic_secret }}@login.kaareskovgaard.net/oauth2/token/introspect - {{- end -}} - ''; - destination = oauthConfigFile; - perms = "0600"; - owner = "stalwart-mail"; - group = "stalwart-mail"; - restartUnits = [ "stalwart-mail.service" ]; - } - ]; - systemd.services.stalwart-mail = { - serviceConfig.ReadOnlyPaths = [ - oauthConfigFile - ]; - unitConfig.ConditionPathExists = [ - oauthConfigFile - ]; - }; + # khscodes.services.vault-agent.templates = [ + # { + # contents = '' + # {{- with secret "kanidm/data/apps/dovecot" -}} + # scope = email openid profile + # username_attribute = username + # debug = yes + # introspection_url = https://dovecot:{{ .Data.data.basic_secret }}@login.kaareskovgaard.net/oauth2/token/introspect + # introspection_mode = post + # {{- end -}} + # ''; + # destination = oauthConfigFile; + # perms = "0600"; + # owner = "root"; + # group = "root"; + # restartUnits = [ "dovecot2.service" ]; + # } + # ]; + # services.dovecot2.extraConfig = '' + # auth_mechanisms = $auth_mechanisms oauthbearer xoauth2 + + # passdb { + # driver = oauth2 + # mechanisms = xoauth2 oauthbearer + # args = ${oauthConfigFile} + # } + # ''; + # systemd.services.dovecot2 = { + # serviceConfig.ReadOnlyPaths = [ + # oauthConfigFile + # ]; + # unitConfig.ConditionPathExists = [ + # oauthConfigFile + # ]; + # }; + }; } diff --git a/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix b/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix index 9aa349f..5d4160c 100644 --- a/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix +++ b/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix @@ -1,5 +1,4 @@ -# This file contains patches for Nixos 25.05 to be compatible with new stalwart mail. -# Also some minor patches to avoid having warnings on startup +# This file contains patches for Nixos 25.05 to be compatible with new stalwart mail { lib, config, @@ -11,17 +10,6 @@ let configFile = configFormat.generate "stalwart-mail.toml" config.services.stalwart-mail.settings; in { - services.stalwart-mail.settings = { - config.local-keys = [ - "spam-filter.resource" - ] - ++ [ - # I think these maybe should be added to nixpkgs? - "resolver.*" - "webadmin.*" - ]; - spam-filter.resource = "file://${config.services.stalwart-mail.package.spam-filter}/spam-filter.toml"; - }; systemd.services.stalwart-mail = lib.mkIf config.services.stalwart-mail.enable { serviceConfig = { User = "stalwart-mail"; @@ -30,7 +18,6 @@ in "" "${lib.getExe config.services.stalwart-mail.package} --config=${configFile}" ]; - ReadOnlyPaths = [ "${config.services.stalwart-mail.package.spam-filter}/spam-filter.toml" ]; }; }; } diff --git a/nix/modules/nixos/infrastructure/mailserver/prometheus.nix b/nix/modules/nixos/infrastructure/mailserver/prometheus.nix index 51d9dcf..9c1e7f5 100644 --- a/nix/modules/nixos/infrastructure/mailserver/prometheus.nix +++ b/nix/modules/nixos/infrastructure/mailserver/prometheus.nix @@ -5,11 +5,8 @@ let in { config = lib.mkIf cfg.enable { - services.stalwart-mail.settings = { - config.local-keys = [ "metrics.prometheus.*" ]; - metrics.prometheus = { - enable = true; - }; + services.stalwart-mail.settings.metrics.prometheus = { + enable = true; }; # Don't expose the endpoint khscodes.services.nginx.virtualHosts."${fqdn}".locations."=/metrics/prometheus" = { diff --git a/nix/systems/aarch64-linux/mx.kaareskovgaard.net/default.nix b/nix/systems/aarch64-linux/mx.kaareskovgaard.net/default.nix index 0d92018..737fa57 100644 --- a/nix/systems/aarch64-linux/mx.kaareskovgaard.net/default.nix +++ b/nix/systems/aarch64-linux/mx.kaareskovgaard.net/default.nix @@ -74,8 +74,6 @@ $config['oauth_identity_uri'] = 'https://login.kaareskovgaard.net/oauth2/openid/dovecot/userinfo'; $config['oauth_identity_fields'] = ['preferred_username']; $config['oauth_scope'] = 'email openid profile'; - # Don't show login dialog, just redirect to oauth login page - # $config['oauth_login_redirect'] = true; ''; }; khscodes.services.nginx = { From 9af8f29b4822572b660747ab66cc681d593af0a3 Mon Sep 17 00:00:00 2001 From: Kaare Hoff Skovgaard Date: Wed, 30 Jul 2025 11:11:17 +0200 Subject: [PATCH 3/3] Revert "Attempt at using stalwart again" This reverts commit 2d3e02ad7858b8f27591425ff626ef906a0f0403. --- .../nixos/infrastructure/mailserver/acme.nix | 33 +-- .../mailserver/admin_password.nix | 67 ------ .../infrastructure/mailserver/default.nix | 87 +++----- .../nixos/infrastructure/mailserver/dkim.nix | 140 +++++-------- .../nixos/infrastructure/mailserver/ldap.nix | 70 ++++--- .../mailserver/openid-connect.nix | 68 +++--- .../mailserver/package/nixos-module.nix | 23 --- .../mailserver/package/package.nix | 194 ------------------ .../mailserver/package/spam-filter.nix | 43 ---- .../mailserver/package/webadmin.nix | 77 ------- .../infrastructure/mailserver/prometheus.nix | 9 +- 11 files changed, 162 insertions(+), 649 deletions(-) delete mode 100644 nix/modules/nixos/infrastructure/mailserver/admin_password.nix delete mode 100644 nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix delete mode 100644 nix/modules/nixos/infrastructure/mailserver/package/package.nix delete mode 100644 nix/modules/nixos/infrastructure/mailserver/package/spam-filter.nix delete mode 100644 nix/modules/nixos/infrastructure/mailserver/package/webadmin.nix diff --git a/nix/modules/nixos/infrastructure/mailserver/acme.nix b/nix/modules/nixos/infrastructure/mailserver/acme.nix index c13d0ca..1321901 100644 --- a/nix/modules/nixos/infrastructure/mailserver/acme.nix +++ b/nix/modules/nixos/infrastructure/mailserver/acme.nix @@ -1,40 +1,9 @@ { lib, config, ... }: let cfg = config.khscodes.infrastructure.mailserver; - fqdn = config.khscodes.networking.fqdn; - acmeDir = config.security.acme.certs.${fqdn}.directory; - # extraDomainNames = lib.lists.filter (d: d != fqdn) (lib.lists.map (d: "mx.${d}") cfg.domains); - extraDomainNames = [ ]; - user = "stalwart-mail"; in { config = lib.mkIf cfg.enable { - khscodes.services.nginx.virtualHosts."${fqdn}" = { - locations."/" = { - proxyPass = "http://127.0.0.1:8080"; - proxyWebsockets = true; - recommendedProxySettings = true; - }; - }; - services.stalwart-mail.settings = { - certificate.default = { - cert = "%{file:${acmeDir}/fullchain.pem}%"; - private-key = "%{file:${config.security.acme.certs.${fqdn}.directory}/key.pem}%"; - }; - }; - security.acme.certs.${fqdn} = { - inherit extraDomainNames; - postRun = '' - systemctl restart stalwart-mail.service - ''; - }; - systemd.services.stalwart-mail = { - after = [ "acme-selfsigned-${fqdn}.service" ]; - wants = [ "acme-finished-${fqdn}.service" ]; - serviceConfig.ReadOnlyPaths = [ acmeDir ]; - }; - users.users.${user}.extraGroups = [ - config.security.acme.certs.${fqdn}.group - ]; + khscodes.services.nginx.virtualHosts."${config.khscodes.networking.fqdn}" = { }; }; } diff --git a/nix/modules/nixos/infrastructure/mailserver/admin_password.nix b/nix/modules/nixos/infrastructure/mailserver/admin_password.nix deleted file mode 100644 index 12a454d..0000000 --- a/nix/modules/nixos/infrastructure/mailserver/admin_password.nix +++ /dev/null @@ -1,67 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.khscodes.infrastructure.mailserver; -in -{ - config = lib.mkIf cfg.enable { - khscodes.infrastructure.vault-server-approle.policy = { - # TODO: Make this configurable - "mx.kaareskovgaard.net/data/logins/admin" = { - capabilities = [ "read" ]; - }; - }; - khscodes.services.vault-agent.templates = [ - { - contents = '' - {{- with secret "mx.kaareskovgaard.net/data/logins/admin" -}} - {{ .Data.data.hashed_password }} - {{- end -}} - ''; - destination = "/run/secret/stalwart/users/admin"; - owner = "stalwart-mail"; - group = "stalwart-mail"; - restartUnits = [ "stalwart-mail.service" ]; - } - ]; - systemd.services.stalwart-mail = { - unitConfig.ConditionPathExists = [ "/run/secret/stalwart/users/admin" ]; - serviceConfig.ReadOnlyPaths = [ "/run/secret/stalwart/users/admin" ]; - }; - services.stalwart-mail = { - settings = { - authentication.fallback-admin = { - user = "admin"; - secret = "%{file:/run/secret/stalwart/users/admin}%"; - }; - }; - }; - khscodes.infrastructure.provisioning.pre.modules = [ - { - terraform.required_providers.random = { - source = "hashicorp/random"; - version = "3.7.2"; - }; - provider.random = { }; - - resource.random_password.stalwart_fallback_admin_password = { - length = 48; - numeric = true; - lower = true; - upper = true; - special = false; - }; - - resource.vault_kv_secret_v2.stalwart_fallback_admin_password = { - mount = "mx.kaareskovgaard.net"; - name = "logins/admin"; - data_json = '' - { - "hashed_password": ''${ jsonencode(resource.random_password.stalwart_fallback_admin_password.bcrypt_hash) }, - "password": ''${ jsonencode(resource.random_password.stalwart_fallback_admin_password.result) } - } - ''; - }; - } - ]; - }; -} diff --git a/nix/modules/nixos/infrastructure/mailserver/default.nix b/nix/modules/nixos/infrastructure/mailserver/default.nix index a4b7289..f59e4e1 100644 --- a/nix/modules/nixos/infrastructure/mailserver/default.nix +++ b/nix/modules/nixos/infrastructure/mailserver/default.nix @@ -1,7 +1,7 @@ { config, lib, - pkgs, + inputs, ... }: let @@ -17,8 +17,7 @@ in }; }; imports = [ - # inputs.simple-nixos-mailserver.nixosModules.mailserver - ./admin_password.nix + inputs.simple-nixos-mailserver.nixosModules.mailserver ./acme.nix ./dmarc.nix ./dane.nix @@ -29,58 +28,8 @@ in ./prometheus.nix ./openid-connect.nix ./ldap.nix - ./package/nixos-module.nix ]; config = lib.mkIf cfg.enable { - services.stalwart-mail = { - enable = true; - package = pkgs.callPackage ./package/package.nix { }; - settings = { - http = { - url = "https://${fqdn}"; - use-x-forwarded = true; - }; - server = { - hostname = fqdn; - tls = { - enable = true; - certificate = "default"; - implicit = true; - ignore-client-order = true; - }; - listener = { - smtp = { - protocol = "smtp"; - bind = "[::]:25"; - }; - submissions = { - bind = "[::]:465"; - protocol = "smtp"; - tls.implicit = true; - }; - imaps = { - bind = "[::]:993"; - protocol = "imap"; - tls.implicit = true; - }; - jmap = { - bind = "[::]:8080"; - url = "https://${fqdn}"; - protocol = "jmap"; - }; - management = { - bind = "[::]:8080"; - protocol = "http"; - }; - }; - }; - lookup.default = { - hostname = fqdn; - domain = "kaareskovgaard.net"; - }; - spam-filter.resource = "${config.services.stalwart-mail.package.spam-filter}/spam-filter.toml"; - }; - }; # TODO: Include a similiar rule for openstack khscodes.infrastructure.hetzner-instance.extraFirewallRules = [ { @@ -129,6 +78,38 @@ in } ) ]; + mailserver = { + enable = true; + enableImap = false; + enableImapSsl = true; + enableSubmission = false; + enableSubmissionSsl = true; + fqdn = config.khscodes.networking.fqdn; + useUTF8FolderNames = true; + domains = cfg.domains; + certificateScheme = "acme"; + }; + services.fail2ban.jails = { + postfix = { + settings = { + enabled = true; + mode = "aggressive"; + findtime = 600; + bantime = "1d"; + maxretry = 3; + }; + }; + dovecot = { + settings = { + enabled = true; + mode = "aggressive"; + findtime = 600; + bantime = "1d"; + maxretry = 3; + }; + }; + }; + networking.firewall.allowedTCPPorts = [ 25 465 diff --git a/nix/modules/nixos/infrastructure/mailserver/dkim.nix b/nix/modules/nixos/infrastructure/mailserver/dkim.nix index 894c6e5..2bef981 100644 --- a/nix/modules/nixos/infrastructure/mailserver/dkim.nix +++ b/nix/modules/nixos/infrastructure/mailserver/dkim.nix @@ -9,82 +9,28 @@ let publicKeyEnd = ''"-----END PUBLIC KEY-----\n"''; rsaKeyPath = domain: "/run/secret/dkim/${domain}.snm_rsa.key"; ed25519KeyPath = domain: "/run/secret/dkim/${domain}.snm_ed25519.key"; - keyFiles = lib.lists.flatten ( + domainKeyPaths = lib.lists.flatten ( lib.lists.map (domain: [ (rsaKeyPath domain) (ed25519KeyPath domain) ]) cfg.domains ); - ifthen = condition: expr: { - "if" = condition; - "then" = expr; - }; - otherwise = expr: { "else" = expr; }; - authDkimForDomain = domain: [ - (ifthen "sender_domain = '${domain}'" "['${domain}_rsa', '${domain}_ed25519']") - ]; - authDkim = lib.lists.flatten (lib.lists.map authDkimForDomain cfg.domains); - signatureForDomain = domain: [ - { - name = "${domain}_rsa"; - value = { - inherit domain; - private-key = "%{file:${rsaKeyPath domain}}%"; - selector = "snm_rsa"; - headers = [ - "From" - "To" - "Cc" - "Date" - "Subject" - "Message-ID" - "Organization" - "MIME-Version" - "Content-Type" - "In-Reply-To" - "References" - "List-Id" - "User-Agent" - "Thread-Topic" - "Thread-Index" - ]; - algorithm = "rsa-sha256"; - canonicalization = "relaxed/relaxed"; - report = true; - }; + # Currently (2025-07-25) I canot get rspamd to sign with ed25519 key, + # it appears it attempts to parse it as an RSA key + # { + # path: "${ed25519KeyPath domain}"; + # selector: "snm_ed25519"; + # } + dkimSigningForDomain = domain: '' + ${domain} { + selectors [ + { + path: "${rsaKeyPath domain}"; + selector: "snm_rsa"; + } + ] } - { - name = "${domain}_ed25519"; - value = { - inherit domain; - private-key = "%{file:${ed25519KeyPath domain}}%"; - selector = "snm_ed25519"; - headers = [ - "From" - "To" - "Cc" - "Date" - "Subject" - "Message-ID" - "Organization" - "MIME-Version" - "Content-Type" - "In-Reply-To" - "References" - "List-Id" - "User-Agent" - "Thread-Topic" - "Thread-Index" - ]; - algorithm = "ed25519-sha256"; - canonicalization = "relaxed/relaxed"; - report = true; - }; - } - ]; - dkimSignatures = { - signature = lib.listToAttrs (lib.lists.flatten (lib.lists.map signatureForDomain cfg.domains)); - }; + ''; dkimPublicKey = tls_key: ''''${ replace(trimprefix(trimsuffix(${tls_key}.public_key_pem, ${publicKeyEnd}), ${publicKeyBegin}), "\n", "") }''; @@ -190,10 +136,10 @@ in ''; destination = rsaKeyPath domain; perms = "0600"; - owner = "stalwart-mail"; - group = "stalwart-mail"; + owner = "rspamd"; + group = "rspamd"; restartUnits = [ - "stalwart-mail.service" + "rspamd.service" ]; } { @@ -204,25 +150,47 @@ in ''; destination = ed25519KeyPath domain; perms = "0600"; - owner = "stalwart-mail"; - group = "stalwart-mail"; + owner = "rspamd"; + group = "rspamd"; restartUnits = [ - "stalwart-mail.service" + "rspamd.service" ]; } ]) cfg.domains ); - services.stalwart-mail.settings = { - auth.dkim = { - sign = authDkim ++ [ - (otherwise false) - ]; + mailserver = { + dkimSigning = false; + }; + services.rspamd.locals."dkim_signing.conf" = lib.mkForce { + text = '' + enabled = true; + allow_username_mismatch = true; + domain { + ${lib.strings.concatStringsSep "\n " (lib.lists.map dkimSigningForDomain cfg.domains)} + } + ''; + }; + services.rspamd.locals."arc.conf" = lib.mkForce { + text = '' + enabled = true; + allow_username_mismatch = true; + domain { + ${lib.strings.concatStringsSep "\n " (lib.lists.map dkimSigningForDomain cfg.domains)} + } + ''; + }; + services.postfix.config = { + # Need to include this as I disabled the in built support for dkim signing + # without this postfix won't forward the mails to rspamd to be signed. + non_smtpd_milters = [ "unix:/run/rspamd/rspamd-milter.sock" ]; + }; + systemd.services.rspamd = { + unitConfig = { + ConditionPathExists = domainKeyPaths; + }; + serviceConfig = { + ReadOnlyPaths = domainKeyPaths; }; - } - // dkimSignatures; - systemd.services.stalwart-mail = { - unitConfig.ConditionPathExists = keyFiles; - serviceConfig.ReadOnlyPaths = keyFiles; }; }; } diff --git a/nix/modules/nixos/infrastructure/mailserver/ldap.nix b/nix/modules/nixos/infrastructure/mailserver/ldap.nix index c009b5a..8699fbc 100644 --- a/nix/modules/nixos/infrastructure/mailserver/ldap.nix +++ b/nix/modules/nixos/infrastructure/mailserver/ldap.nix @@ -16,43 +16,44 @@ in }; config = lib.mkIf cfg.enable { - services.stalwart-mail.settings = { - storage = { - directory = "ldap"; + mailserver.ldap = { + enable = true; + uris = [ "ldaps://login.kaareskovgaard.net" ]; + searchBase = "dc=login,dc=kaareskovgaard,dc=net"; + searchScope = "sub"; + bind = { + dn = "dn=token"; + passwordFile = secretFile; }; - directory.ldap = { - type = "ldap"; - url = "ldaps://login.kaareskovgaard.net"; - base-dn = "dc=login,dc=kaareskovgaard,dc=net"; - bind = { - dn = "dn=token"; - secret = "%{env:STALWART_LDAP_SECRET}%"; - auth = { - method = "lookup"; - }; - }; - filter = { - name = "(&(class=account)(memberOf=mail_user)(uid=?))"; - email = "(&(class=account)(memberOf=mail_user)(mail=?))"; - }; - attributes = { - name = "name"; - class = "class"; - description = "name"; - groups = "memberOf"; - email = "mail;primary"; - email-alias = "mail;alternative"; - quota = "diskQuota"; - }; + dovecot = { + # Map LDAP uid to dovecot user, and ldap userPassword to dovecot password + passAttrs = "uid=user"; + passFilter = "(&(class=account)(memberOf=mail_user)(uid=%u))"; + # This filter is used both when receiving mail (thus needing to lookup by mail address, and when authenticating, requriing the lookup by uid.) + # Note that the pass filter only allows looking up by uid, so should still only be able to authenticate using that. + userFilter = "(&(class=account)(memberOf=mail_user)(|(mail=%u)(uid=%u)))"; + userAttrs = "uid=user"; + }; + postfix = { + filter = "(&(class=account)(memberOf=mail_user)(mail=%s))"; + mailAttribute = "uid"; + uidAttribute = "uid"; }; }; systemd.services = { - stalwart-mail = { + dovecot2 = { unitConfig = { ConditionPathExists = [ secretFile ]; }; - serviceConfig = { - EnvironmentFile = secretFile; + }; + postfix = { + unitConfig = { + ConditionPathExists = [ secretFile ]; + }; + }; + postfix-setup = { + unitConfig = { + ConditionPathExists = [ secretFile ]; }; }; }; @@ -61,14 +62,15 @@ in { contents = '' {{- with secret "${cfg.ldap.mount}/data/${cfg.ldap.path}" -}} - STALWART_LDAP_SECRET={{ .Data.data.apiToken }} + {{ .Data.data.apiToken }} {{- end -}} ''; destination = secretFile; - owner = "stalwart-mail"; - group = "stalwart-mail"; + owner = "dovecot"; + group = "dovecot"; restartUnits = [ - "stalwart-mail.service" + "dovecot2.service" + "postfix.service" ]; } ]; diff --git a/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix b/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix index 43c383f..120886d 100644 --- a/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix +++ b/nix/modules/nixos/infrastructure/mailserver/openid-connect.nix @@ -5,41 +5,41 @@ let in { config = lib.mkIf cfg.enable { - # khscodes.services.vault-agent.templates = [ - # { - # contents = '' - # {{- with secret "kanidm/data/apps/dovecot" -}} - # scope = email openid profile - # username_attribute = username - # debug = yes - # introspection_url = https://dovecot:{{ .Data.data.basic_secret }}@login.kaareskovgaard.net/oauth2/token/introspect - # introspection_mode = post - # {{- end -}} - # ''; - # destination = oauthConfigFile; - # perms = "0600"; - # owner = "root"; - # group = "root"; - # restartUnits = [ "dovecot2.service" ]; - # } - # ]; - # services.dovecot2.extraConfig = '' - # auth_mechanisms = $auth_mechanisms oauthbearer xoauth2 + khscodes.services.vault-agent.templates = [ + { + contents = '' + {{- with secret "kanidm/data/apps/dovecot" -}} + scope = email openid profile + username_attribute = username + debug = yes + introspection_url = https://dovecot:{{ .Data.data.basic_secret }}@login.kaareskovgaard.net/oauth2/token/introspect + introspection_mode = post + {{- end -}} + ''; + destination = oauthConfigFile; + perms = "0600"; + owner = "root"; + group = "root"; + restartUnits = [ "dovecot2.service" ]; + } + ]; + services.dovecot2.extraConfig = '' + auth_mechanisms = $auth_mechanisms oauthbearer xoauth2 - # passdb { - # driver = oauth2 - # mechanisms = xoauth2 oauthbearer - # args = ${oauthConfigFile} - # } - # ''; - # systemd.services.dovecot2 = { - # serviceConfig.ReadOnlyPaths = [ - # oauthConfigFile - # ]; - # unitConfig.ConditionPathExists = [ - # oauthConfigFile - # ]; - # }; + passdb { + driver = oauth2 + mechanisms = xoauth2 oauthbearer + args = ${oauthConfigFile} + } + ''; + systemd.services.dovecot2 = { + serviceConfig.ReadOnlyPaths = [ + oauthConfigFile + ]; + unitConfig.ConditionPathExists = [ + oauthConfigFile + ]; + }; }; } diff --git a/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix b/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix deleted file mode 100644 index 5d4160c..0000000 --- a/nix/modules/nixos/infrastructure/mailserver/package/nixos-module.nix +++ /dev/null @@ -1,23 +0,0 @@ -# This file contains patches for Nixos 25.05 to be compatible with new stalwart mail -{ - lib, - config, - pkgs, - ... -}: -let - configFormat = pkgs.formats.toml { }; - configFile = configFormat.generate "stalwart-mail.toml" config.services.stalwart-mail.settings; -in -{ - systemd.services.stalwart-mail = lib.mkIf config.services.stalwart-mail.enable { - serviceConfig = { - User = "stalwart-mail"; - Group = "stalwart-mail"; - ExecStart = lib.mkForce [ - "" - "${lib.getExe config.services.stalwart-mail.package} --config=${configFile}" - ]; - }; - }; -} diff --git a/nix/modules/nixos/infrastructure/mailserver/package/package.nix b/nix/modules/nixos/infrastructure/mailserver/package/package.nix deleted file mode 100644 index b1c1256..0000000 --- a/nix/modules/nixos/infrastructure/mailserver/package/package.nix +++ /dev/null @@ -1,194 +0,0 @@ -{ - lib, - rustPlatform, - fetchFromGitHub, - pkg-config, - protobuf, - bzip2, - openssl, - sqlite, - foundationdb, - zstd, - stdenv, - nix-update-script, - nixosTests, - rocksdb, - callPackage, - withFoundationdb ? false, - stalwartEnterprise ? false, -}: - -rustPlatform.buildRustPackage (finalAttrs: { - pname = "stalwart-mail" + (lib.optionalString stalwartEnterprise "-enterprise"); - version = "0.13.2"; - - src = fetchFromGitHub { - owner = "stalwartlabs"; - repo = "stalwart"; - rev = "51a0a1445d74a8cfb880e9d88f5be390fa0e9365"; - hash = "sha256-VdeHb1HVGXA5RPenhhK4r/kkQiLG8/4qhdxoJ3xIqR4="; - }; - - cargoHash = "sha256-Wu6skjs3Stux5nCX++yoQPeA33Qln67GoKcob++Ldng="; - - nativeBuildInputs = [ - pkg-config - protobuf - rustPlatform.bindgenHook - ]; - - buildInputs = [ - bzip2 - openssl - sqlite - zstd - ] - ++ lib.optionals (stdenv.hostPlatform.isLinux && withFoundationdb) [ foundationdb ]; - - # Issue: https://github.com/stalwartlabs/stalwart/issues/1104 - buildNoDefaultFeatures = true; - buildFeatures = [ - "postgres" - "rocks" - "elastic" - "redis" - ] - ++ lib.optionals withFoundationdb [ "foundationdb" ] - ++ lib.optionals stalwartEnterprise [ "enterprise" ]; - - env = { - OPENSSL_NO_VENDOR = true; - ZSTD_SYS_USE_PKG_CONFIG = true; - ROCKSDB_INCLUDE_DIR = "${rocksdb}/include"; - ROCKSDB_LIB_DIR = "${rocksdb}/lib"; - }; - - postInstall = '' - mkdir -p $out/etc/stalwart - - mkdir -p $out/lib/systemd/system - - substitute resources/systemd/stalwart-mail.service $out/lib/systemd/system/stalwart-mail.service \ - --replace "__PATH__" "$out" - ''; - - checkFlags = lib.forEach [ - # Require running mysql, postgresql daemon - "directory::imap::imap_directory" - "directory::internal::internal_directory" - "directory::ldap::ldap_directory" - "directory::sql::sql_directory" - "directory::oidc::oidc_directory" - "store::blob::blob_tests" - "store::lookup::lookup_tests" - "smtp::lookup::sql::lookup_sql" - # thread 'directory::smtp::lmtp_directory' panicked at tests/src/store/mod.rs:122:44: - # called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" } - "directory::smtp::lmtp_directory" - # thread 'imap::imap_tests' panicked at tests/src/imap/mod.rs:436:14: - # Missing store type. Try running `STORE= cargo test`: NotPresent - "imap::imap_tests" - # thread 'jmap::jmap_tests' panicked at tests/src/jmap/mod.rs:303:14: - # Missing store type. Try running `STORE= cargo test`: NotPresent - "jmap::jmap_tests" - # Failed to read system DNS config: io error: No such file or directory (os error 2) - "smtp::inbound::data::data" - # Expected "X-My-Header: true" but got Received: from foobar.net (unknown [10.0.0.123]) - "smtp::inbound::scripts::sieve_scripts" - # thread 'smtp::outbound::lmtp::lmtp_delivery' panicked at tests/src/smtp/session.rs:313:13: - # Expected " (failed to lookup" but got From: "Mail Delivery Subsystem" - "smtp::outbound::lmtp::lmtp_delivery" - # thread 'smtp::outbound::extensions::extensions' panicked at tests/src/smtp/inbound/mod.rs:45:23: - # No queue event received. - "smtp::outbound::extensions::extensions" - # panicked at tests/src/smtp/outbound/smtp.rs:173:5: - "smtp::outbound::smtp::smtp_delivery" - # panicked at tests/src/smtp/outbound/lmtp.rs - "smtp::outbound::lmtp::lmtp_delivery" - # thread 'smtp::queue::retry::queue_retry' panicked at tests/src/smtp/queue/retry.rs:119:5: - # assertion `left == right` failed - # left: [1, 2, 2] - # right: [1, 2, 3] - "smtp::queue::retry::queue_retry" - # thread 'smtp::queue::virtualq::virtual_queue' panicked at /build/source/crates/store/src/dispatch/store.rs:548:14: - # called `Result::unwrap()` on an `Err` value: Error(Event { inner: Store(MysqlError), keys: [(Reason, String("Input/output error: Input/output error: Connection refused (os error 111)")), (CausedBy, String("crates/store/src/dispatch/store.rs:301"))] }) - "smtp::queue::virtualq::virtual_queue" - # Missing store type. Try running `STORE= cargo test`: NotPresent - "store::store_tests" - # Missing store type. Try running `STORE= cargo test`: NotPresent - "cluster::cluster_tests" - # Missing store type. Try running `STORE= cargo test`: NotPresent - "webdav::webdav_tests" - # thread 'config::parser::tests::toml_parse' panicked at crates/utils/src/config/parser.rs:463:58: - # called `Result::unwrap()` on an `Err` value: "Expected ['\\n'] but found '!' in value at line 70." - "config::parser::tests::toml_parse" - # error[E0432]: unresolved import `r2d2_sqlite` - # use of undeclared crate or module `r2d2_sqlite` - "backend::sqlite::pool::SqliteConnectionManager::with_init" - # thread 'smtp::reporting::analyze::report_analyze' panicked at tests/src/smtp/reporting/analyze.rs:88:5: - # assertion `left == right` failed - # left: 0 - # right: 12 - "smtp::reporting::analyze::report_analyze" - # thread 'smtp::inbound::dmarc::dmarc' panicked at tests/src/smtp/inbound/mod.rs:59:26: - # Expected empty queue but got Reload - "smtp::inbound::dmarc::dmarc" - # thread 'smtp::queue::concurrent::concurrent_queue' panicked at tests/src/smtp/inbound/mod.rs:65:9: - # assertion `left == right` failed - "smtp::queue::concurrent::concurrent_queue" - # Failed to read system DNS config: io error: No such file or directory (os error 2) - "smtp::inbound::auth::auth" - # Failed to read system DNS config: io error: No such file or directory (os error 2) - "smtp::inbound::antispam::antispam" - # Failed to read system DNS config: io error: No such file or directory (os error 2) - "smtp::inbound::vrfy::vrfy_expn" - # thread 'smtp::management::queue::manage_queue' panicked at tests/src/smtp/inbound/mod.rs:45:23: - # No queue event received. - # NOTE: Test unreliable on high load systems - "smtp::management::queue::manage_queue" - # thread 'responses::tests::parse_responses' panicked at crates/dav-proto/src/responses/mod.rs:671:17: - # assertion `left == right` failed: failed for 008.xml - # left: ElementEnd - # right: Bytes([...]) - "responses::tests::parse_responses" - ] (test: "--skip=${test}"); - - doCheck = !(stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch64); - - # Allow network access during tests on Darwin/macOS - __darwinAllowLocalNetworking = true; - - passthru = { - inherit rocksdb; # make used rocksdb version available (e.g., for backup scripts) - webadmin = callPackage ./webadmin.nix { }; - spam-filter = callPackage ./spam-filter.nix { }; - updateScript = nix-update-script { }; - tests.stalwart-mail = nixosTests.stalwart-mail; - }; - - meta = { - description = "Secure & Modern All-in-One Mail Server (IMAP, JMAP, SMTP)"; - homepage = "https://github.com/stalwartlabs/mail-server"; - changelog = "https://github.com/stalwartlabs/mail-server/blob/main/CHANGELOG.md"; - license = [ - lib.licenses.agpl3Only - ] - ++ lib.optionals stalwartEnterprise [ - { - fullName = "Stalwart Enterprise License 1.0 (SELv1) Agreement"; - url = "https://github.com/stalwartlabs/mail-server/blob/main/LICENSES/LicenseRef-SEL.txt"; - free = false; - redistributable = false; - } - ]; - - mainProgram = "stalwart"; - maintainers = with lib.maintainers; [ - happysalada - onny - oddlama - pandapip1 - norpol - ]; - }; -}) diff --git a/nix/modules/nixos/infrastructure/mailserver/package/spam-filter.nix b/nix/modules/nixos/infrastructure/mailserver/package/spam-filter.nix deleted file mode 100644 index d0ca6c6..0000000 --- a/nix/modules/nixos/infrastructure/mailserver/package/spam-filter.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ - lib, - fetchFromGitHub, - stdenv, - stalwart-mail, - nix-update-script, -}: - -stdenv.mkDerivation (finalAttrs: { - pname = "spam-filter"; - version = "2.0.3"; - - src = fetchFromGitHub { - owner = "stalwartlabs"; - repo = "spam-filter"; - tag = "v${finalAttrs.version}"; - hash = "sha256-NhD/qUiGhgESwR2IOzAHfDATRlgWMcCktlktvVfDONk="; - }; - - buildPhase = '' - bash ./build.sh - ''; - - installPhase = '' - mkdir -p $out - cp spam-filter.toml $out/ - ''; - - passthru = { - updateScript = nix-update-script { }; - }; - - meta = { - description = "Secure & modern all-in-one mail server Stalwart (spam-filter module)"; - homepage = "https://github.com/stalwartlabs/spam-filter"; - changelog = "https://github.com/stalwartlabs/spam-filter/blob/${finalAttrs.src.tag}/CHANGELOG.md"; - license = with lib.licenses; [ - mit - asl20 - ]; - inherit (stalwart-mail.meta) maintainers; - }; -}) diff --git a/nix/modules/nixos/infrastructure/mailserver/package/webadmin.nix b/nix/modules/nixos/infrastructure/mailserver/package/webadmin.nix deleted file mode 100644 index 18785be..0000000 --- a/nix/modules/nixos/infrastructure/mailserver/package/webadmin.nix +++ /dev/null @@ -1,77 +0,0 @@ -{ - lib, - rustPlatform, - stalwart-mail, - fetchFromGitHub, - trunk, - tailwindcss_3, - fetchNpmDeps, - nix-update-script, - nodejs, - npmHooks, - llvmPackages, - wasm-bindgen-cli_0_2_93, - binaryen, - zip, -}: - -rustPlatform.buildRustPackage (finalAttrs: { - pname = "webadmin"; - version = "0.1.31"; - - src = fetchFromGitHub { - owner = "stalwartlabs"; - repo = "webadmin"; - rev = "6f1368b8a1160341b385980accea489ee0e45440"; - hash = "sha256-/EWn/wiY6zFNhObfo11OkoGufcUODMYs18P3vTBbB8s="; - }; - - npmDeps = fetchNpmDeps { - name = "${finalAttrs.pname}-npm-deps"; - hash = "sha256-na1HEueX8w7kuDp8LEtJ0nD1Yv39cyk6sEMpS1zix2s="; - }; - - cargoHash = "sha256-Q05+wH9+NfkfmEDJFLuWVQ7wuDeEu9h1XmOMN6SYdyU="; - - postPatch = '' - # Using local tailwindcss for compilation - substituteInPlace Trunk.toml --replace-fail "npx tailwindcss" "tailwindcss" - ''; - - nativeBuildInputs = [ - binaryen - llvmPackages.bintools-unwrapped - nodejs - npmHooks.npmConfigHook - tailwindcss_3 - trunk - # needs to match with wasm-bindgen version in upstreams Cargo.lock - wasm-bindgen-cli_0_2_93 - - zip - ]; - - NODE_PATH = "$npmDeps"; - - buildPhase = '' - trunk build --offline --frozen --release - ''; - - installPhase = '' - cd dist - mkdir -p $out - zip -r $out/webadmin.zip * - ''; - - passthru = { - updateScript = nix-update-script { }; - }; - - meta = { - description = "Secure & modern all-in-one mail server Stalwart (webadmin module)"; - homepage = "https://github.com/stalwartlabs/webadmin"; - changelog = "https://github.com/stalwartlabs/webadmin/blob/${finalAttrs.src.tag}/CHANGELOG.md"; - license = lib.licenses.agpl3Only; - inherit (stalwart-mail.meta) maintainers; - }; -}) diff --git a/nix/modules/nixos/infrastructure/mailserver/prometheus.nix b/nix/modules/nixos/infrastructure/mailserver/prometheus.nix index 9c1e7f5..3318a54 100644 --- a/nix/modules/nixos/infrastructure/mailserver/prometheus.nix +++ b/nix/modules/nixos/infrastructure/mailserver/prometheus.nix @@ -1,16 +1,13 @@ { config, lib, ... }: let - fqdn = config.khscodes.networking.fqdn; cfg = config.khscodes.infrastructure.mailserver; in { config = lib.mkIf cfg.enable { - services.stalwart-mail.settings.metrics.prometheus = { + + services.prometheus.exporters.postfix = { enable = true; }; - # Don't expose the endpoint - khscodes.services.nginx.virtualHosts."${fqdn}".locations."=/metrics/prometheus" = { - return = 404; - }; + khscodes.infrastructure.vault-prometheus-sender.exporters.enabled = [ "postfix" ]; }; }