From: Stoiko Ivanov Date: Thu, 14 Nov 2019 16:35:07 +0000 (+0100) Subject: add support for before queue filtering X-Git-Url: https://git.proxmox.com/?p=pmg-api.git;a=commitdiff_plain;h=e0cbdf9fc98178f97223922f305cc19d6d29262d;hp=88a5150331354c0b80cd6340a83c40a26aff4226 add support for before queue filtering Support for rejecting mails during the SMTP-dialog with 550 (permanent failure) instead of seemingly accepting the mail (250 OK) and dropping it if it is rejected by the rule-system is also known as 'before queue filtering' [0]. This patch adds minimal support for before queue filtering to pmg-smtp-filter. Since pmg-smtp-filter is currently called via LMTP (and the 'scan' service in 'master.cf') we can adapt the already existing branch dealing with SMTP to send a 550 selectively. We can reply with 554 (permfail) if all recepients are blocked. In the case that some accept the mail, we reply with 250 OK. Depending on the setting of 'ndr_on_block' we generate ndrs for all blocking recepients. (This is also the behavior that postfix has when not enabling receiver verification and the downstream server rejects recepients). Configuration of before-queue filtering is done via the 'before_queue_filtering' boolean in the 'mail' section of 'pmg.conf': the before_queue_filtering flag is used when rendering '/etc/postfix/master.cf' to adapt the needed config-options for both, inbound and outbound, smtpd servers. The settings were adapted from [0]. [0] http://www.postfix.org/SMTPD_PROXY_README.html Signed-off-by: Stoiko Ivanov --- diff --git a/src/PMG/Config.pm b/src/PMG/Config.pm index e1a9cd4..ed4a665 100755 --- a/src/PMG/Config.pm +++ b/src/PMG/Config.pm @@ -627,6 +627,11 @@ sub properties { minimum => 0, default => 1 }, + before_queue_filtering => { + description => "Enable before queue filtering by pmg-smtp-filter", + type => 'boolean', + default => 0 + }, ndr_on_block => { description => "Send out NDR when mail gets blocked", type => 'boolean', @@ -666,6 +671,7 @@ sub options { verifyreceivers => { optional => 1 }, dnsbl_sites => { optional => 1 }, dnsbl_threshold => { optional => 1 }, + before_queue_filtering => { optional => 1 }, ndr_on_block => { optional => 1 }, }; } diff --git a/src/PMG/SMTP.pm b/src/PMG/SMTP.pm index 00a448e..544d0a5 100644 --- a/src/PMG/SMTP.pm +++ b/src/PMG/SMTP.pm @@ -154,16 +154,21 @@ sub loop { } } } else { - my $all_done = 1; - - foreach $a (@{$self->{to}}) { - if (!($self->{queue}->{status}->{$a} eq 'delivered' || - $self->{queue}->{status}->{$a} eq 'blocked')) { - $all_done = 0; + my $queueid = $self->{queue}->{logid}; + my $qstat = $self->{queue}->{status}; + my @rec = keys %$qstat; + my @success_rec = grep { $qstat->{$_} eq 'delivered' } @rec; + my @reject_rec = grep { $qstat->{$_} eq 'blocked' } @rec; + + if (scalar(@reject_rec) == scalar(@rec)) { + $self->reply ("554 5.7.1 Rejected for policy reasons"); + syslog('info', "reject mail $queueid"); + } elsif ((scalar(@reject_rec) + scalar(@success_rec)) == scalar(@rec)) { + $self->reply ("250 2.5.0 OK ($queueid)"); + if ($cfg->get('mail', 'ndr_on_block')) { + my $dnsinfo = $cfg->get_host_dns_info(); + generate_ndr($self->{from}, [ @reject_rec ], $dnsinfo->{fqdn}, $queueid) if scalar(@reject_rec); } - } - if ($all_done) { - $self->reply ("250 2.5.0 OK ($self->{queue}->{logid})"); } else { $self->reply ("451 4.4.0 detected undelivered mail"); } diff --git a/src/templates/master.cf.in b/src/templates/master.cf.in index cbf4677..b7761ea 100644 --- a/src/templates/master.cf.in +++ b/src/templates/master.cf.in @@ -72,13 +72,21 @@ # (yes) (yes) (yes) (never) (100) # ========================================================================== +[% IF ! pmg.mail.before_queue_filtering -%] scan unix - - n - [% pmg.mail.max_filters %] lmtp -o lmtp_send_xforward_command=yes -o lmtp_connection_cache_on_demand=no -o disable_dns_lookups=yes +[% END -%] [% pmg.mail.int_port %] inet n - - - [% pmg.mail.max_smtpd_out %] smtpd +[% IF pmg.mail.before_queue_filtering -%] + -o smtpd_proxy_filter=127.0.0.1:10023 + -o smtpd_proxy_options=speed_adjust + -o smtpd_client_connection_count_limit=[% pmg.mail.conn_count_limit div 5 %] +[%- ELSE -%] -o content_filter=scan:127.0.0.1:10023 +[%- END %] -o smtpd_recipient_restrictions=permit_mynetworks,reject_unauth_destination -o smtpd_helo_restrictions= -o smtpd_client_restrictions= @@ -87,7 +95,13 @@ scan unix - - n - [% pmg.mail.max_filters %] [% pmg.mail.ext_port %] inet n - - - 1 postscreen smtpd pass - - - - [% pmg.mail.max_smtpd_in %] smtpd +[% IF pmg.mail.before_queue_filtering -%] + -o smtpd_proxy_filter=127.0.0.1:10024 + -o smtpd_proxy_options=speed_adjust + -o smtpd_client_connection_count_limit=[% pmg.mail.conn_count_limit div 5 %] +[%- ELSE -%] -o content_filter=scan:127.0.0.1:10024 +[%- END %] -o receive_override_options=no_address_mappings -o smtpd_discard_ehlo_keywords=silent-discard,dsn -o mynetworks=127.0.0.0/8,[% postfix.int_ip %]