Quantcast

Restarting milter application

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Restarting milter application

Purushotham Nayak
Hi All,

I have a question about the correct way to restart a milter application.

I'm using postfix 2.6.6 with a milter application that was built using sendmail's libmilter (8.14.7). The problem I'm having is when I need to restart the milter application (due to a config change for example), I send it a SIGTERM and then start it up again.

However, an smtpd instance that was running which was already connected to milter will not try to connect to the milter after the milter has been restarted. But when a new SMTP connection arrives from the client the new smtpd will connect to the milter application and all processing works correctly. Is this the expected behavior?  or have a missed something in the configuration / or possibly in the code? (To debug, I'm just using the sample that comes with sendmail). Is there a way to get smtpd to send tempfail to client when milter is not there but once the milter starts up and is listening again smtpd reconnects
and starts sending data to the milter.


In main.cf I have:

milter_default_action = tempfail
smtpd_milters = inet:localhost:10025
milter_protocol = 2

tcpdump output shows:
localhost.45724 > localhost.10025: Flags [.], ack 89, win 33, length 0
localhost.10025 > localhost.45724: Flags [F.], seq 89, ack 588, win 36, length 0             ==> milter application received SIGTERM
localhost.45724 > localhost.10025: Flags [.], ack 90, win 33, length 0
localhost.45724 > localhost.10025: Flags [P.], seq 588:733, ack 90, win 33, length 145  ==> SMIFC_ABORT
localhost.10025 > localhost.45724: Flags [R], seq 1329360186, win 0, length 0              ==> Reset since milter application has restarted

Thanks,
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Restarting milter application

Wietse Venema
Purushotham Nayak:

> Hi All,
>
> I have a question about the correct way to restart a milter application.
>
> I'm using postfix 2.6.6 with a milter application that was built using
> sendmail's libmilter (8.14.7). The problem I'm having is when I need to
> restart the milter application (due to a config change for example), I send
> it a SIGTERM and then start it up again.
>
> However, an smtpd instance that was running which was already connected to
> milter will not try to connect to the milter after the milter has been
> restarted.

When the milter process is stopped, it loses state of the sessions
that were in progress.

Postfix does not connect to a milter in the middle of an SMTP
session, because libmilter has to be able to see all stages of the
protocol.

> Is there a way to get smtpd to send tempfail to client when milter
> is not there

I would expect that Postfix does that by default.

> But once the milter starts up and is listening again smtpd reconnects
> and starts sending data to the milter.

No, see above.

        Wietse
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Restarting milter application

Purushotham Nayak
Thanks so much for the information! Also, tempfail does work correctly. But couple of questions though,

1. When default action is tempfail and the milter is unavailable, smtpd sends 451 (Requested action aborted: error in processing). Wonder if there is a way to send 421 (Service not available, closing transmission channel) and then close the connection. 451 works fine except that some of the clients keeps retrying for several minutes before giving up and creating a new connection. If we have a config option to send 421 and close the connection it might help it be faster.

2. I noticed that when the milter application exits, it sends FIN to smtpd but smtpd keeps the connection open in the CLOSE_WAIT state. When the client sends something new and smptd tries to send SMFIC_ABORT to the milter on the old connection in the CLOSE_WAIT state it gets a reset and then the connection is closed. This is not really a problem, but just that the socket stays in CLOSE_WAIT state sometimes for a long time if there is nothing new from the client.

Thanks,
Purush  

On Wed, May 10, 2017 at 1:33 PM, Wietse Venema <[hidden email]> wrote:
Purushotham Nayak:
> Hi All,
>
> I have a question about the correct way to restart a milter application.
>
> I'm using postfix 2.6.6 with a milter application that was built using
> sendmail's libmilter (8.14.7). The problem I'm having is when I need to
> restart the milter application (due to a config change for example), I send
> it a SIGTERM and then start it up again.
>
> However, an smtpd instance that was running which was already connected to
> milter will not try to connect to the milter after the milter has been
> restarted.

When the milter process is stopped, it loses state of the sessions
that were in progress.

Postfix does not connect to a milter in the middle of an SMTP
session, because libmilter has to be able to see all stages of the
protocol.

> Is there a way to get smtpd to send tempfail to client when milter
> is not there

I would expect that Postfix does that by default.

> But once the milter starts up and is listening again smtpd reconnects
> and starts sending data to the milter.

No, see above.

        Wietse

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Restarting milter application

Viktor Dukhovni

> On May 11, 2017, at 12:16 PM, Purushotham Nayak <[hidden email]> wrote:
>
> 2. I noticed that when the milter application exits, it sends FIN to smtpd but smtpd keeps the connection open in the CLOSE_WAIT state. When the client sends something new and smptd tries to send SMFIC_ABORT to the milter on the old connection in the CLOSE_WAIT state it gets a reset and then the connection is closed. This is not really a problem, but just that the socket stays in CLOSE_WAIT state sometimes for a long time if there is nothing new from the client.

The smtpd(8) process is single-threaded, and only looks at the milter connection
when it is using the milter.   If the milter connection closes while smtpd(8) is
doing other things, it will be kept open until it is time to try to use it.

If you are in the habit of restarting milters, you may as well at least "postfix
reload" when you do so.  A more invasive:

        postfix stop; delay?; <milter> stop; <milter> start; delay?; postfix start

will ensure no anomalies in milter use while the milter is down.

--
        Viktor.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Restarting milter application

Purushotham Nayak
Combining milter restart with postfix reload sounds like a good suggestion. Our milter restarts due on rare occasions due to upstream changes, but combining it with postfix reload or postfix -> milter seems good solution. Thanks very much for your input.

Thanks,
Purush

On Thu, May 11, 2017 at 12:22 PM, Viktor Dukhovni <[hidden email]> wrote:

> On May 11, 2017, at 12:16 PM, Purushotham Nayak <[hidden email]> wrote:
>
> 2. I noticed that when the milter application exits, it sends FIN to smtpd but smtpd keeps the connection open in the CLOSE_WAIT state. When the client sends something new and smptd tries to send SMFIC_ABORT to the milter on the old connection in the CLOSE_WAIT state it gets a reset and then the connection is closed. This is not really a problem, but just that the socket stays in CLOSE_WAIT state sometimes for a long time if there is nothing new from the client.

The smtpd(8) process is single-threaded, and only looks at the milter connection
when it is using the milter.   If the milter connection closes while smtpd(8) is
doing other things, it will be kept open until it is time to try to use it.

If you are in the habit of restarting milters, you may as well at least "postfix
reload" when you do so.  A more invasive:

        postfix stop; delay?; <milter> stop; <milter> start; delay?; postfix start

will ensure no anomalies in milter use while the milter is down.

--
        Viktor.


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Restarting milter application

Wietse Venema
In reply to this post by Purushotham Nayak
Purushotham Nayak:
> Thanks so much for the information! Also, tempfail does work correctly. But
> couple of questions though,
>
> 1. When default action is tempfail and the milter is unavailable, smtpd
> sends 451 (Requested action aborted: error in processing). Wonder if there
> is a way to send 421 (Service not available, closing transmission channel)

Following the SMTP protocol rules, Postfix does not close connections
unless it has to.

> and then close the connection. 451 works fine except that some of the
> clients keeps retrying for several minutes before giving up and creating a
> new connection. If we have a config option to send 421 and close the
> connection it might help it be faster.

If developer cycles were unlimited, we could make Postfix 100x as
complex just to handle all possible client badness. But, we don't
have an unlimited budget.

> 2. I noticed that when the milter application exits, it sends FIN to smtpd

That is incorrect. Milters don't send FIN, and Postfix does not
receive FIN. Such signals are sent between the TCP layers of the
network stack.

The Milter protocol as defined is a half-duplex protocol, meaning
that each party waits for its turn to speak. A 'spontaneous'
disconnect by one party won't be detected until the other tries to
send or receive something.

This might be different if there Milters and Postfix were sending
packets at each other, but that is not how they work.

        Wietse
Loading...