{pkgs, lib, config, ...}: let inherit (builtins) attrNames; inherit (lib) types; inherit (config.services) dkim dovecot2 rmilter; createDomainDkimCert = domain: let dkim_key = "${dkim.keyDir}/${domain}.${dkim.selector}.key"; dkim_txt = "${dkim.keyDir}/${domain}.${dkim.selector}.txt"; in '' if [ ! -f "${dkim_key}" ] || [ ! -f "${dkim_txt}" ] then ${pkgs.opendkim}/bin/opendkim-genkey \ --domain "${domain}" \ --selector "${dkim.selector}" \ --directory="${dkim.keyDir}" mv "${dkim.keyDir}/${dkim.selector}.private" "${dkim_key}" mv "${dkim.keyDir}/${dkim.selector}.txt" "${dkim_txt}" fi ''; in { options.services.dkim = lib.mkOption { default = {}; type = types.submodule { options = { keyDir = lib.mkOption { type = types.path; default = "/var/lib/dkim"; description = '' ''; }; selector = lib.mkOption { type = types.str; default = "mail"; description = '' ''; }; }; }; }; config = { services.rspamd = { enable = true; }; /* services.redis = { enable = true; }; */ services.rmilter = { enable = true; #debug = true; postfix = { enable = true; }; rspamd = { enable = true; extraConfig = "extended_spam_headers = yes;"; }; extraConfig = '' use_redis = true; max_size = 20M; #clamav { # servers = /var/run/clamav/clamd.ctl; #}; # NOTE: domain = "*"; causes rmilter to try to search key in the key path # as keypath/domain.selector.key for any domain. dkim { domain { domain = "*"; key = "${dkim.keyDir}"; selector = "${dkim.selector}"; }; sign_alg = sha256; auth_only = yes; }; ''; bindSocket.type = "unix"; bindSocket.path = "/run/rmilter.sock"; # NOTE: fix default which is in wiped out directory /run/rmilter/rmilter.sock }; #systemd.sockets.rmilter.socketConfig.Accept = false; systemd.services.rmilter = { requires = [ "rmilter.socket" ]; after = [ "rmilter.socket" ]; preStart = '' install -D -d -o rmilter -g rmilter ${dkim.keyDir} ${lib.concatStringsSep "\n" (map createDomainDkimCert (attrNames dovecot2.domains))} chown -R rmilter:rmilter "${dkim.keyDir}" ''; }; }; }