Top

反病毒及反垃圾邮件

大多数解决方案是采用一个中间件(amavis-new)调用杀毒软件(ClamAV)检查邮件病毒,以及调用垃圾邮件检测软件(SpamAssassin)判断邮件是否为垃圾邮件。
注意,这个仅仅检查病毒,检测到病毒后会将邮件放在统一的一个邮箱里。并不会采取杀毒动作。

主要参考:
Amavisd, Spamassassin and clamav
amavisd doc:Chapter 1. Integrating amavisd-new in Postfix

clamav

首先安装杀毒软件:
pkg install clamav
在/etc/rc.conf中添加以下三句:
clamav_clamd_enable="YES"
clamav_freshclam_enable="YES"
clamav_milter_enable="YES"
启动以上服务,freshclam会自动更新病毒库。

spamssassin

然后安装扫描垃圾软件: 安装spamassassin后需要先运行一次sa-update(jail内可能会提示gpg:警告:正在使用不安全的内存。忽略即可),然后将spamd_enable="YES"追加到/etc/rc.conf。
需要注意的是,启动它需要执行service sa-spamd start命令。

另外一个需要注意的:
某次做pkg upgrade时,更新了spamssassin,sa-spamd服务无法启动,提示:
child process [1660] exited or timed out without signaling production of a PID file: exit 255 at /usr/local/bin/spamd line 3034.
同时,下面的amavisd服务也无法启动。
解决方法是执行以下命令:
sa-update
推测可能是spamassassin更新时将规则冲掉了,需要重新建立规则。

amavis-new

最后安装中间件: 安装amavisd-new,并在/etc/rc.conf中追加amavisd_enalbe="YES"。 如果主机名不是FQDN(fully-qualified domain name),则服务启动失败。修改/usr/local/etc/amavisd.conf文件,插入一行:
$myhostname = 'mail.local';
此处仅为测试,后面还要进行改动
注意,保存退出时会被提示“只读文件,未写入;用!强制写入.”的提示。
以上全部安装并启动后,使用sockstat -4l命令可以看到比原来多出一些端口:
root@mail:/usr/local/etc/rc.d # sockstat -4l
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
vscan    perl       20468 6  tcp4   192.168.0.111:10024   *:*
vscan    perl       20467 6  tcp4   192.168.0.111:10024   *:*
vscan    perl       20466 6  tcp4   192.168.0.111:10024   *:*
dovenull imap-login 20245 7  tcp4   192.168.0.111:143     *:*
dovenull imap-login 20245 8  tcp4   192.168.0.111:993     *:*
dovenull imap-login 19995 7  tcp4   192.168.0.111:143     *:*
dovenull imap-login 19995 8  tcp4   192.168.0.111:993     *:*
spamd    perl       19952 5  tcp4   192.168.0.111:783     *:*
spamd    perl       19951 5  tcp4   192.168.0.111:783     *:*
root     perl       19950 5  tcp4   192.168.0.111:783     *:*
dovenull imap-login 18207 7  tcp4   192.168.0.111:143     *:*
dovenull imap-login 18207 8  tcp4   192.168.0.111:993     *:*
dovenull imap-login 18190 7  tcp4   192.168.0.111:143     *:*
dovenull imap-login 18190 8  tcp4   192.168.0.111:993     *:*
dovenull imap-login 18188 7  tcp4   192.168.0.111:143     *:*
dovenull imap-login 18188 8  tcp4   192.168.0.111:993     *:*
root     master     18135 13 tcp4   192.168.0.111:25      *:*
root     master     18135 17 tcp4   192.168.0.111:587     *:*
root     master     18135 20 tcp4   192.168.0.111:465     *:*
root     dovecot    18056 22 tcp4   192.168.0.111:110     *:*
root     dovecot    18056 23 tcp4   192.168.0.111:995     *:*
root     dovecot    18056 38 tcp4   192.168.0.111:143     *:*
root     dovecot    18056 39 tcp4   192.168.0.111:993     *:*
root     syslogd    18010 5  udp4   192.168.0.111:514     *:*
其中: 783端口是SpamAssassin开的; 10024端口是amavis开的。

将postfix与amavis集成

