antispam: rspamd strips a sender's own verdict for every client
test / test (push) Canceled after 0s
test / test (push) Canceled after 0s
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>
This commit is contained in:
@@ -118,11 +118,15 @@ smtp/inet` removes Debian's stock smtpd). Outbound delivery still uses the
|
||||
every change and on every start with the relay on. SelfPost never consults
|
||||
them. The sidecar mounts the directory and rspamd's multimap rules
|
||||
([deploy/antispam/rspamd/multimap.conf](../deploy/antispam/rspamd/multimap.conf))
|
||||
read them: a deny entry is a prefilter `reject`, an allow entry a symbol
|
||||
weighing -100. Allow is deliberately not a prefilter `accept`: with two
|
||||
prefilters rspamd lets the one that ran first decide, and deny then won or
|
||||
lost by rule order (seen on rspamd 3.11). A refusal by the deny list
|
||||
overrides any score, so deny wins whichever entries match.
|
||||
read them: a deny entry's rule carries the action `reject`, which rspamd
|
||||
sets as a pre-result, an allow entry is a symbol weighing -100. Allow is
|
||||
deliberately not an `accept` action: with two pre-results rspamd keeps the
|
||||
one set first, and deny then won or lost by rule order (seen on rspamd
|
||||
3.11, date not recorded). A refusal by the deny list overrides any score,
|
||||
so deny wins whichever entries match. A sender entry is matched against
|
||||
the envelope sender only (`extract_from = "smtp"`; by default rspamd takes
|
||||
a bounce's `From:` header instead - rspamd 3.11.1,
|
||||
`src/plugins/lua/multimap.lua`, the `from` callback).
|
||||
How often an entry decided a message is not stored: `Lists.Usage` reads it
|
||||
off the journal on each view of Filter lists - the rows a list decided (the
|
||||
deny rule's reply, the allow rule's symbol, which the journal milter keeps
|
||||
|
||||
+10
-3
@@ -261,7 +261,13 @@ operator can act on it.
|
||||
keeps of the filter's verdict only what its patterns recognise. **A verdict
|
||||
is read only next to the filter's signature.** The filter is attached so
|
||||
that mail flows when it is down, and then nothing removes verdict headers a
|
||||
sender wrote himself. So rspamd adds a third header, `X-SelfPost-Filter`:
|
||||
sender wrote himself. Nor would rspamd itself by default for a client it
|
||||
counts as local - a private address, which every client has when Docker's
|
||||
proxy relays port 25 - or an authenticated one: `skip_local` and
|
||||
`skip_authenticated` (rspamd 3.11.1, `milter_headers.lua`, `skip_wanted()`)
|
||||
leave the sender's headers in place, while the signing routine below runs
|
||||
regardless; both are turned off in `milter_headers.conf` (assumptions
|
||||
C-R7, tried on 2026-10-14). So rspamd adds a third header, `X-SelfPost-Filter`:
|
||||
the HMAC-SHA256 of the message's queue id under a key SelfPost generates
|
||||
(`data/antispam/filter.key`) and the sidecar reads from the directory it
|
||||
mounts. The journal milter recomputes it at end-of-message; with no
|
||||
@@ -427,8 +433,9 @@ deferred item from the roadmap.
|
||||
Senders on the internet, whom the signature is for, cannot read it. Trigger
|
||||
to revisit: the same as for the list files - a shared host.
|
||||
- **An allow entry for a sender address or domain trusts what the sending
|
||||
server says.** The filter matches the envelope sender, which is not
|
||||
authenticated: anyone who knows or guesses an allowed address can send as it
|
||||
server says.** The filter matches the envelope sender (only that: a
|
||||
bounce's `From:` header is not looked at, `extract_from = "smtp"`), which
|
||||
is not authenticated: anyone who knows or guesses an allowed address can send as it
|
||||
and is given the entry's weight, which no spam score outweighs. The page's
|
||||
Help and the guide say so and recommend an entry for the client's address or
|
||||
network instead. Deny entries have no such problem - claiming to be a denied
|
||||
|
||||
Reference in New Issue
Block a user