[pmg-devel] applied: [PATCH pmg-api v2 2/2] add support for before queue filtering

Dietmar Maurer dietmar at proxmox.com
Fri Nov 15 09:01:12 CET 2019


applied
> On 14 November 2019 17:35 Stoiko Ivanov <s.ivanov at proxmox.com> wrote:
> 
>  
> 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 <s.ivanov at proxmox.com>
> ---
>  src/PMG/Config.pm          |  6 ++++++
>  src/PMG/SMTP.pm            | 23 ++++++++++++++---------
>  src/templates/master.cf.in | 14 ++++++++++++++
>  3 files changed, 34 insertions(+), 9 deletions(-)
> 
> 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 %]
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> pmg-devel mailing list
> pmg-devel at pve.proxmox.com
> https://pve.proxmox.com/cgi-bin/mailman/listinfo/pmg-devel



More information about the pmg-devel mailing list