Merge options virtualAccountAliases and virtualDomainAliases into virtualAliases

This commit is contained in:
Thomas Preisner 2025-02-22 19:52:13 +01:00
parent faf6f549b0
commit a1e87f70fa
3 changed files with 49 additions and 57 deletions

View file

@ -15,33 +15,27 @@ with (import ./common.nix {inherit config;}); let
mergeLookupTables lookupTables;
lookupTableToString = attrs: let
valueToString = value: lib.concatStringsSep ", " value;
isDomain = value: !(lib.hasInfix "@" value);
valueToString = value:
if (isDomain value)
then "@${value}"
else value;
listToString = list: lib.concatStringsSep ", " (map valueToString list);
in
lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name} ${valueToString value}") attrs);
lib.concatStringsSep "\n" (lib.mapAttrsToList (name: list: "${valueToString name} ${listToString list}") attrs);
mergeLookupTables = tables: lib.zipAttrsWith (n: v: lib.flatten v) tables;
virtual_accounts = mergeLookupTables (lib.map (name: {"${name}" = name;}) (lib.attrNames cfg.accounts));
virtual_account_aliases = attrsToLookupTable cfg.virtualAccountAliases;
virtual_domain_aliases = let
alias_domains = lib.mapAttrs' (src: dst: lib.nameValuePair "@${src}" "@${dst}") cfg.virtualDomainAliases;
in
attrsToLookupTable alias_domains;
all_virtual_aliases = mergeLookupTables [virtual_accounts virtual_account_aliases virtual_domain_aliases];
virtual_aliases = attrsToLookupTable cfg.virtualAliases;
all_virtual_aliases = mergeLookupTables [virtual_accounts virtual_aliases];
# File containing all mappings of aliases/authenticated accounts and their sender mail addresses.
aliases_file = let
content = lookupTableToString all_virtual_aliases;
in
builtins.toFile "virtual_aliases" content;
# File containing all mappings of authenticated accounts and their sender mail addresses.
virtual_accounts_file = let
content = lookupTableToString all_virtual_aliases;
in
builtins.toFile "virtual_accounts" content;
virtual_domains_file = builtins.toFile "virtual_domains" (lib.concatStringsSep "\n" cfg.domains);
denied_recipients = map (account: "${account.name} REJECT ${account.rejectMessage}") (lib.filter (account: account.isSystemUser) (lib.attrValues cfg.accounts));
@ -67,14 +61,15 @@ with (import ./common.nix {inherit config;}); let
tls_exclude_ciphers = "MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL";
in {
config = lib.mkIf cfg.enable {
assertions =
lib.mapAttrsToList (
src: dst: {
assertion = (builtins.elem src cfg.domains) && (builtins.elem dst cfg.domains);
message = "Both aliased domain (${src}) and actual domain (${dst}) need to be managed by the mailserver.";
}
)
cfg.virtualDomainAliases;
assertions = let
isDomain = value: !lib.hasInfix "@" value;
aliasedDomains = builtins.filter isDomain (builtins.attrNames cfg.virtualAliases);
in
map (domain: {
assertion = builtins.elem domain cfg.domains;
message = "The domain to be aliased (${domain}) must be managed by the mailserver.";
})
aliasedDomains;
services.postfix = {
enable = true;
@ -86,9 +81,7 @@ in {
enableSubmissions = true;
# TODO: create function to simplify this?
mapFiles."virtual_aliases" = aliases_file;
mapFiles."virtual_accounts" = virtual_accounts_file;
mapFiles."denied_recipients" = denied_recipients_file;
virtual = lookupTableToString all_virtual_aliases;
@ -100,8 +93,7 @@ in {
smtpd_sasl_security_options = "noanonymous";
smtpd_sasl_local_domain = "$myhostname";
smtpd_client_restrictions = "permit_sasl_authenticated,reject";
# use mappedFile -> different path?
smtpd_sender_login_maps = "hash:/etc/postfix/virtual_accounts";
smtpd_sender_login_maps = mappedFile "virtual_aliases";
smtpd_sender_restrictions = "reject_sender_login_mismatch";
smtpd_recipient_restrictions = "reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject";
cleanup_service_name = "submission-header-cleanup";