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:
@@ -47,9 +47,10 @@ var port25Cases = []port25Case{
|
||||
{param: "smtpd_sasl_auth_enable", contains: "no", wantExact: true},
|
||||
{param: "smtpd_relay_restrictions", contains: "reject_unauth_destination", wantExact: true},
|
||||
{param: "smtpd_recipient_restrictions", contains: "reject_unauth_destination,reject_unlisted_recipient", wantExact: true},
|
||||
// No antispam milter configured: the submission chain (strict
|
||||
// OpenDKIM + journal-milter) must not reach inbound mail.
|
||||
{param: "smtpd_milters", contains: "", wantExact: true},
|
||||
// No antispam milter configured: the inbound journal milter
|
||||
// alone. The submission chain (strict OpenDKIM + journal-milter)
|
||||
// must not reach inbound mail.
|
||||
{param: "smtpd_milters", contains: "{unix:/run/selfpost/inbound-journal.sock,default_action=accept}", wantExact: true},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -72,7 +73,7 @@ var port25Cases = []port25Case{
|
||||
},
|
||||
check: []optionCheck{
|
||||
{param: "smtpd_recipient_restrictions", contains: "check_recipient_access,texthash:/data/postfix/dmarc_recipients,reject_unauth_destination,reject_unlisted_recipient", wantExact: true},
|
||||
{param: "smtpd_milters", contains: "", wantExact: true},
|
||||
{param: "smtpd_milters", contains: "{unix:/run/selfpost/inbound-journal.sock,default_action=accept}", wantExact: true},
|
||||
},
|
||||
// Both on: the report addresses sit on a relay domain, and the relay's
|
||||
// unlisted-recipient check runs after the restriction list. Unless their
|
||||
@@ -94,7 +95,7 @@ var port25Cases = []port25Case{
|
||||
check: []optionCheck{
|
||||
// Exact equality also covers the absence of OpenDKIM/journal-milter
|
||||
// sockets — anything else there would fail the comparison.
|
||||
{param: "smtpd_milters", contains: "{inet:antispam:11332,default_action=accept}", wantExact: true},
|
||||
{param: "smtpd_milters", contains: "{inet:antispam:11332,default_action=accept},{unix:/run/selfpost/inbound-journal.sock,default_action=accept}", wantExact: true},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user