{ pkgs, lib, config, ... }: let inherit (builtins) attrNames listToAttrs readFile; inherit (lib) types; inherit (pkgs.lib) unlinesAttrs; inherit (config.security) gnupg; inherit (config.services) postfix rspamd dovecot2; redis = config.services.redis.servers.rspamd; inherit (config.users) users groups; in { imports = [ rspamd/autogeree.net.nix rspamd/sourcephile.fr.nix ]; options = { services.rspamd.dkimSelectorMap = lib.mkOption { type = types.lines; default = ""; description = ''Each line maps a domain to its active DKIM selector''; apply = s: pkgs.writeText "dkim_selectors.map" s; }; }; config = { users.groups.redis-rspamd.members = [ rspamd.user ]; users.groups.keys.members = [ rspamd.user ]; services.rspamd = { enable = true; debug = false; postfix.enable = postfix.enable; locals = { "dkim_signing.conf".text = '' selector_map = ${rspamd.dkimSelectorMap}; path = "/run/keys/gnupg/rspamd/dkim/$domain/$selector.key/file"; allow_username_mismatch = true; ''; "arc.conf".text = '' selector_map = ${rspamd.dkimSelectorMap}; path = "/run/keys/gnupg/rspamd/dkim/$domain/$selector.key/file"; allow_username_mismatch = true; ''; "redis.conf".text = '' servers = "${redis.unixSocket}"; db = "1"; ''; "classifier-bayes.conf".text = '' users_enabled = false; backend = "redis"; servers = "${redis.unixSocket}"; database = "1"; autolearn = true; cache { backend = "redis"; } new_schema = true; statfile { BAYES_HAM { spam = false; } BAYES_SPAM { spam = true; } } ''; /* "logging.conf" = '' debug_modules = [“dkim_signing”] ''; */ }; overrides = { "milter_headers.conf".text = '' extended_spam_headers = true; ''; "actions.conf".text = '' reject = 15; # Reject when reaching this score add_header = 6; # Add header when reaching this score greylist = 4; # Apply greylisting when reaching this score (will emit `soft reject action`) ''; }; workers = { learner = { # Like controller but without a password, only the bindSockets' permissions type = "controller"; includes = [ "$CONFDIR/worker-controller.inc" ]; bindSockets = [ { socket = "/run/rspamd/learner.sock"; mode = "0660"; owner = "${rspamd.user}"; group = "${dovecot2.group}"; } ]; extraConfig = '' ''; }; controller = { includes = [ "$CONFDIR/worker-controller.inc" gnupg.secrets."rspamd/controller/hashedPassword".path ]; bindSockets = [ "127.0.0.1:11334" ]; extraConfig = '' #count = 1; #static_dir = "''${WWWDIR}"; ''; }; }; }; security.gnupg.secrets."rspamd/controller/hashedPassword" = { # Generated with: rspamadm pw user = rspamd.user; pipe = ''${pkgs.gnused}/bin/sed -e 's/.*/password = "\0";/' ''; systemdConfig.postStart = "systemctl try-restart --no-block rspamd"; # rspamd does not support reloading so far }; systemd.services.rspamd = { wants = [ gnupg.secrets."rspamd/controller/hashedPassword".service ]; after = [ gnupg.secrets."rspamd/controller/hashedPassword".service ]; }; fileSystems."/var/lib/redis-rspamd" = { device = "rpool/var/redis-rspamd"; fsType = "zfs"; }; services.sanoid.datasets."rpool/var/redis-rspamd" = { use_template = [ "snap" ]; hourly = 0; daily = 7; monthly = 0; yearly = 0; }; services.redis.vmOverCommit = true; services.redis.servers.rspamd = { enable = true; databases = 16; syslog = true; bind = "127.0.0.1 ::1"; save = [ [1800 100] [300 1000] ]; #unixSocketPerm = "660"; settings = { maxmemory = "512MB"; maxmemory-policy = "volatile-ttl"; }; }; /* services.postfix.extraConfig = '' smtpd_milters = unix:/run/rspamd.sock milter_default_action = accept ''; # Allow users to run 'rspamc' and 'rspamadm'. environment.systemPackages = [ pkgs.rspamd ]; */ }; }