From 9af8f29b4822572b660747ab66cc681d593af0a3 Mon Sep 17 00:00:00 2001 From: Kaare Hoff Skovgaard Date: Wed, 30 Jul 2025 11:11:17 +0200 Subject: [PATCH] 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" ]; }; }