fruitbasket/modules/mail/rspamd.nix

219 lines
6.3 KiB
Nix

{ config, pkgs, ... }:
let
domain = "rspamd.${config.networking.domain}";
in
{
sops.secrets."rspamd-password".owner = config.users.users.rspamd.name;
users.users.rspamd.extraGroups = [ "redis-rspamd" ];
services = {
rspamd = {
enable = true;
postfix.enable = true;
locals = {
"worker-controller.inc".source = config.sops.secrets."rspamd-password".path;
"redis.conf".text = ''
read_servers = "/run/redis-rspamd/redis.sock";
write_servers = "/run/redis-rspamd/redis.sock";
'';
# headers in spamassasin style to not break old sieve scripts
"worker-proxy.inc".text = ''
spam_header = "X-Spam-Flag";
'';
"milter_headers.conf".text = ''
use = ["x-spam-level", "x-spam-status", "x-spamd-result", "authentication-results" ];
'';
"neural.conf".text = ''
servers = "/run/redis-rspamd/redis.sock";
enabled = true;
'';
"neural_group.conf".text = ''
symbols = {
"NEURAL_SPAM" {
weight = 0.5; # fairly low weight since we don't know how this will behave
description = "Neural network spam";
}
"NEURAL_HAM" {
weight = -0.5;
description = "Neural network ham";
}
}
'';
"dmarc.conf".text = ''
reporting {
enabled = true;
email = 'noreply-dmarc@${config.networking.domain}';
domain = '${config.networking.domain}';
org_name = '${config.networking.domain}';
from_name = 'DMARC Aggregate Report';
}
'';
"dkim_signing.conf".text = ''
selector = "quitte2024";
allow_username_mismatch = true;
allow_hdrfrom_mismatch = true;
use_domain_sign_local = "ifsr.de";
path = /var/lib/rspamd/dkim/$domain.$selector.key;
'';
"reputation.conf".text = ''
rules {
ip_reputation = {
selector "ip" {
}
backend "redis" {
servers = "/run/redis-rspamd/redis.sock";
}
symbol = "IP_REPUTATION";
}
spf_reputation = {
selector "spf" {
}
backend "redis" {
servers = "/run/redis-rspamd/redis.sock";
}
symbol = "SPF_REPUTATION";
}
dkim_reputation = {
selector "dkim" {
}
backend "redis" {
servers = "/run/redis-rspamd/redis.sock";
}
symbol = "DKIM_REPUTATION"; # Also adjusts scores for DKIM_ALLOW, DKIM_REJECT
}
generic_reputation = {
selector "generic" {
selector = "ip"; # see https://rspamd.com/doc/configuration/selectors.html
}
backend "redis" {
servers = "/run/redis-rspamd/redis.sock";
}
symbol = "GENERIC_REPUTATION";
}
}
'';
"groups.conf".text = ''
group "reputation" {
symbols = {
"IP_REPUTATION_HAM" {
weight = 1.0;
}
"IP_REPUTATION_SPAM" {
weight = 4.0;
}
"DKIM_REPUTATION" {
weight = 1.0;
}
"SPF_REPUTATION_HAM" {
weight = 1.0;
}
"SPF_REPUTATION_SPAM" {
weight = 2.0;
}
"GENERIC_REPUTATION" {
weight = 1.0;
}
}
}
'';
"multimap.conf".text =
let
local_ips = pkgs.writeText "localhost.map" ''
::1
127.0.0.1
'';
tud_ips = pkgs.writeText "tud.map" ''
141.30.0.0/16
141.76.0.0/16
'';
in
''
WHITELIST_SENDER_DOMAIN {
type = "from";
filter = "email:domain";
map = "/var/lib/rspamd/whitelist.sender.domain.map";
action = "accept";
regexp = true;
}
WHITELIST_SENDER_EMAIL {
type = "from";
map = "/var/lib/rspamd/whitelist.sender.email.map";
action = "accept";
regexp = true;
}
BLACKLIST_SENDER_DOMAIN {
type = "from";
filter = "email:domain";
map = "/var/lib/rspamd/blacklist.sender.domain.map";
action = "reject";
regexp = true;
}
BLACKLIST_SENDER_EMAIL {
type = "from";
map = "/var/lib/rspamd/blacklist.sender.email.map";
action = "reject";
regexp = true;
}
BLACKLIST_SUBJECT_KEYWORDS {
type = "header";
header = "Subject"
map = "/var/lib/rspamd/blacklist.keyword.subject.map";
action = "reject";
regexp = true;
}
RECEIVED_LOCALHOST {
type = "ip";
action = "accept";
map = ${local_ips};
}
RECEIVED_TU_NETWORKS {
type = "ip";
map = ${tud_ips};
}
'';
};
};
redis = {
vmOverCommit = true;
servers.rspamd = {
enable = true;
};
};
nginx = {
virtualHosts."${domain}" = {
locations = {
"/" = {
proxyPass = "http://127.0.0.1:11334";
proxyWebsockets = true;
extraConfig = ''
allow 141.30.0.0/16;
allow 141.76.0.0/16;
deny all;
'';
};
};
};
};
};
systemd = {
services.rspamd-dmarc-report = {
description = "rspamd dmarc reporter";
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.rspamd}/bin/rspamadm dmarc_report -v";
User = "rspamd";
Group = "rspamd";
};
startAt = "daily";
};
};
}