diff options
Diffstat (limited to 'krebs/3modules/exim-smarthost.nix')
-rw-r--r-- | krebs/3modules/exim-smarthost.nix | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/krebs/3modules/exim-smarthost.nix b/krebs/3modules/exim-smarthost.nix index fe149448..4e42ce72 100644 --- a/krebs/3modules/exim-smarthost.nix +++ b/krebs/3modules/exim-smarthost.nix @@ -1,6 +1,6 @@ { config, pkgs, lib, ... }: -with import <stockholm/lib>; +with import ../../lib/pure.nix { inherit lib; }; let cfg = config.krebs.exim-smarthost; @@ -12,20 +12,22 @@ let api = { enable = mkEnableOption "krebs.exim-smarthost"; + enableSPFVerification = mkEnableOption "SPF verification"; + authenticators = mkOption { type = types.attrsOf types.str; default = {}; }; dkim = mkOption { - type = types.listOf (types.submodule ({ config, ... }: { + type = types.listOf (types.submodule (dkim: { options = { domain = mkOption { type = types.str; }; private_key = mkOption { type = types.absolute-pathname; - default = toString <secrets> + "/${config.domain}.dkim.priv"; + default = "${config.krebs.secret.directory}/${dkim.config.domain}.dkim.priv"; defaultText = "‹secrets/‹domain›.dkim.priv›"; }; selector = mkOption { @@ -37,6 +39,11 @@ let default = []; }; + extraRouters = mkOption { + type = types.nullOr types.lines; + default = null; + }; + internet-aliases = mkOption { type = types.listOf (types.submodule ({ options = { @@ -48,6 +55,7 @@ let }; }; })); + default = []; }; local_domains = mkOption { @@ -102,11 +110,12 @@ let }; }; })); + default = []; }; }; imp = { - krebs.systemd.services.exim = {}; + krebs.systemd.services.exim.restartIfCredentialsChange = true; systemd.services.exim.serviceConfig.LoadCredential = map (dkim: "${dkim.domain}.dkim_private_key:${dkim.private_key}") cfg.dkim; krebs.exim = { @@ -123,10 +132,12 @@ let # XXX We abuse local_domains to mean "domains, we're the gateway for". domainlist local_domains = ${concatStringsSep ":" cfg.local_domains} domainlist relay_to_domains = ${concatStringsSep ":" cfg.relay_to_domains} + domainlist sender_domains = ${concatStringsSep ":" cfg.sender_domains} hostlist relay_from_hosts = <;${concatStringsSep ";" cfg.relay_from_hosts} - acl_smtp_rcpt = acl_check_rcpt acl_smtp_data = acl_check_data + acl_smtp_mail = acl_check_mail + acl_smtp_rcpt = acl_check_rcpt never_users = root @@ -173,11 +184,46 @@ let acl_check_data: warn - sender_domains = ${concatStringsSep ":" cfg.sender_domains} + sender_domains = +sender_domains set acl_m_special_dom = $sender_address_domain accept + acl_check_mail: + ${if cfg.enableSPFVerification then indent /* exim */ '' + accept + authenticated = * + accept + hosts = +relay_from_hosts + deny + spf = fail : softfail + log_message = spf=$spf_result + message = SPF validation failed: \ + $sender_host_address is not allowed to send mail from \ + ''${if def:sender_address_domain\ + {$sender_address_domain}\ + {$sender_helo_name}} + deny + spf = permerror + log_message = spf=$spf_result + message = SPF validation failed: \ + syntax error in SPF record(s) for \ + ''${if def:sender_address_domain\ + {$sender_address_domain}\ + {$sender_helo_name}} + defer + spf = temperror + log_message = spf=$spf_result; deferred + message = temporary error during SPF validation; \ + please try again later + warn + spf = none : neutral + log_message = spf=$spf_result + accept + add_header = $spf_received + '' else indent /* exim */ '' + accept + ''} begin routers @@ -215,6 +261,8 @@ let transport = home_maildir cannot_route_message = Unknown user + ${lib.optionalString (cfg.extraRouters != null) cfg.extraRouters} + begin transports retiolum_smtp: |