修改/usr/local/etc/amavisd.conf确定有如下行:
# @bypass_virus_checks_maps = (1);  # controls running of anti-virus code
# @bypass_spam_checks_maps  = (1);  # controls running of anti-spam code
# $bypass_decode_parts = 1;         # controls running of decoders&dearchivers
$daemon_user  = 'vscan';     # (no default;  customary: vscan or amavis), -u
$daemon_group = 'vscan';     # (no default;  customary: vscan or amavis), -g
$mydomain = 'example.com';   # a convenient default for other settings (此处需要根据实际情况修改)
$MYHOME = '/var/amavis';   # a convenient default for other settings, -H (去掉前面的井号)
@local_domains_maps = ( [".$mydomain","myotherdomain.net"] );  # list of all local domains(可以有多个域名,域名用双引号括起来,域名之间用逗号分隔)
$myhostname = 'host.example.com';  # must be a fully-qualified domain name! (去掉前面的井号,并根据实际情况修改)
配置文件里面引出两个邮箱:virusalert\@mydomain(用于接收并病毒邮件)、spam.police\@mydomain(用于处理垃圾邮件),需要为它们创建虚拟账号。

再修改/usr/local/etc/amavisd.conf,将以下行取消注释:
['ClamAV-clamd',
  \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.sock"],
  qr/\bOK$/m, qr/\bFOUND$/m,
  qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],

修改/etc/group,将clamav加入到vscan组:
vscan:*:110:clamav
有文章提到需要修改/usr/local/etc/clamd.conf,在末尾加入如下行:
AllowSupplementaryGroups yes
实际测试中在FreeBSD系统中不需要这样做,似乎官方已经放弃了这个做法。
但是在Debian中还是需要追加
AllowSupplementaryGroups true
否则在日志中会提示类似以下错误:
Jul  6 09:58:36 mail amavis[5998]: (05998-04) (!)run_av (ClamAV-clamd) FAILED - unexpected , output="/var/lib/amavis/tmp/amavis-20220706T095836-05998-se3vTMfM/parts: File path check failure: Permission denied. ERROR\n/var/lib/amavis/tmp/amavis-20220706T095836-05998-se3vTMfM/parts: File path check failure: Permission denied. ERROR\n"
Jul  6 09:58:36 mail amavis[5998]: (05998-04) (!)ClamAV-clamd av-scanner FAILED: CODE(0x558470cff4d0) unexpected , output="/var/lib/amavis/tmp/amavis-20220706T095836-05998-se3vTMfM/parts: File path check failure: Permission denied. ERROR\n/var/lib/amavis/tmp/amavis-20220706T095836-05998-se3vTMfM/parts: File path check failure: Permission denied. ERROR\n" at (eval 96) line 951.
Jul  6 09:58:36 mail amavis[5998]: (05998-04) (!)WARN: all primary virus scanners failed, considering backups
Jul  6 09:58:36 mail amavis[5997]: (05997-05) (!)run_av (ClamAV-clamd) FAILED - unexpected , output="/var/lib/amavis/tmp/amavis-20220706T095430-05997-AbMAysm7/parts: File path check failure: Permission denied. ERROR\n/var/lib/amavis/tmp/amavis-20220706T095430-05997-AbMAysm7/parts: File path check failure: Permission denied. ERROR\n"
Jul  6 09:58:36 mail amavis[5997]: (05997-05) (!)ClamAV-clamd av-scanner FAILED: CODE(0x558470cff4d0) unexpected , output="/var/lib/amavis/tmp/amavis-20220706T095430-05997-AbMAysm7/parts: File path check failure: Permission denied. ERROR\n/var/lib/amavis/tmp/amavis-20220706T095430-05997-AbMAysm7/parts: File path check failure: Permission denied. ERROR\n" at (eval 96) line 951.
Jul  6 09:58:36 mail amavis[5997]: (05997-05) (!)WARN: all primary virus scanners failed, considering backups
Jul  6 09:59:33 mail amavis[5997]: (05997-05) (!!)TROUBLE in check_mail: quar+notif FAILED: Can't create dir /var/vmail/virusmails/A: Permission denied at (eval 95) line 149.
Jul  6 09:59:33 mail amavis[5997]: (05997-05) (!)PRESERVING EVIDENCE in /var/lib/amavis/tmp/amavis-20220706T095430-05997-AbMAysm7
Jul  6 09:59:33 mail amavis[5997]: (05997-06) (!)connect to /var/run/clamav/clamd.ctl failed, attempt #1: Can't connect to a UNIX socket /var/run/clamav/clamd.ctl: Connection refused


