best practice anti virus integration & custom reject messages

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

best practice anti virus integration & custom reject messages

Stefan Bauer-2
Hi,

I like the clean and easy milter way and having clamd this way integrated in postfix. But i can not use custom reject message in case clamd detects virus.

postfix/cleanup[4292]: BD6BA80ACA: milter-reject: END-OF-MESSAGE from (...): 5.7.1 Command rejected; from=<me> to=<recipient> proto=ESMTP helo=<my internal mailserver>

This message lacks basic information - virus detected.

smtp_delivery_status_filters seems to not work in this case. Right?

Pulling in amavis as well might give option to have custom reject messages, but i do not like to have an additonal service in the chain.

Any other option available?
Reply | Threaded
Open this post in threaded view
|

Re: best practice anti virus integration & custom reject messages

Wietse Venema
Stefan Bauer:

> Hi,
>
> I like the clean and easy milter way and having clamd this way integrated
> in postfix. But i can not use custom reject message in case clamd detects
> virus.
>
> postfix/cleanup[4292]: BD6BA80ACA: milter-reject: END-OF-MESSAGE from
> (...): 5.7.1 Command rejected; from=<me> to=<recipient> proto=ESMTP
> helo=<my internal mailserver>
>
> This message lacks basic information - virus detected.

That is because the Milter did not provide that a reason in the
response to Postfix. The milter could be changed to provide a reason:
see discussion below.

>  smtp_delivery_status_filters seems to not work in this case. Right?

As documented that is applicable for SENDING, not RECEIVING email.

> Pulling in amavis as well might give option to have custom reject
> messages, but i do not like to have an additonal service in the
> chain.

Postfix has no 'milter reply filter' feature and it is unlikely to
happen.

To solve this problem you'd pass the Milter response through another
program, or you would use a virus detector that produces more
informative responses.

The Milter replies with code SMFIR_REJECT, which supports no
indication why mail is rejected:

  * SMFIR_REJECT
    In response to a RCPT command, indicates that the recipient
    should be rejected with a permanent error. In any other context
    this indicates that the entire message should be rejected with
    a permanent error and that no further milter commands or responses
    will be exchanged.

The Milter could be improved by sending SMFIR_REPLYCODE instead,
which allows the Milter to provide the complete SMTP server response
to Postfix, including SMTP code and text.
 
  * SMFIR_REPLYCODE
    In response to a RCPT command, indicates that the recipient
    should be rejected with the specified error. In any other context
    this indicates that the entire message should be rejected with
    the specified error and that no further milter commands or
    responses will be exchanged.

Below is the code that handles the Milter response.

        Wietse

        case SMFIR_REJECT:
            if (data_size != 0)
                break;
            if (IN_CONNECT_EVENT(event)) {
#ifdef LIBMILTER_AUTO_DISCONNECT
                milter8_close_stream(milter);
#endif
                milter->state = MILTER8_STAT_REJECT_CON;
                MILTER8_EVENT_BREAK(milter8_def_reply(milter, "550 5.7.1 Command rejected"));
            } else {
              MILTER8_EVENT_BREAK("550 5.7.1 Command rejected");
            }

Reply | Threaded
Open this post in threaded view
|

Re: best practice anti virus integration & custom reject messages

Stefan Bauer-2
Thank you! I was too stupid to RTFM. Clamd can provide custom reject messages.

Am Mo., 17. Sep. 2018 um 16:18 Uhr schrieb Wietse Venema <[hidden email]>:
Stefan Bauer:
> Hi,
>
> I like the clean and easy milter way and having clamd this way integrated
> in postfix. But i can not use custom reject message in case clamd detects
> virus.
>
> postfix/cleanup[4292]: BD6BA80ACA: milter-reject: END-OF-MESSAGE from
> (...): 5.7.1 Command rejected; from=<me> to=<recipient> proto=ESMTP
> helo=<my internal mailserver>
>
> This message lacks basic information - virus detected.

That is because the Milter did not provide that a reason in the
response to Postfix. The milter could be changed to provide a reason:
see discussion below.

>  smtp_delivery_status_filters seems to not work in this case. Right?

As documented that is applicable for SENDING, not RECEIVING email.

> Pulling in amavis as well might give option to have custom reject
> messages, but i do not like to have an additonal service in the
> chain.

Postfix has no 'milter reply filter' feature and it is unlikely to
happen.

To solve this problem you'd pass the Milter response through another
program, or you would use a virus detector that produces more
informative responses.

The Milter replies with code SMFIR_REJECT, which supports no
indication why mail is rejected:

  * SMFIR_REJECT
    In response to a RCPT command, indicates that the recipient
    should be rejected with a permanent error. In any other context
    this indicates that the entire message should be rejected with
    a permanent error and that no further milter commands or responses
    will be exchanged.

The Milter could be improved by sending SMFIR_REPLYCODE instead,
which allows the Milter to provide the complete SMTP server response
to Postfix, including SMTP code and text.

  * SMFIR_REPLYCODE
    In response to a RCPT command, indicates that the recipient
    should be rejected with the specified error. In any other context
    this indicates that the entire message should be rejected with
    the specified error and that no further milter commands or
    responses will be exchanged.

Below is the code that handles the Milter response.

        Wietse

        case SMFIR_REJECT:
            if (data_size != 0)
                break;
            if (IN_CONNECT_EVENT(event)) {
#ifdef LIBMILTER_AUTO_DISCONNECT
                milter8_close_stream(milter);
#endif
                milter->state = MILTER8_STAT_REJECT_CON;
                MILTER8_EVENT_BREAK(milter8_def_reply(milter, "550 5.7.1 Command rejected"));
            } else {
                MILTER8_EVENT_BREAK("550 5.7.1 Command rejected");
            }