(Please note that I also changed the remainder of the subject line to
try and avoid further confusion.)

On 06-08-18 20:48, Wietse Venema wrote:
> Luc Pardon:
>> The only "problem" that I am trying to solve is how to detect that the
>> other side is telling me to re-send through my ISP, so that I can oblige.
>>
>> With other types of 5xx, I would of course let the mail bounce as usual.
> 
> Conceivably, you could use the smtp_delivery_status_filter feature
> to selectively replace 5xx responses with 4xx if the receiver does
> not say things that look like 'user unknown'.
> 

Yes, that was indeed what I ended up using (with the minor difference
that I go looking for strings like "blocked using ...", to be more
selective).

Thanks for confirming that this hook was the proper thing to look at.

> Combined with smtp_fallback_relay=[mail.isp.com], this would punt
> potentially resendable mail to the ISP.
> 

I decided to work with transport maps instead, one per domain.

One of the reasons is that, if I already know that example.com doesn't
like my current IP, it doesn't feel right to keep trying again and again
for each and every message. With a low traffic site like mine, the extra
load on example.com may be negligible, but in any case it serves no
useful purpose (unlike greylisting, SAV, etc.). Compare to my restaurant
example: if I know that they want me to wear a tie, it is only proper to
remember to put one on before I go there next time.

Another (very) important reason to _not_ use smtp_fallback_relay is
that, unless I am mistaken, *all* the deferred mail would go to the
relay, including mails that are being greylisted by domains that would
otherwise accept them directly from me after the greylist time.

That is Doubleplus Ungood, because - as I repeatedly said - I want to
avoid to relay if I can. Sending via an ISP in Belgium is asking for
trouble, believe me.


Bottom line, when my DSN filter detects one of the "blocked using ..."
tell-tale strings, it first creates the appropriate
"nexthop=mail.isp.com" transport map for the example.com domain, and
then it defers the mail by returning "4xx" instead of the original "5xx".

At the next attempt to deliver the mail to john....@example.com, the
"example.com" transport map will be waiting for it.

Problem solved.



Of course, the disadvantage (for my purpose) of transport maps is
precisely that they are "static". Meaning, once the map for example.com
is in place, all the mail for them will go through "mail.isp.com"
forever and ever - until the map gets removed again.

Now, example.com may refuse my IP today, yet they may start to accept it
tomorrow, or next week, or whenever my (then current) IP is not (or no
longer) listed by the RBL's they consult.

This has happened before, even in the short time (a little over 2 weeks
now) that I was forced from static to dynamic, and even though I am
forcing a DSL reconnect every night, just to stress-test the whole thing.

So yes, it really can happen that example.com "changes their mind" over
time.

But because of the transport map, created at their first refusal, I
would keep sending through the relay for nothing, because they would now
accept direct delivery if I tried.


So I keep the maps in an SQL table and plugged a tcp_table map script
into the "transport_maps" hook.

If the table script finds an expired transport map for example.com, that
map will be ignored, and the mail will "go direct" again.

Time will tell how best to expire the maps, but anyway these details are
not relevant to get the overall picture.


You may wonder how the DSN filter knows how to insert a map for
example.com, since it doesn't know the intended recipient address?

Indeed, the filter map gets only queried with this:

    enhanced-status-code SPACE explanatory-text

And of course the explanatory text in this case does not usually mention
the recipient...

Taking that hurdle was actually the easier part of the job. A few minor
changes to the Postfix source code were enough to make the
dsn_filter_lookup() function (in global/dsn_filter.c) take an extra
"RECIPIENT *rcpt" parameter, so that it now can (and does) query the
maps with:

    recipient-address SPACE enhanced-status-code SPACE explanatory-text


Of course, this is a radically incompatible change that brutally breaks
all existing DSN filters big time, but I myself had no such filters
before, so there were none to break, and, as a private patch (applied
here on my own computer when I compile my own Postfix from source for my
own use), it serves me just fine.


So, as I said, problem solved.

It has been working fine for several days now. We'll see what happens in
the future.


Anyway, all it took was a handful lines of (mostly boilerplate) Perl code.

As to Postfix itself, it says much about the quality of the code that I
had only 9 lines to change and one to add (not including some comments
and one change to a debug statement).

All in all it was well worth the relatively small effort, if only to see
what the real issues are when sending mail from a dynamic IP...

Technical comments welcome, although I have left out a lot of irrelevant
details in the outline above.

Luc

Reply via email to