postfix config: port 25's size limit for cleanup too, no local delivery
Port 25 says it takes INBOUND_MESSAGE_SIZE_LIMIT (25 MiB by default) with smtpd -o message_size_limit, but cleanup writes the queue file under its own limit, main.cf's - never set, so DEF_MESSAGE_LIMIT, 10240000 (Postfix 3.7.11, src/cleanup/cleanup_init.c, cleanup_post_jail(), set_file_limit(); src/global/mail_params.h). A larger message went through DATA and was refused 552 (assumptions C-P31). cleanup now gets port 25's limit as a master.cf -o when it is larger than main.cf's; 465 and 587 keep main.cf's in smtpd's own DATA/BDAT checks. /etc/postfix outlives a restart, so the override is removed with postconf -PX first on every start. An empty mydestination left one local destination: an address literal of an interface the container listens on (src/global/resolve_local.c, resolve_local(), own_inet_addr()). local_transport is now "error:local mail delivery is disabled", as STANDARD_CONFIGURATION_README's null client has it (assumptions C-P8). Stand (2026-10-14, make e2e, exit 0): inbound_relay_delivers_and_refuses sends a 12 MB message through port 25 and finds it at the upstream, and counts it among the Inbound log's rows; new address_literal_is_not_local - probe@[127.0.0.1] from an application is refused at RCPT "550 5.1.1 ... local mail delivery is disabled" (smtpd's check_rcpt_maps() rejects what resolves to the error transport; before, local(8) took it). go vet and go test ./... pass on the server (23 packages). Tested together with the next commit (the log tailer); the two touch no common file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -268,6 +268,21 @@ func testInboundRelay(t *testing.T, sc *scenario) {
|
||||
t.Fatalf("mail for the inbound domain never reached its upstream: %v\n%s", err, mailLogTail(h, "postfix/"))
|
||||
}
|
||||
|
||||
// Port 25's limit is the whole limit: a 12 MB message - over the
|
||||
// 10240000 bytes cleanup would hold it to on its own, under the 25 MiB the
|
||||
// listener says - is accepted and passed on (Postfix 3.7.11,
|
||||
// src/cleanup/cleanup_init.c, cleanup_post_jail(); assumptions C-P31).
|
||||
big := uniqueToken("inbound-12mb")
|
||||
line := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ab\r\n"
|
||||
bigBody := strings.Repeat(line, 12*1000*1000/len(line))
|
||||
if res := deliverPort25("someone@stranger.e2e.test", inboundRecipient,
|
||||
strings.Replace(message(inboundRecipient, big), "mail for the inbound domain\r\n", bigBody, 1)); !res.ok() {
|
||||
t.Fatalf("port 25 refused a 12 MB message: %v\n%s", res.firstErr(), mailLogTail(h, "postfix/"))
|
||||
}
|
||||
if _, err := findSinkMessage(h.stageDir, big, 60*time.Second); err != nil {
|
||||
t.Fatalf("the 12 MB message never reached the upstream: %v\n%s", err, mailLogTail(h, "postfix/"))
|
||||
}
|
||||
|
||||
// The filter lists exist as files from the first start with the relay on,
|
||||
// readable by a filter that is another user in another container. Nothing
|
||||
// is on them until someone adds an entry.
|
||||
@@ -335,7 +350,8 @@ func testInboundRelay(t *testing.T, sc *scenario) {
|
||||
return ""
|
||||
}
|
||||
|
||||
rows := logRows("e2e " + token)
|
||||
rows := logRows("e2e " + big)
|
||||
rowWith(rows, "user@<wbr>"+inboundDomain, "e2e "+big, `class="tag is-success is-light" popovertarget="why-`)
|
||||
rowWith(rows,
|
||||
"someone@<wbr>stranger.e2e.test", "user@<wbr>"+inboundDomain, "e2e "+token,
|
||||
`class="tag is-success is-light" popovertarget="why-`, `<th>Decided by</th><td>selfpost</td>`,
|
||||
@@ -343,8 +359,8 @@ func testInboundRelay(t *testing.T, sc *scenario) {
|
||||
`href="/inbound/filter-lists?list=deny&kind=address&value=someone%40stranger.e2e.test">Deny sender</a>`)
|
||||
// A report mailed to the server's own name earlier in the run came through
|
||||
// the same listener and is not the relay's mail.
|
||||
if len(rows) != 1 {
|
||||
t.Fatalf("the Inbound log holds %d rows, want the relayed message alone:\n%s", len(rows), strings.Join(rows, "\n"))
|
||||
if len(rows) != 2 {
|
||||
t.Fatalf("the Inbound log holds %d rows, want the two relayed messages alone:\n%s", len(rows), strings.Join(rows, "\n"))
|
||||
}
|
||||
|
||||
// Postfix 3.7.11, src/smtpd/smtpd_check.c: "User unknown in relay recipient
|
||||
@@ -377,8 +393,8 @@ func testInboundRelay(t *testing.T, sc *scenario) {
|
||||
if strings.Contains(refused, "sender</a>") {
|
||||
t.Fatalf("the refused row offers a way into the filter lists:\n%s", refused)
|
||||
}
|
||||
if len(rows) != 2 {
|
||||
t.Fatalf("the Inbound log holds %d rows, want the relayed message and one refusal:\n%s", len(rows), strings.Join(rows, "\n"))
|
||||
if len(rows) != 3 {
|
||||
t.Fatalf("the Inbound log holds %d rows, want the two relayed messages and one refusal:\n%s", len(rows), strings.Join(rows, "\n"))
|
||||
}
|
||||
|
||||
// The filter lists: an entry added in the panel is in the map file the
|
||||
|
||||
Reference in New Issue
Block a user