[pfx] Re: cleanup(8): recipient_canonical can emit an over-long socketmap query with no operator guard; PERM then retried as 451
Dmytro Alieksieiev via Postfix-users <[email protected]> Wed, 15 Jul 2026 22:17:05 +0200
| Newsgroups | gmane.mail.postfix.user |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format.
--===============4514944276040578966==
Content-Type: multipart/alternative;
boundary="------------LvRyDTnY7bTJDcmGgM4tjFzn"
Content-Language: en-US
This is a multi-part message in MIME format.
--------------LvRyDTnY7bTJDcmGgM4tjFzn
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Hi Wietse,
Thanks — and glad we agree on the PERM/451 point; that alone would take
most of the pain out of this.
On header_checks: I don't think it can cover this one. header_checks
match a header as a single logical blob, not per-address, so I can't
express "reject/shorten the one over-long address token" — and
rewriting/truncating text inside a folded, quote-swallowed header is
fragile (the very thing that makes it dangerous, the unterminated quote,
is what makes it hard to match a stable pattern against).
I do already have finer-grained control in a milter (rspamd) in front of
the relay, but it runs into the deeper problem I mentioned: what the
milter parses and what cleanup ends up sending to the socketmap are two
different things. The milter's address parser doesn't reproduce
postfix's tok822 behavior — the unterminated quote swallowing the fold,
and cleanup appending remote_header_rewrite_domain — so the filter can't
reliably predict, let alone pre-empt, the exact key cleanup will emit.
It can approximate (flag unbalanced quotes / over-long raw tokens), but
not match postfix's own tokenization from outside.
So from my side the ideal outcomes would be either:
* reject the message at the inbound relay, before accepting it, or
* at minimum, make the outbound header_recipient canonicalization
failure non-fatal — log skip even and deliver the message rather than
cancel it.
What I'd like to avoid is accepting on the inbound relay and then
rejecting on the outbound hop, since that turns into backscatter.
For context on why I can't just filter the source: the volume is small,
but the dominant origin of these broken messages is Gmail — and since
this is already forwarded mail, blocking by sender domain isn't viable -
unpredictable, and blocking by IP isn't either (too large a provider to
ban).
Thanks again for looking at it.
Regards,
Dmytro Alieksieiev
DevOps Engineer
On 15/07/2026 21:48, Wietse Venema via Postfix-users wrote:
>> Hi Wietse, Viktor,
>>
>> I ran into a funky interaction between|recipient_canonical|header
>> rewriting and a socketmap map (PostSRSd, doing reverse-SRS), where a
>> single malformed/header/address can deterministically cancel an
>> otherwise-deliverable message. I think I've narrowed the root cause down
>> to something that postfix itself has no way to guard against, and I'd
>> love your read on it and maybe propose a way to solve this issue.
>>
>>
>> Setup
>>
>> An incoming relay accepts mail for forwarding and hands it to an
>> outgoing relay. The outgoing relay does reverse-SRS via a socketmap and
>> also canonicalizes header recipients (so the|To:|in a DSN matches the
>> real MAIL TO, per RFC 3464):
>>
>> |recipient_canonical_maps = socketmap:inet:127.0.0.1:10003:reverse
>> recipient_canonical_classes = envelope_recipient, header_recipient
>> remote_header_rewrite_domain = domain.invalid # remote clients ->
>> rewrite context = remote |
>>
>> The socketmap server is PostSRSd 2.x, but ? importantly ? it is*not*the
>> culprit; any socketmap with a bounded request buffer behaves the same
>> (see below).
> Would a header_checks pattern work around with this, like replacing
> long text with a shorter text?
>
> I agree that a PERM error should not result in a 451 status.
>
> Wietse
--------------LvRyDTnY7bTJDcmGgM4tjFzn
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi Wietse,<br>
<br>
Thanks — and glad we agree on the PERM/451 point; that alone would
take most of the pain out of this.<br>
<br>
On header_checks: I don't think it can cover this one.
header_checks match a header as a single logical blob, not
per-address, so I can't express "reject/shorten the one over-long
address token" — and rewriting/truncating text inside a folded,
quote-swallowed header is fragile (the very thing that makes it
dangerous, the unterminated quote, is what makes it hard to match
a stable pattern against).<br>
<br>
I do already have finer-grained control in a milter (rspamd) in
front of the relay, but it runs into the deeper problem I
mentioned: what the milter parses and what cleanup ends up sending
to the socketmap are two different things. The milter's address
parser doesn't reproduce postfix's tok822 behavior — the
unterminated quote swallowing the fold, and cleanup appending
remote_header_rewrite_domain — so the filter can't reliably
predict, let alone pre-empt, the exact key cleanup will emit. It
can approximate (flag unbalanced quotes / over-long raw tokens),
but not match postfix's own tokenization from outside.<br>
<br>
So from my side the ideal outcomes would be either:<br>
<br>
* reject the message at the inbound relay, before accepting it, or<br>
* at minimum, make the outbound header_recipient canonicalization
failure non-fatal — log skip even and deliver the message rather
than cancel it.</p>
<p>What I'd like to avoid is accepting on the inbound relay and then
rejecting on the outbound hop, since that turns into backscatter.<br>
<br>
For context on why I can't just filter the source: the volume is
small, but the dominant origin of these broken messages is Gmail —
and since this is already forwarded mail, blocking by sender
domain isn't viable - unpredictable, and blocking by IP isn't
either (too large a provider to ban).<br>
<br>
Thanks again for looking at it.</p>
<pre class="moz-signature" cols="72">Regards,
Dmytro Alieksieiev
DevOps Engineer</pre>
<div class="moz-cite-prefix">On 15/07/2026 21:48, Wietse Venema via
Postfix-users wrote:<br>
</div>
<blockquote type="cite"
cite="mid:[email protected]">
<pre class="moz-quote-pre" wrap=""><blockquote type="cite"
style="color: #007cff;"><pre wrap="" class="moz-quote-pre">Hi Wietse, Viktor,
I ran into a funky interaction between|recipient_canonical|header
rewriting and a socketmap map (PostSRSd, doing reverse-SRS), where a
single malformed/header/address can deterministically cancel an
otherwise-deliverable message. I think I've narrowed the root cause down
to something that postfix itself has no way to guard against, and I'd
love your read on it and maybe propose a way to solve this issue.
Setup
An incoming relay accepts mail for forwarding and hands it to an
outgoing relay. The outgoing relay does reverse-SRS via a socketmap and
also canonicalizes header recipients (so the|To:|in a DSN matches the
real MAIL TO, per RFC 3464):
|recipient_canonical_maps = socketmap:inet:127.0.0.1:10003:reverse
recipient_canonical_classes = envelope_recipient, header_recipient
remote_header_rewrite_domain = domain.invalid # remote clients ->
rewrite context = remote |
The socketmap server is PostSRSd 2.x, but ? importantly ? it is*not*the
culprit; any socketmap with a bounded request buffer behaves the same
(see below).
</pre></blockquote><pre wrap="" class="moz-quote-pre">Would a header_checks pattern work around with this, like replacing
long text with a shorter text?
I agree that a PERM error should not result in a 451 status.
Wietse</pre></pre>
</blockquote>
</body>
</html>
--------------LvRyDTnY7bTJDcmGgM4tjFzn--
--===============4514944276040578966==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
Postfix-users mailing list -- [email protected]
To unsubscribe send an email to [email protected]
--===============4514944276040578966==--