Postfix、Amavis 和外发邮件:如何通知发件人

Postfix、Amavis 和外发邮件:如何通知发件人

我遇到了垃圾邮件问题,来自受感染的电子邮件帐户从我的服务器发送垃圾邮件并进入黑名单。 因此,我遵循使用 amavis 设置 postfix 的指南:

一切似乎都运行良好,但我想阻止外发垃圾邮件/病毒邮件,而是通知发件人他的邮件已被拒绝(例如通过 MAILER-DAEMON)。有可能做到这一点吗?我只能弄清楚如何:

  • 完全拒绝邮件并且不通知发件人(这不是很好,不是吗?):
    Aug 25 12:05:35 ns207813 amavis[24728]: (24728-01) Blocked SPAM {NoBounceOpenRelay,Quarantined}, <[email protected]> -> <[email protected]>, quarantine: J/spam-Jfuzg0ScCmKf.gz, Message-ID: <[email protected]>, mail_id: Jfuzg0ScCmKf, Hits: 1004.054, size: 935, 2013 ms
  • 仍然发送邮件(但标记为“垃圾邮件”):
    Aug 25 12:19:10 ns207813 amavis[25182]: (25182-01) Passed SPAM {RelayedTaggedInbound,Quarantined}, [217.230.20.223]:65071 [217.230.20.223] <[email protected]> -> <[email protected]>, quarantine: i/spam-iy3rVCiRk8k2.gz, Queue-ID: 5B9D722AAA, Message-ID: <[email protected]>, mail_id: iy3rVCiRk8k2, Hits: 999.001, size: 2663, queued_as: DD67222ABE, 1379 ms

我当前的 amavis 设置是:

$sa_spam_subject_tag = '[SPAM] ';
$sa_tag_level_deflt  = undef;  # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 5; # add 'spam detected' headers at that level
$sa_kill_level_deflt = 20; # triggers spam evasive actions
$sa_dsn_cutoff_level = 10;   # spam level beyond which a DSN is not sent

$final_virus_destiny      = D_DISCARD;  # (data not lost, see virus quarantine)
$final_banned_destiny     = D_BOUNCE;   # D_REJECT when front-end MTA
$final_spam_destiny       = D_PASS;
$final_bad_header_destiny = D_PASS;     # False-positive prone (for spam)

如果可能的话,我还想将收到的病毒标记为病毒,而不是完全拒绝邮件(这样就不会丢失邮件)。

感谢您的帮助!

答案1

您想要做的是,使用您的服务器作为其 MSA(即其外发中继)的用户的邮件,使用不同的政策比从第三方收到的邮件要多(即当您的邮件服务器充当 MX 角色时)。幸运的是,amavis 为您提供了合适的工具:策略库。

让我们看看如何为您的用户定义策略:

$policy_bank{'PREQ-SUB'} = {
        originating => 1, # indicates client is ours, allows signing
        final_spam_destiny => D_DISCARD, # discard spam
        final_virus_destiny => D_DISCARD, # discard spam
        warnspamsender => 1, # send a warning 
        forward_method => 'smtp:127.0.0.1:10025', # you probably need to adjust this
        smtpd_discard_ehlo_keywords => ['8BITMIME'], # force mail conversion to Q/P
        smtpd_greeting_banner => '${helo-name} ${protocol} ${product} SUBMISSION service ready',
        spam_admin_maps  => ["postmaster\@example.net"],  # warn of spam from us
        virus_admin_maps => ["postmaster\@example.net"],  # warn of viruses from us
};

从这个策略库的命名,您已经可以猜到我正在将其作为预排队过滤器运行,如果通过提交 TCP 端口 587 传递邮件,则会触发该过滤器。为了使此配置正常工作,我告诉我的 Postfix MTA 将提交服务收到的邮件传递到端口 10028 上的本地主机(而当充当公共 MX 时,服务器会将邮件转发到端口 10024)。为了在 amavis 中激活两个端口并将 PREQ-SUB 策略绑定到端口 10028,我使用以下设置:

# policy bank definition
$inet_socket_port = [10024, 10028];  # listen on listed inet tcp ports
$interface_policy{'10028'} = 'PREQ-SUB'; # mail submitted using TLS on submission/smtps port

Postfix 对应的 master.cf 条目是:

submission inet n - - - - smtpd -o smtpd_tls_security_level=encrypt 
  -o tls_preempt_cipherlist=$submission_tls_preempt_cipherlist 
  -o smtpd_tls_protocols=$submission_smtpd_tls_protocols 
  -o smtpd_tls_ciphers=$submission_smtpd_tls_ciphers 
  -o smtpd_tls_exclude_ciphers=$submission_smtpd_tls_exclude_ciphers 
  -o smtpd_sasl_auth_enable=yes 
  -o smtpd_recipient_restrictions=$submission_smtpd_recipient_restrictions 
  -o milter_macro_daemon_name=ORIGINATING 
  -o smtpd_proxy_filter=127.0.0.1:10028 
  -o syslog_name=postfix-submission/smtpd
  -o receive_override_options=no_header_body_checks

请注意,这实际上不仅仅是向 amavis 发送邮件,例如设置密码列表等等(您会注意到 main.cf 变量引用)。

那么,如果您的用户没有在端口 587 上提交邮件,或者并非所有用户都这样做,您该怎么办?好吧,那么您将不得不放弃 100% 确定的领域。amavis 可以分析邮件的内容并根据邮件头的存在采取行动。如果您设置了以下邮件头,Postfix 会添加经过身份验证的用户的姓名:smtpd_sasl_authenticated_header = 是。然后你可以告诉 amavis 根据这个标头采取行动:

package Amavis::Custom;
use strict;
BEGIN {
        import Amavis::Conf qw(:platform :confvars c cr ca $myhostname);
        import Amavis::Util qw(do_log untaint safe_encode safe_decode);
        import Amavis::rfc2821_2822_Tools;
        import Amavis::Notify qw(build_mime_entity);
}
sub new {
        my($class,$conn,$msginfo) = @_;
        my($self) = bless {}, $class;
        my $auth_sender = 0;
        foreach my $line (@{$msginfo->{'orig_header'}}) {
                $line =~ s/\n    / /g;
                # WARNING: you need to improve this to AT LEAST also match
                # for your OWN mail servers name!
                $auth_sender = 1 if $line =~ m/^Authenticated sender/i;
        }
        if ($auth_sender) {
                do_log(2, sprintf("Load pre-queue submission policy bank"));
                Amavis::load_policy_bank('PREQ-SUBMISSION')
        }
        return $self;
}
1;  # insure a defined return

请不要忽略此代码中的警告:标头很容易被伪造,并且其他邮件服务器也可以插入“已验证的发件人”标头,因此最好匹配“your-mailserver.example.net.*已验证的发件人”之类的内容。

最后,关于您的一条评论:运行邮件服务器确实需要花费大量时间,并且需要您不断监控其是否被滥用。参与全球电子邮件系统时,没有“免于牢狱之灾”的卡!

相关内容