From c2078d3e8be3bec0248c3f272ec6bebf46093196 Mon Sep 17 00:00:00 2001 From: sinanmohd Date: Sun, 18 Feb 2024 10:58:23 +0530 Subject: kay/mail: init --- common.nix | 2 + hosts/kay/configuration.nix | 1 + .../dns/5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.zone | 1 + hosts/kay/modules/dns/ddns.nix | 7 +- hosts/kay/modules/dns/sinanmohd.com.zone | 21 ++- hosts/kay/modules/hurricane.nix | 1 + hosts/kay/modules/mail.nix | 103 +++++++++++++ hosts/kay/modules/www.nix | 13 +- hosts/kay/secrets.yaml | 8 +- modules/stalwart-mail.nix | 167 +++++++++++++++++++++ modules/userdata.nix | 2 +- pkgs/stalwart-mail-config.nix | 43 ++++++ 12 files changed, 361 insertions(+), 8 deletions(-) create mode 100644 hosts/kay/modules/mail.nix create mode 100644 modules/stalwart-mail.nix create mode 100644 pkgs/stalwart-mail-config.nix diff --git a/common.nix b/common.nix index c2695ab..b9d2dab 100644 --- a/common.nix +++ b/common.nix @@ -7,6 +7,7 @@ in { disabledModules = [ "services/networking/pppd.nix" + "services/mail/stalwart-mail.nix" ]; imports = [ ./modules/userdata.nix @@ -15,6 +16,7 @@ in ./modules/dev.nix ./modules/pppd.nix + ./modules/stalwart-mail.nix ]; sops = { diff --git a/hosts/kay/configuration.nix b/hosts/kay/configuration.nix index 78385d1..1e264e2 100644 --- a/hosts/kay/configuration.nix +++ b/hosts/kay/configuration.nix @@ -7,6 +7,7 @@ ./modules/www.nix ./modules/sftp.nix ./modules/acme.nix + ./modules/mail.nix ./modules/dns ./modules/sshfwd.nix ../../common.nix diff --git a/hosts/kay/modules/dns/5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.zone b/hosts/kay/modules/dns/5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.zone index 3991e1f..69b3524 100644 --- a/hosts/kay/modules/dns/5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.zone +++ b/hosts/kay/modules/dns/5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.zone @@ -11,3 +11,4 @@ $TTL 2d IN NS ns1.sinanmohd.com. 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR ns1.sinanmohd.com. +7.3.3.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR mail.sinanmohd.com. diff --git a/hosts/kay/modules/dns/ddns.nix b/hosts/kay/modules/dns/ddns.nix index 6d0a944..e6e417a 100644 --- a/hosts/kay/modules/dns/ddns.nix +++ b/hosts/kay/modules/dns/ddns.nix @@ -9,8 +9,11 @@ server 2001:470:ee65::1 zone sinanmohd.com. - update delete sinanmohd.com. A - update add sinanmohd.com. 180 A $4 + update delete sinanmohd.com. A + update add sinanmohd.com. 180 A $4 + + update delete mail.sinanmohd.com. A + update add mail.sinanmohd.com. 180 A $4 send EOF diff --git a/hosts/kay/modules/dns/sinanmohd.com.zone b/hosts/kay/modules/dns/sinanmohd.com.zone index 5833a2a..5fb9ca5 100644 --- a/hosts/kay/modules/dns/sinanmohd.com.zone +++ b/hosts/kay/modules/dns/sinanmohd.com.zone @@ -1,8 +1,8 @@ $ORIGIN sinanmohd.com. $TTL 2d -@ IN SOA ns1 sinan ( - 2024021100 ; serial +@ IN SOA ns1 hostmaster ( + 2024022500 ; serial 2h ; refresh 5m ; retry 1d ; expire @@ -17,8 +17,25 @@ $TTL 2d 30 IN A 127.0.0.1 30 IN AAAA ::1 + IN MX 10 mail + + IN TXT "v=spf1 mx -all" +_dmarc IN TXT "v=DMARC1; p=reject; rua=mailto:postmaster@sinanmohd.com; ruf=mailto:postmaster@sinanmohd.com; adkim=s; aspf=s" + +ed25519._domainkey IN TXT "v=DKIM1; k=ed25519; p=EHk924AruF9Y0Xaf009rpRl+yGusjmjT1Zeho67BnDU=" +rsa._domainkey IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4HEqO63fSC0cUnJt9vAQBssTkPfT4QefmAK/1BtAIRIOdGakf7PI7p3A1ETgwfYxuHj7BUSzUtESsHMThbhB1Wko79+AR+5ZBDBmD8CE0dOnZfzeG8xIaGfYkaL4gana6YZWiBT2oi/CimJfc22wacF01SufOs4R8cDpy4BZIgDD/zfF4bFTORQ0vMSJQJkp1zdQelERDU5CEezgxgVYgoSmdEpgkhc23PJSyj4Z7hA69N0amsb3cVVrfVXcYvSqTK3S2vLLA89ws4CUjCCpUW40gVIP8QP6CqTL76936Oo7OVWgmV3Sn3wa8FMN6IATY+fbMlrdOMsPY5PauJyEoQIDAQAB" + ns1 IN AAAA 2001:470:ee65::1 +mail 30 IN A 127.0.0.1 +mail IN AAAA 2001:470:ee65::1337 +smtp IN CNAME @ +imap IN CNAME @ +mta-sts IN CNAME @ + +_mta-sts IN TXT "v=STSv1; id=2024022500" +_smtp._tls IN TXT "v=TLSRPTv1; rua=mailto:postmaster@sinanmohd.com" + www IN CNAME @ git IN CNAME @ bin IN CNAME @ diff --git a/hosts/kay/modules/hurricane.nix b/hosts/kay/modules/hurricane.nix index ede8e8f..9e22bf5 100644 --- a/hosts/kay/modules/hurricane.nix +++ b/hosts/kay/modules/hurricane.nix @@ -33,6 +33,7 @@ in (makeAddr prefix64 "1") (makeAddr prefix48 "1") + (makeAddr prefix48 "1337") ]; }; diff --git a/hosts/kay/modules/mail.nix b/hosts/kay/modules/mail.nix new file mode 100644 index 0000000..b255650 --- /dev/null +++ b/hosts/kay/modules/mail.nix @@ -0,0 +1,103 @@ +{ config, ... }: let + ipv6 = "2001:470:ee65::1337"; + domain = config.userdata.domain; + + username = config.userdata.user; + secret = "$argon2i$v=19$m=4096,t=3,p=1$SWV5aWU3YWUgZWFTNm9oc28gTGFvdDdlRG8ga2FTaWVjaDYgYWV0aDFHb28$O/sDv7oy9wUxFjvKoxB5o8ZnPvjYJo9DjX0C/AZQFF0"; + email = [ + "${username}@${domain}" + "sinanmohd@${domain}" + "me@${domain}" + + "postmaster@${domain}" + "hostmaster@${domain}" + "admin@${domain}" + ]; + + credentials_directory = "/run/credentials/stalwart-mail.service"; +in { + networking.firewall.allowedTCPPorts = [ + 25 # smto + 465 # submission + 587 # submissions + 993 # imap ssl + 4190 # managesieve + ]; + + sops.secrets = { + "mail.${domain}/dkim_rsa" = {}; + "mail.${domain}/dkim_ed25519" = {}; + }; + + 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}" + + "cert:${config.security.acme.certs.${domain}.directory}/fullchain.pem" + "key:${config.security.acme.certs.${domain}.directory}/key.pem" + ]; + + settings = { + macros = { + host = "mail.${domain}"; + default_domain = domain; + default_directory = "in-memory"; + default_store = "sqlite"; + }; + + 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" ]; + }; + + signature = { + rsa = { + private-key = "file://${credentials_directory}/dkim_rsa"; + selector = "rsa"; + set-body-length = true; + }; + ed25519 = { + public-key = "EHk924AruF9Y0Xaf009rpRl+yGusjmjT1Zeho67BnDU="; + private-key = "file://${credentials_directory}/dkim_ed25519"; + domain = "%{DEFAULT_DOMAIN}%"; + selector = "ed25519"; + headers = [ "From" "To" "Date" "Subject" "Message-ID" ]; + algorithm = "ed25519-sha256"; + canonicalization = "relaxed/relaxed"; + set-body-length = true; + report = true; + }; + }; + + certificate."default" = { + cert = "file://${credentials_directory}/cert"; + private-key = "file://${credentials_directory}/key"; + }; + + storage.blob = "fs"; + store = { + fs.disable = false; + sqlite.disable = false; + }; + + directory."in-memory" = { + type = "memory"; + options.subaddressing = true; + + principals = [{ + inherit email; + inherit secret; + name = username; + type = "admin"; + }]; + }; + }; + }; +} diff --git a/hosts/kay/modules/www.nix b/hosts/kay/modules/www.nix index a0b9c20..1447b1e 100644 --- a/hosts/kay/modules/www.nix +++ b/hosts/kay/modules/www.nix @@ -1,4 +1,4 @@ -{ config, pkgs, ... }: +{ config, pkgs, lib, ... }: let domain = config.userdata.domain; @@ -117,6 +117,17 @@ in extraConfig = "add_header Content-Type text/html;"; }; }; + + "mta-sts.${domain}" = defaultOpts // { + locations."= /.well-known/mta-sts.txt".return = ''200 "${ + lib.strings.concatStringsSep "\\n" [ + "version: STSv1" + "mode: enforce" + "mx: mail.${domain}" + "max_age: 86400" + ] + }"''; + }; }; }; } diff --git a/hosts/kay/secrets.yaml b/hosts/kay/secrets.yaml index 11bebda..47be11b 100644 --- a/hosts/kay/secrets.yaml +++ b/hosts/kay/secrets.yaml @@ -10,6 +10,10 @@ dns: ENC[AES256_GCM,data:Pa6Oo7UFDqo5ZN+eyz9MKy0p4KU1ePTpWQ+R8PuSFO9JjFt/I86ru/q matrix-sinanmohd.com: key: ENC[AES256_GCM,data:xsSYua3g+ySUVBtfVZ2uZR4761MC5LeJGxmcgf+dWb5+tBSmgzAQL9FFcl7GLzhTmvlq13lARUr599wShS/C9IyMVGOOT9A8hxLFF9Kak64hmM7ERGrwbmzBY1mdTtvibJqzHaeybUVIMbDagczF54zpjDGLmdC5V84wduPFCndSA5FW+4Hhqw==,iv:KJtqrGNPgMDR6Sg/fOUzVAiwnPZwve9wpVfDQPc4g/c=,tag:E2jlbt5WbRA9wu16Lr69Bg==,type:str] sliding_sync: ENC[AES256_GCM,data:ubFeb/OgYYHaIHVky6KS3icORbpqf7PO3p8bONA8mwG8vU1LB0TDqVm6vQTa8G9pe96JzJ8+IAgSZafG9PaEJc/Bpj53aWRFO3HEV0Pj,iv:P8VD8utVEwNoeQEZUdS2R9GuDe20nKiXYCfKJl0Id3E=,tag:VksV/4IaKN0C2g/alw6r4Q==,type:str] +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] misc: wireguard: ENC[AES256_GCM,data:kbUtxJv3xSmikJWgtu87TSo5N8tUb2BiH3dH3oOV36waYyXI3bp2aBeAl1k=,iv:yB4UIyMDNRS+JmSnt9XuBhNRTLz+k0FqkK4ofjosRto=,tag:BDSD9SfQuQppKT4+6Cu65w==,type:str] sops: @@ -36,8 +40,8 @@ sops: OXgwSml4bkc1dnloNUFsRGFFcXFHc2cK26l2eiKbZUkogmAXoha6HTUs3YFKixYz bTkpKKyOAIIin3YM975wwvkCuWNG4tbnHBHQFh5JGK2OEyLDXuV7Pg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-02-01T06:10:26Z" - mac: ENC[AES256_GCM,data:6Gow3dOvqseuuNbpztmm3yNU+6DKo+2LPqigO1cDhmKB509RN/T9GqDQEk/uC/aOyYeYSWrQY3EzZYOXiXgyiH2hurYV8WXGAAjssXog9YaVcC+OiXXv2zDRV8o8VKigc0hlrZJuN8FeL0qxrorojBft0QR/6JhGpV+s1jvS/8o=,iv:wV/WKfl2HPFHX3aoIdMpuK5frVs9imeO6LI0igYi2+Q=,tag:IXs92PzvwQM3FGaHW/qU8Q==,type:str] + lastmodified: "2024-02-25T04:23:28Z" + mac: ENC[AES256_GCM,data:SUFBHKTM2tQHX1Xtta3spl/GaaNrIAcNrLFzKzqb2ki3FhXnLLYu0wD+IBxuj1nxICn9TDprHFdcDenfFPV1mYWtmXLmWMeDcIGKXedYex2nakdlIYngGiLkEseuehft46YtoEqLJVksBFoLKmywRi+/ZGux/heSIyD14Toxb3Q=,iv:dqYGObF1SV3VBxSZtrggRdD1ROqvlp7tn8xLdNuDxx4=,tag:N/4L6NgIqYKQ8IbpFGru2g==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.8.1 diff --git a/modules/stalwart-mail.nix b/modules/stalwart-mail.nix new file mode 100644 index 0000000..ebeedd9 --- /dev/null +++ b/modules/stalwart-mail.nix @@ -0,0 +1,167 @@ +{ config, lib, pkgs, ... }: + +with lib; + +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 = mkEnableOption (mdDoc "the Stalwart all-in-one email server"); + package = mkPackageOption pkgs "stalwart-mail" { }; + + loadCredential = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = []; + example = [ "dkim.private:/path/to/stalwart.private" ]; + description = lib.mdDoc '' + 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 = mkOption { + inherit (configFormat) type; + default = { }; + description = mdDoc '' + Configuration options for the Stalwart email server. + See for available options. + + By default, the module is configured to store everything locally. + ''; + }; + }; + + config = 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 ]; + }; + + meta = { + maintainers = with maintainers; [ happysalada pacien ]; + }; +} diff --git a/modules/userdata.nix b/modules/userdata.nix index 46c7377..00f0e13 100644 --- a/modules/userdata.nix +++ b/modules/userdata.nix @@ -18,7 +18,7 @@ in }; email = mkOption { type = types.str; - default = "sinan@firemail.cc"; + default = "sinan@${cfg.domain}"; description = mdDoc "Owner's email"; }; }; diff --git a/pkgs/stalwart-mail-config.nix b/pkgs/stalwart-mail-config.nix new file mode 100644 index 0000000..77fc366 --- /dev/null +++ b/pkgs/stalwart-mail-config.nix @@ -0,0 +1,43 @@ +{ 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 ]; + }; +} -- cgit v1.2.3