{ config, lib, pkgs, ... }: with lib; let cfg = config.local.mta; inherit (config.local) domains virtual users; inherit (config.networking) domain; in { options.local.mta = { enable = mkEnableOption "mail transfer agent"; mdaAddr = mkOption { type = types.str; }; saslPort = mkOption { type = types.port; }; lmtpPort = mkOption { type = types.port; }; }; config = mkIf cfg.enable { services.postfix = let cert = config.security.acme.certs.${domains.smtp.main}.directory; virtualDomains = filterAttrs (name: _: name != domain) virtual; in { enable = true; enableSmtp = true; enableSubmission = true; enableSubmissions = true; inherit domain; hostname = domains.smtp.main; #TODO: check_recipient_access para rechazar localhost desde afuera destination = [ "localhost" "$mydomain" ]; origin = "$mydomain"; networksStyle = "host"; sslKey = "${cert}/key.pem"; sslCert = "${cert}/fullchain.pem"; # TambiƩn es postmaster rootAlias = config.local.sysadmin; extraAliases = concatStrings (flatten (mapAttrsToList (name: user: map (alias: '' ${alias}: ${name} '') user.hardAliases) users)); localRecipients = map (user: "${user}@${domain}") (attrNames (users // virtual.${domain}.users)); virtual = concatStrings (flatten (mapAttrsToList (name: virtual: mapAttrsToList (alias: targets: '' ${alias}@${name} ${concatStringsSep ", " targets} '') virtual.aliases) virtual)); mapFiles = { sender_login = pkgs.writeText "postfix-sender_login" (concatStrings (flatten (mapAttrsToList (username: user: map (alias: '' ${alias}@${domain} ${username} '') ([ username ] ++ user.hardAliases)) users))); virtual_recipients = pkgs.writeText "postfix-virtual-recipients" (concatStrings (flatten (mapAttrsToList (virtualDomain: virtual: mapAttrsToList # El lado derecho de esta tabla debe existir pero nunca se usa (username: _: '' ${username}@${virtualDomain} foo '') virtual.users) virtualDomains))); virtual_rules = pkgs.writeText "postfix-virtual-rules" (concatStrings (flatten (mapAttrsToList (name: virtual: map (rule: '' /^${rule.pattern}@${name}$/ ${concatStringsSep ", " rule.targets} '') virtual.rules) virtual))); }; config = let mdaTransport = "lmtp:inet:${cfg.mdaAddr}:${toString cfg.lmtpPort}"; in { message_size_limit = toString (50 * 1048576); virtual_alias_maps = mkAfter [ "pcre:/etc/postfix/virtual_rules" ]; virtual_mailbox_domains = attrNames virtualDomains; virtual_mailbox_maps = [ "hash:/etc/postfix/virtual_recipients" ]; local_transport = mdaTransport; virtual_transport = mdaTransport; smtpd_sasl_auth_enable = true; smtpd_sasl_type = "dovecot"; smtpd_sasl_path = "inet:${cfg.mdaAddr}:${toString cfg.saslPort}"; smtpd_sasl_tls_security_options = [ "noanonymous" ]; smtpd_tls_auth_only = true; smtpd_tls_dh1024_param_file = config.security.dhparams.params.postfix.path; smtpd_relay_restrictions = [ "permit_mynetworks" "permit_sasl_authenticated" "reject_unauth_destination" ]; smtpd_sender_login_maps = [ "hash:/etc/postfix/sender_login" ]; smtpd_sender_restrictions = [ "permit_mynetworks" "reject_sender_login_mismatch" "permit_sasl_authenticated" ]; smtpd_milters = "unix:/run/opendkim/opendkim.sock"; non_smtpd_milters = "$smtpd_milters"; milter_default_action = "accept"; }; }; services.opendkim = { enable = true; group = "postfix"; domains = "csl:${domain}"; selector = "202402"; configFile = pkgs.writeText "opendkim.conf" '' UMask 007 ''; }; security.dhparams.params.postfix = { }; networking.firewall.allowedTCPPorts = [ 25 465 ]; local = { boot.impermanence.directories = [ { directory = "/var/lib/opendkim"; user = "opendkim"; group = "postfix"; mode = "u=rwx,g=,o="; } { directory = "/var/lib/postfix"; user = "root"; group = "root"; mode = "u=rwx,g=rx,o=rx"; } ]; certs.smtp.enable = true; }; }; }