From 02abf4ed0131237c25e0a10db50fa4c41a902a50 Mon Sep 17 00:00:00 2001 From: Alejandro Soto Date: Sun, 14 Jul 2024 17:53:13 -0600 Subject: sys: final merge of dmz, hv into sys --- sys/mail/default.nix | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 sys/mail/default.nix (limited to 'sys/mail/default.nix') diff --git a/sys/mail/default.nix b/sys/mail/default.nix new file mode 100644 index 0000000..5b7e4b5 --- /dev/null +++ b/sys/mail/default.nix @@ -0,0 +1,238 @@ +{ config, lib, pkgs, ... }: +with lib; let + cfg = config.local.mailHost; + imapHostname = config.local.domains.imap.main; + + inherit (config.local) users virtual; +in +{ + options.local.mailHost = { + enable = mkEnableOption "mailbox host service"; + + mdaListen = mkOption { + type = types.str; + }; + + saslPort = mkOption { + type = types.port; + }; + + lmtpPort = mkOption { + type = types.port; + }; + }; + + config = mkIf cfg.enable { + services.dovecot2 = + let + cert = config.security.acme.certs.${imapHostname}.directory; + in + { + enable = true; + enablePAM = false; + enableLmtp = true; + + sslServerKey = "${cert}/key.pem"; + sslServerCert = "${cert}/fullchain.pem"; + + modules = [ pkgs.dovecot_pigeonhole ]; + + mailUser = "vmail"; + mailGroup = "vmail"; + mailLocation = "maildir:~/mail"; + mailPlugins.perProtocol.lmtp.enable = [ "sieve" ]; + + extraConfig = + let + inherit (config.networking) domain; + + # https://dovecot.org/list/dovecot/2019-March/115250.html + # Otra solución posible (https://serverfault.com/a/1062274/980378): + # auth_username_format = %{if;%d;eq;${domain};%Ln;%Lu} + localEntry = canonical: username: '' + ${username}:::::::user=${canonical} nopassword userdb_user=${canonical} + ''; + + localMailboxes = + pkgs.writeText "local-mailboxes" + (concatStrings + (flatten (mapAttrsToList + (canonical: user: + map (localEntry canonical) ([ canonical ] ++ user.hardAliases)) + users))); + + localCerts = + flatten (mapAttrsToList + (canonical: user: + let + certNames = { + inherit canonical; + logins = [ canonical ] ++ user.hardAliases; + }; + in + map (flip nameValuePair certNames) user.mail.certs) + users); + + vmailCerts = + flatten (flatten (mapAttrsToList + (domain: virtual: mapAttrsToList + (username: user: + let + address = "${username}@${domain}"; + + certNames = { + canonical = address; + logins = [ address ]; + }; + in + map (flip nameValuePair certNames) user.mail.certs) + virtual.users) + virtual)); + + certLogins = + pkgs.writeText "cert-logins" + (concatStrings (flatten (mapAttrsToList + (uuid: names: map + (addr: '' + ${uuid}.mail-client@nodomain,${addr}:::::::user=${names.canonical} + '') + names.logins) + (listToAttrs (localCerts ++ vmailCerts))))); + + vmailPath = "/var/lib/vmail/%{if;%d;ne;;%Ld;${domain}}"; + in + '' + auth_mechanisms = plain login external + + #TODO: automatizar implantación de archivo de CA + + # Orden de concatenación de mail-fullchain-crl.crt: + # - Issuing CA cert + # - Issuing CA CRL + # - Intermediate CA cert + # - Intermediate CA CRL + # - Root CA cert + # - Root CA CRL + ssl_ca =