修改/usr/local/etc/postfix/master.cf,加入以下行:
# Amavisd
smtp-amavis unix - - n - 2 smtp
		  -o syslog_name=/postfix/amavis
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes
        -o disable_dns_lookups=yes
        -o max_use=20
        -o smtp_tls_security_level=none
127.0.0.1:10025 inet n - n - - smtpd
        -o syslog_name=postfix/10025
        -o content_filter=
        -o smtpd_delay_reject=no
        -o smtpd_client_restrictions=permit_mynetworks,reject
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o smtpd_data_restrictions=reject_unauth_pipelining
        -o smtpd_end_of_data_restrictions=
        -o smtpd_restriction_classes=
        -o mynetworks_style=subnet
        -o smtpd_error_sleep_time=0
        -o smtpd_soft_error_limit=1001
        -o smtpd_hard_error_limit=1000
        -o smtpd_client_connection_count_limit=0
        -o smtpd_client_connection_rate_limit=0
        -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters,no_address_mappings
        -o local_header_rewrite_clients=
        -o smtpd_milters=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o strict_rfc821_envelopes=yes
        -o smtp_tls_security_level=none
        -o smtpd_tls_security_level=none
修改/usr/local/etc/postfix/main.cf,加入以下行:
content_filter = amavisfeed:[127.0.0.1]:10024

做完以上设置后,重启各相关服务,然后进行测试。
测试代码:
关于jail的一个疑惑:
同时搭建了两个基于FreeBSD的邮件系统,其中一个是在host上做的,另一个是在jail中做的(不在同一台实体机)。 host上的一切正常,jail里面的在启动amavisd服务时未收到错误记录。
查看amavisd服务已经起来了,10024端口也开放了,但是telnet上去马上被远程主机断开。然后/var/log/maillog中出现一条记录:
amavis[46321]: (!)DENIED ACCESS from IP 192.168.0.111, policy bank ''
上网搜找到一篇文章说要在/usr/local/etc/amavisd.conf中加入ACL:
@inet_acl = qw(192.168.0.111 127.0.0.1 [::1]);
然后重启amavisd服务即可。
但在另一台host上却没有出现类似情况,所以怀疑这是jail的问题。
另外,如果要检查邮件附带的压缩文件,需要安装一些解压缩软件。
启动amavisd服务时会在/var/log/maillog中有提示:
Jun 22 10:16:57 mail amavis[3567]: No $altermime,         not using it
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .F, tried: unfreeze, freeze -d, melt, fcat
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .lrz, tried: lrzip -q -k -d -o -, lrzcat -q -k
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .cab, tried: cabextract
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .tnef, tried: tnef
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .zip, tried: 7za, 7zz, 7z
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .kmz, tried: 7za, 7zz, 7z
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .7z, tried: 7zr, 7za, 7zz, 7z
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .jar, tried: 7zz, 7z
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .swf, tried: 7zz, 7z
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .lha, tried: 7zz, 7z
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .iso, tried: 7zz, 7z
Jun 22 10:16:57 mail amavis[3567]: No ext program for   .cab, tried: 7zz, 7z
Jun 22 10:16:57 mail amavis[3567]: No decoder for       .7z
Jun 22 10:16:57 mail amavis[3567]: No decoder for       .F
Jun 22 10:16:57 mail amavis[3567]: No decoder for       .cab
Jun 22 10:16:57 mail amavis[3567]: No decoder for       .iso
Jun 22 10:16:57 mail amavis[3567]: No decoder for       .jar
Jun 22 10:16:57 mail amavis[3567]: No decoder for       .lha
Jun 22 10:16:57 mail amavis[3567]: No decoder for       .lrz
Jun 22 10:16:57 mail amavis[3567]: No decoder for       .swf
需要安装以下几个包:
p7zip
lrzip
cabextract(解压Microsoft .cab包(Cabinet))
tnef(解压MS Outlook TNEF格式)
但是.F的尚且不知用哪个工具解压,上面提到的freeze、melt、fcat在FreeBSD均找不到对应的软件。