From 5b8929435cb955169d7d497fc8d759e50d5f67ff Mon Sep 17 00:00:00 2001 From: Max Audron Date: Fri, 10 Oct 2025 11:58:28 +0200 Subject: setup mailserver --- flake.lock | 6 +- machines/mail/default.nix | 3 + modules/common/default.nix | 5 + modules/mailserver/default.nix | 209 ++++++++++++++++++++++++++++++++++++----- modules/monitoring/scrape.nix | 17 ++++ secrets | 2 +- 6 files changed, 214 insertions(+), 28 deletions(-) diff --git a/flake.lock b/flake.lock index 84cb644..725bf4f 100644 --- a/flake.lock +++ b/flake.lock @@ -573,11 +573,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1753694789, - "narHash": "sha256-cKgvtz6fKuK1Xr5LQW/zOUiAC0oSQoA9nOISB0pJZqM=", + "lastModified": 1758427187, + "narHash": "sha256-pHpxZ/IyCwoTQPtFIAG2QaxuSm8jWzrzBGjwQZIttJc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "dc9637876d0dcc8c9e5e22986b857632effeb727", + "rev": "554be6495561ff07b6c724047bdd7e0716aa7b46", "type": "github" }, "original": { diff --git a/machines/mail/default.nix b/machines/mail/default.nix index eca85a2..36de86e 100644 --- a/machines/mail/default.nix +++ b/machines/mail/default.nix @@ -55,4 +55,7 @@ in substituteOnTarget = true; hermetic = false; }; + + # System state version + system.stateVersion = "25.05"; } diff --git a/modules/common/default.nix b/modules/common/default.nix index ed45914..5a6497a 100644 --- a/modules/common/default.nix +++ b/modules/common/default.nix @@ -17,6 +17,11 @@ # Default Packages Set environment.systemPackages = with pkgs; [ git vim htop wget nftables wireguard-tools tmux fd ripgrep ]; + programs.vim = { + enable = true; + defaultEditor = true; + }; + nixpkgs.config.allowUnfree = true; # Security diff --git a/modules/mailserver/default.nix b/modules/mailserver/default.nix index 9188129..30e4506 100644 --- a/modules/mailserver/default.nix +++ b/modules/mailserver/default.nix @@ -1,44 +1,205 @@ -{ config, lib, pkgs, ...}: +{ + config, + lib, + pkgs, + nixpkgs-unstable, + ... +}: { - mailserver = { + disabledModules = [ "services/mail/stalwart-mail.nix" ]; + imports = [ "${nixpkgs-unstable}/nixos/modules/services/mail/stalwart-mail.nix" ]; + + services.stalwart-mail = { enable = true; + package = pkgs.unstable.stalwart-mail.override { stalwartEnterprise = true; }; + openFirewall = true; - fqdn = "mail.vapor.systems"; - domains = [ "vapor.systems" ]; - - # A list of all login accounts. To create the password hashes, use - # nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt' - loginAccounts = { - # "user1@example.com" = { - # hashedPasswordFile = "/a/file/containing/a/hashed/password"; - # aliases = ["postmaster@example.com"]; - # }; - # "user2@example.com" = { ... }; - }; + settings = { + config = { + local-keys = [ + "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.*" + "webadmin.*" + "metrics.prometheus.*" + "resolver.*" + "http.hsts" + ]; + }; - ldap = { - enable = true; - uris = [ "ldaps://ettves:636" ]; + certificate."mail-vapor-systems" = { + cert = "%{file:/var/lib/acme/mail.vapor.systems/fullchain.pem}%"; + private-key = "%{file:/var/lib/acme/mail.vapor.systems/key.pem}%"; + }; + + spam-filter = lib.mkForce {}; - bind = { - dn = "cn=mail,ou=users,dc=mail,dc=vapor,dc=systems"; - passwordFile = "/etc/secrets/ldap"; + http = { + hsts = true; }; - searchBase = "dc=mail,dc=vapor,dc=systems"; - }; + metrics.prometheus = { + enable = true; + auth = { + username = "prometheus"; + secret = "%{file:/etc/secrets/prometheus}%"; + }; + }; + + server = { + hostname = "mail.vapor.systems"; + + tls = { + enable = true; + implicit = true; + timeout = "1m"; + disable-protocols = [ "TLSv1.2" ]; + disable-ciphers = [ + "TLS13_AES_256_GCM_SHA384" + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" + ]; + ignore-client-order = true; + }; + + listener = { + smtp = { + bind = [ + "0.0.0.0:25" + "[2a01:4f8:1c1c:3ce7::1]:25" + ]; + protocol = "smtp"; + }; + submission = { + bind = [ + "0.0.0.0:587" + "[2a01:4f8:1c1c:3ce7::1]:587" + ]; + protocol = "smtp"; + }; + submissions = { + bind = [ + "0.0.0.0:465" + "[2a01:4f8:1c1c:3ce7::1]:465" + ]; + protocol = "smtp"; + tls = { + enable = true; + implicit = true; + }; + }; + + imap = { + bind = [ + "0.0.0.0:993" + "[2a01:4f8:1c1c:3ce7::1]:993" + ]; + protocol = "imap"; + tls = { + enable = true; + implicit = true; + }; + }; + + management_plain = { + bind = [ + "0.0.0.0:80" + "[2a01:4f8:1c1c:3ce7::1]:80" + ]; + protocol = "http"; + }; + management = { + bind = [ + "0.0.0.0:443" + "[2a01:4f8:1c1c:3ce7::1]:443" + ]; + protocol = "http"; + tls = { + enable = true; + implicit = true; + }; + }; + }; - certificateScheme = "acme"; + }; + + storage.directory = "internal"; + + directory = { + ldap = { + type = "ldap"; + url = "ldap://10.10.0.1:389"; + timeout = "30s"; + tls.enable = false; + + base-dn = "dc=mail,dc=vapor,dc=systems"; + + bind = { + dn = "cn=mail,ou=users,dc=mail,dc=vapor,dc=systems"; + secret = "%{file:/etc/secrets/ldap}%"; + auth = { + method = "template"; + template = "cn={local},ou=users,dc=mail,dc=vapor,dc=systems"; + search = true; + }; + }; + + filter = { + name = "(&(|(objectClass=person)(objectClass=group))(sAMAccountName=?))"; + email = "(&(|(objectClass=person)(objectClass=group))(|(mail=?)(mailAlias=?)))"; + }; + + attributes = { + name = "sAMAccountName"; + class = "objectClass"; + description = [ + "displayName" + ]; + secret = "userPassword"; + groups = [ "memberOf" ]; + email = "mail"; + email-alias = "mailAlias"; + quota = "diskQuota"; + }; + }; + }; + + authentication = { + fallback-admin = { + user = "admin"; + secret = "$6$W2nCPyf1a./fdBxp$yLaBwQDxQqj00UnH9hR3XN8NIXGd.X/ts.dKVKjSWsd8DPJbn/YUnFGUAaoTX5jbeRi76qeFnCVLARdDJKLgA/"; + }; + }; + }; }; secrets = { - minecraft = { + ldap = { source = ../../secrets/authentik/mail; dest = "/etc/secrets/ldap"; + owner = config.users.users.stalwart-mail.name; + }; + prometheus = { + source = ../../secrets/prometheus; + dest = "/etc/secrets/prometheus"; + owner = config.users.users.stalwart-mail.name; }; }; + users.users.stalwart-mail.extraGroups = [ "acme" ]; + security.acme.certs = { "mail.vapor.systems" = { }; }; diff --git a/modules/monitoring/scrape.nix b/modules/monitoring/scrape.nix index 69ea001..928902e 100644 --- a/modules/monitoring/scrape.nix +++ b/modules/monitoring/scrape.nix @@ -24,6 +24,15 @@ in { (mkScrapeConfig "garage" [ "fra01" "nyc01" "sin01" ] 3903) (mkScrapeConfig "pdns" [ "ettves" "fra01" "nyc01" "sin01" ] 8081) + ((mkScrape "mail" [ "mail.vapor.systems:443" ]) // { + metrics_path = "/metrics/prometheus"; + scheme = "https"; + basic_auth = { + username = "prometheus"; + password_file = "/etc/secrets/prometheus"; + }; + }) + ((mkScrape "minecraft" [ "ettves:25585" "ettves:9150" "ettves:9225" ]) // { relabel_configs = [ { @@ -42,4 +51,12 @@ in { }) ]; }; + + secrets = { + prometheus = { + source = ../../secrets/prometheus; + dest = "/etc/secrets/prometheus"; + owner = config.users.users.prometheus.name; + }; + }; } diff --git a/secrets b/secrets index 811147e..6e0d80a 160000 --- a/secrets +++ b/secrets @@ -1 +1 @@ -Subproject commit 811147e78d70054339a6aeb623c30959c096fea2 +Subproject commit 6e0d80a8d98f8c97f8904b4dc0cd8d19dfe3cf84 -- cgit v1.2.3