{ config, pkgs, lib, ... }: with config.krebs.lib; let cfg = config.krebs.exim-smarthost; out = { options.krebs.exim-smarthost = api; config = lib.mkIf cfg.enable imp; }; api = { enable = mkEnableOption "krebs.exim-smarthost"; internet-aliases = mkOption { type = types.listOf (types.submodule ({ options = { from = mkOption { type = types.str; # TODO e-mail address }; to = mkOption { type = types.str; # TODO e-mail address / TODO listOf }; }; })); }; relay_from_hosts = mkOption { type = with types; listOf str; default = []; }; primary_hostname = mkOption { type = types.str; default = "${config.networking.hostName}.retiolum"; }; sender_domains = mkOption { type = with types; listOf str; default = []; }; system-aliases = mkOption { type = types.listOf (types.submodule ({ options = { from = mkOption { type = types.str; # TODO e-mail address }; to = mkOption { type = types.str; # TODO e-mail address / TODO listOf }; }; })); }; }; imp = { services.exim = { enable = true; config = '' primary_hostname = ${cfg.primary_hostname} # HOST_REDIR contains the real destinations for "local_domains". #HOST_REDIR = /etc/exim4/host_redirect # Domains not listed in local_domains need to be deliverable remotely. # XXX We abuse local_domains to mean "domains, we're the gateway for". domainlist local_domains = @ : localhost domainlist relay_to_domains = hostlist relay_from_hosts = <;${concatStringsSep ";" ( [ "127.0.0.1" "::1" ] ++ cfg.relay_from_hosts )} acl_smtp_rcpt = acl_check_rcpt acl_smtp_data = acl_check_data never_users = root host_lookup = * rfc1413_hosts = * rfc1413_query_timeout = 5s log_selector = -queue_run +address_rewrite +all_parents +queue_time log_file_path = syslog syslog_timestamp = false syslog_duplication = false begin acl acl_check_rcpt: accept hosts = : control = dkim_disable_verify deny message = Restricted characters in address domains = +local_domains local_parts = ^[.] : ^.*[@%!/|] deny message = Restricted characters in address domains = !+local_domains local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ accept local_parts = postmaster domains = +local_domains accept hosts = +relay_from_hosts control = submission control = dkim_disable_verify accept authenticated = * control = submission control = dkim_disable_verify accept message = relay not permitted 2 recipients = lsearch;${lsearch.internet-aliases} require message = relay not permitted domains = +local_domains : +relay_to_domains require message = unknown user verify = recipient/callout accept acl_check_data: warn sender_domains = ${concatStringsSep ":" cfg.sender_domains} set acl_m_special_dom = $sender_address_domain accept begin routers # feature RETIOLUM_MAIL retiolum: debug_print = "R: retiolum for $local_part@$domain" driver = manualroute domains = ! ${cfg.primary_hostname} : *.retiolum transport = retiolum_smtp route_list = ^.* $0 byname no_more internet_aliases: debug_print = "R: internet_aliases for $local_part@$domain" driver = redirect data = ''${lookup{$local_part@$domain}lsearch{${lsearch.internet-aliases}}} dnslookup: debug_print = "R: dnslookup for $local_part@$domain" driver = dnslookup domains = ! +local_domains transport = remote_smtp ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 no_more system_aliases: debug_print = "R: system_aliases for $local_part@$domain" driver = redirect data = ''${lookup{$local_part}lsearch{${lsearch.system-aliases}}} local_user: debug_print = "R: local_user for $local_part@$domain" driver = accept check_local_user transport = home_maildir cannot_route_message = Unknown user begin transports retiolum_smtp: driver = smtp retry_include_ip_address = false remote_smtp: driver = smtp helo_data = ''${if eq{$acl_m_special_dom}{} \ {$primary_hostname} \ {$acl_m_special_dom} } home_maildir: driver = appendfile maildir_format maildir_use_size_file directory = $home/Mail directory_mode = 0700 delivery_date_add envelope_to_add return_path_add begin retry *.retiolum * F,42d,1m * * F,2h,15m; G,16h,1h,1.5; F,4d,6h begin rewrite begin authenticators ''; }; }; lsearch = mapAttrs (name: set: toFile name (to-lsearch set)) { inherit (cfg) internet-aliases; inherit (cfg) system-aliases; }; to-lsearch = concatMapStringsSep "\n" ({ from, to, ... }: "${from}: ${to}"); in out