inbound-antispam-panel: inbound journal milter on port 25
Step 3/12 of docs/plans/inbound-antispam-panel.md. The panel serves a second milter while the inbound relay is on (internal/milter/inbound.go, socket INBOUND_JOURNAL_MILTER_SOCKET, default /run/selfpost/inbound-journal.sock). build/postfix-config.sh puts it last on port 25, after the optional antispam milter, with default_action=accept; postfix-wrapper.sh waits for its socket. At end-of-message it writes one inbound_spam_log row per recipient at an inbound domain - other port-25 recipients (DMARC report addresses) get none - and always accepts. With a filter attached it reads the verdict from X-Rspamd-Action and X-Spamd-Result (action, score, up to six weighted symbols, only what the patterns recognise, 255 bytes); without one those headers are the sender's and are not read. The plan named X-Rspamd-Score, which rspamd does not have. The antispam compose fragment mounts rspamd/milter_headers.conf into the sidecar so that it adds the two headers (checked in rspamd 3.11: both routines exist and remove a sender's own headers of those names). Store: InsertInboundSpam, IsInboundDomain. Checked on the test server, uncommitted tree: go vet ./... ok, go test ./... ok (22 packages), make e2e ok - the relayed message of inbound_relay_delivers_and_refuses has its journal row (accept by selfpost) and the DMARC report sent through the same listener has none. Not yet seen in a real run: a verdict written by rspamd reaching this milter. The e2e stand has no filter, and the test server's only inbound domain has no upstream, so it accepts no mail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+16
-1
@@ -10,7 +10,22 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
|
||||
- Schema: migration `0002_inbound_spam_log.sql`, the first after the 2.0
|
||||
baseline - two empty tables for the inbound antispam journal and the filter
|
||||
lists (inbound-antispam-panel). A 2.0.x database is migrated when the panel
|
||||
starts; nothing reads or writes the tables yet.
|
||||
starts.
|
||||
- **Inbound mail is recorded.** With the inbound relay on, the panel runs a
|
||||
second milter, the last one on port 25, and writes a row for every recipient
|
||||
of a message that was accepted for an inbound domain: client address,
|
||||
envelope, subject and - with a spam filter attached - the filter's action,
|
||||
score and heaviest symbols. It only watches: it refuses nothing and Postfix
|
||||
accepts mail when it is down. Refused mail is not there yet (it comes from
|
||||
the mail log, next), and there is no page for the journal yet.
|
||||
- The antispam compose fragment mounts `antispam/rspamd/milter_headers.conf`
|
||||
into the rspamd sidecar, which makes it write its verdict into
|
||||
`X-Rspamd-Action` and `X-Spamd-Result`. **Copy `deploy/antispam/rspamd/`
|
||||
next to the fragment before starting it** - Docker creates a directory in
|
||||
place of a missing file and the sidecar then fails to read its
|
||||
configuration.
|
||||
- New setting `INBOUND_JOURNAL_MILTER_SOCKET` (default
|
||||
`/run/selfpost/inbound-journal.sock`).
|
||||
|
||||
## [2.0.1] - 2026-10-11
|
||||
|
||||
|
||||
Reference in New Issue
Block a user