summaryrefslogtreecommitdiffstats
path: root/krebs/3modules/exim-smarthost.nix
diff options
context:
space:
mode:
Diffstat (limited to 'krebs/3modules/exim-smarthost.nix')
-rw-r--r--krebs/3modules/exim-smarthost.nix60
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: