[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