{ config, lib, pkgs, ... }: with lib; let cfg = config.local; in { options.local.mailHost = with types; { enable = mkEnableOption "mailbox host service"; security.acme.defaults.dnsProvider = "gandiv5"; mdaListen = mkOption { type = str; }; saslPort = mkOption { type = port; }; lmtpPort = mkOption { type = port; }; }; config = let imapHostname = cfg.domains.imap.main; in mkIf cfg.mailHost.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)) cfg.users))); localCerts = flatten (mapAttrsToList (canonical: user: let certNames = { inherit canonical; logins = [ canonical ] ++ user.hardAliases; }; in map (flip nameValuePair certNames) user.mail.certs) cfg.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) cfg.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 =