Files
selfpost/deploy/antispam/rspamd/multimap.conf
T
mixandClaude Opus 5.5 31c2b50457
test / test (push) Canceled after 0s
antispam: rspamd strips a sender's own verdict for every client
rspamd 3.11.1's milter_headers skips its verdict routines - removes none
of the sender's X-Spamd-Result / X-Rspamd-Action, adds none - for a client
it counts as local (loopback, a unix socket, local_addrs: the private
ranges) or one that authenticated (skip_local, skip_authenticated, both on
by default; milter_headers.lua skip_wanted(), lua_ip.c lua_ip_is_local()).
The custom routine that signs X-SelfPost-Filter is never put through
skip_wanted(), so it signed the sender's own verdict, and Inbound > Log
showed it as rspamd's. Every sender is private when Docker's proxy relays
port 25 from the bridge gateway. Both options set to false.

Tried 2026-10-14 in a throwaway rspamd/rspamd:3.11.1-3 on the test server
(rspamc --ucl, a message carrying its own verdict headers): old config,
from 10.0.0.5 and as an authenticated user, the milter reply removed and
added neither and added the signature; new config, both removed and
rspamd's own added, as from 203.0.113.9.

Also: the sender rules take the envelope only (extract_from = "smtp"; by
default a bounce's From: header is used - tried: a bounce whose From:
domain is denied was refused before, is not now; a denied sender is
refused either way); the image pinned to 3.11.1-3, the build read (3.11 and
3.11.1 move with each rebuild); the prefilter lines no longer read go.
architecture.md and security.md say so. Assumptions C-R7, B-R1, C-R4,
C-R12, C-R5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 19:48:07 +03:00

91 lines
3.8 KiB
Plaintext

# Mounted into the sidecar as /etc/rspamd/local.d/multimap.conf.
#
# The allow and deny lists kept in the panel (Inbound > Filter lists). SelfPost
# writes them as six files under data/antispam/, which the fragment mounts at
# /etc/rspamd/selfpost; rspamd rereads a file when it changes, no restart.
# (rspamd 3.11.1, src/libserver/maps/map.c: a file map is watched with libev's
# ev_stat - inotify where the kernel has it, else a stat poll every
# map_watch_interval x map_file_watch_multiplier, 5min x 0.1, conf/options.inc;
# docs.rspamd.com/configuration/maps asks for an atomic rename, which
# internal/inbound writes with.)
#
# Deny wins over allow, whichever entries match. A denied sender is refused
# whatever else is found (the rule's action is a pre-result, below). An
# allowed one is not accepted outright - rspamd would then let whichever of
# the two rules ran first decide - but given a weight no spam score
# outweighs, which a refusal by the deny list still overrides. (rspamd
# 3.11.1, src/plugins/lua/multimap.lua: every rule is registered as a
# "normal" symbol, one with an action with the "passthrough" augmentation;
# no "prefilter" setting is read.)
#
# A sender rule looks at the envelope sender only, extract_from = "smtp":
# by default multimap.lua takes the header From: when the envelope sender is
# empty (the "from" callback, has_from('smtp') then has_from('mime')), so a
# bounce would be judged by an address the panel never counts it under
# (assumptions C-R4). Tried on 2026-10-14 in rspamd/rspamd:3.11.1-3: a
# bounce whose From: domain is on the deny list was refused by default and
# is not with this setting; a sender on the list is refused either way.
#
# A domain entry is that domain, not its subdomains. (rspamd 3.11.1,
# src/libserver/maps/map_helpers.c: a hash map is looked up by the whole key,
# case-insensitively - rspamd_icase_hash, rspamd_lc_cmp; "email:domain" gives
# the address's domain part, src/plugins/lua/multimap.lua, apply_addr_filter().)
#
# A refusal is rspamd's "pre-result": multimap.lua calls task:set_pre_result()
# with the rule's action and message, and that action stands whatever the score
# (docs.rspamd.com/modules/multimap, "action"). The message reaches the client
# as "554 5.7.1 <message>": src/libserver/protocol.c, rspamd_scan_result_ucl(),
# puts it into messages.smtp_message, src/libserver/milter.c,
# rspamd_milter_send_task_results(), replies with it.
#
# SelfPost counts how often an entry decided a message by what these rules
# leave behind: the deny message below and the names of the allow symbols.
# Change either and Inbound > Filter lists shows "never" for every entry.
SELFPOST_DENY_IP {
type = "ip";
map = "/etc/rspamd/selfpost/deny_ip.map";
action = "reject";
message = "Refused by this server's deny list";
description = "Client address on the deny list";
}
SELFPOST_DENY_FROM {
type = "from";
extract_from = "smtp";
map = "/etc/rspamd/selfpost/deny_from.map";
action = "reject";
message = "Refused by this server's deny list";
description = "Sender address on the deny list";
}
SELFPOST_DENY_DOMAIN {
type = "from";
extract_from = "smtp";
filter = "email:domain";
map = "/etc/rspamd/selfpost/deny_domain.map";
action = "reject";
message = "Refused by this server's deny list";
description = "Sender domain on the deny list";
}
SELFPOST_ALLOW_IP {
type = "ip";
map = "/etc/rspamd/selfpost/allow_ip.map";
score = -100.0;
description = "Client address on the allow list";
}
SELFPOST_ALLOW_FROM {
type = "from";
extract_from = "smtp";
map = "/etc/rspamd/selfpost/allow_from.map";
score = -100.0;
description = "Sender address on the allow list";
}
SELFPOST_ALLOW_DOMAIN {
type = "from";
extract_from = "smtp";
filter = "email:domain";
map = "/etc/rspamd/selfpost/allow_domain.map";
score = -100.0;
description = "Sender domain on the allow list";
}