为了过滤垃圾邮件,我们已经使用了实时黑名单(RBL)和灰名单(postgrey)。现在我们将增加自适应垃圾邮件过滤来让我们的垃圾邮件过滤能力提高一个等级。这意味着我们将为我们的邮件服务器增加人工智能,这样它就能从经验中学习哪些邮件是垃圾哪些不是。我们将使用来实现这个功能。
- apt-get install dspam dovecot-antispam postfix-pcre dovecot-sieve
dovecot-antispam是一个安装包,可以在我们发现有邮件被dspam误分类了之后让dovecot重新更新垃圾邮件过滤器。基本上,我们所需要做的就只是把邮件放进或拿出垃圾箱。dovecot-antispam将负责调用dspam来更新过滤器。至于postfix-pcre和dovecot-sieve,我们将分别用它们来把接收的邮件传递给垃圾邮件过滤器以及自动把垃圾邮件放入用户的垃圾箱。
在配置文件/etc/dspam/dspam.conf里,为以下参数设置相应的值:
- TrustedDeliveryAgent"/usr/sbin/sendmail"
- UntrustedDeliveryAgent"/usr/lib/dovecot/deliver -d %u"
- Tokenizer osb
- IgnoreHeader X-Spam-Status
- IgnoreHeader X-Spam-Scanned
- IgnoreHeader X-Virus-Scanner-Result
- IgnoreHeader X-Virus-Scanned
- IgnoreHeader X-DKIM
- IgnoreHeader DKIM-Signature
- IgnoreHeaderDomainKey-Signature
- IgnoreHeader X-Google-Dkim-Signature
- ParseToHeaders on
- ChangeModeOnParse off
- ChangeUserOnParse full
- ServerPID/var/run/dspam/dspam.pid
- ServerDomainSocketPath"/var/run/dspam/dspam.sock"
- ClientHost/var/run/dspam/dspam.sock
然后,在配置文件/etc/dspam/default.prefs里,把以下参数改为:
- spamAction=deliver # { quarantine | tag | deliver } -> default:quarantine
- signatureLocation=headers # { message | headers } -> default:message
- showFactors=on
现在我们需要把dspam连接到postfix和dovecot上,在配置文件/etc/postfix/master.cf最后添加这样两行:
- dspam unix - n n -10 pipe
- flags=Ru user=dspam argv=/usr/bin/dspam --deliver=innocent,spam --user $recipient -i-f $sender -- $recipient
- dovecot unix - n n -- pipe
- flags=DRhu user=mail:mail argv=/usr/lib/dovecot/deliver -f ${sender}-d ${recipient}
现在我们将告诉postfix通过dspam来过滤所有提交给服务器端口25(一般的SMTP通信)的新邮件,除非该邮件是从服务器本身发出(permit_mynetworks)。注意下我们通过SASL鉴权提交给postfix的邮件不会通过dspam过滤,因为我们在前面部分里为这种方式设定了独立的提交服务。编辑文件/etc/postfix/main.cf将选项**smtpd_client_restrictions**改为如下内容:
- smtpd_client_restrictions = permit_mynetworks, reject_rbl_client zen.spamhaus.org, check_policy_service inet:127.0.0.1:10023, check_client_access pcre:/etc/postfix/dspam_filter_access
在文件末尾,还需要增加:
- # For DSPAM, only scan one mail at a time
- dspam_destination_recipient_limit =1
现在我们需要指定我们定义的过滤器。基本上,我们将告诉postfix把所有邮件(如下用 /./ 代表)通过unix套接字发给dspam。创建一个新文件/etc/postfix/dspam_filter_access并把下面一行写进去:
- /./ FILTER dspam:unix:/run/dspam/dspam.sock
这是postfix部分的配置。现在让我们为dovecot设置垃圾过滤。在文件/etc/dovecot/conf.d/20-imap.conf里,修改imap mail_plugin插件参数为下面的方式:
- mail_plugins = $mail_plugins antispam
并为lmtp增加一个部分:
- protocol lmtp {
- # Space separated list of plugins to load (default is global mail_plugins).
- mail_plugins = $mail_plugins sieve
- }
我们现在设置dovecot-antispam插件。编辑文件/etc/dovecot/conf.d/90-plugin.conf并把以下内容添加到插件部分:
- plugin {
- ...
- # Antispam (DSPAM)
- antispam_backend = dspam
- antispam_allow_append_to_spam = YES
- antispam_spam =Junk;Spam
- antispam_trash =Trash;trash
- antispam_signature = X-DSPAM-Signature
- antispam_signature_missing = error
- antispam_dspam_binary =/usr/bin/dspam
- antispam_dspam_args =--user;%u;--deliver=;--source=error
- antispam_dspam_spam =--class=spam
- antispam_dspam_notspam =--class=innocent
- antispam_dspam_result_header = X-DSPAM-Result
- }
然后在文件/etc/dovecot/conf.d/90-sieve.conf里指定默认的sieve脚本,这个将对服务器上所有用户有效:
- sieve_default =/etc/dovecot/default.sieve
什么是sieve以及为什么我们需要为所有用户设置一个默认脚本?sieve可以在IMAP服务器上为我们自动处理任务。在我们的例子里,我们想让所有被确定为垃圾的邮件移到垃圾箱而不是收件箱里。我们希望这是服务器上所有用户的默认行为;这是为什么我们把这个脚本设为默认脚本。现在让我们来创建这个脚本,建立一个新文件/etc/dovecot/default.sieve并写入以下内容:
- require["regex","fileinto","imap4flags"];
- # Catch mail tagged as Spam, except Spam retrained and delivered to the mailbox
- if allof (header :regex "X-DSPAM-Result""^(Spam|Virus|Bl[ao]cklisted)$",
- not header :contains "X-DSPAM-Reclassified""Innocent"){
- # Mark as read
- # setflag "\\Seen";
- # Move into the Junk folder
- fileinto "Junk";
- # Stop processing here
- stop;
- }
现在我们需要编译这个脚本好让dovecot能运行它。我们也需要给它合适的权限。
- cd /etc/dovecot
- sievec .
- chown mail.dovecot default.siev*
- chmod 0640default.sieve
- chmod 0750default.svbin
最后,我们需要修改dspam需要读取的两个postfix配置文件的权限:
- chmod 0644/etc/postfix/dynamicmaps.cf /etc/postfix/main.cf
就这些!让我们重启dovecot和postfix服务:
- service dovecot restart
- service postfix restart
测试
然后通过从远程主机(比如我们用来设定服务器的电脑)连接服务器来测试一下反垃圾邮件:
- openssl s_client -connect cloud.linuxidc.net:25-starttls smtp
- EHLO cloud.linuxidc.net
- MAIL FROM:youremail@domain.com
- rcpt to:roudy@linuxidc.net
- DATA
- Subject: DSPAM test
- HiRoudy, how'd you like to eat some ham tonight? Yours, J
- .
- QUIT
让我们检查一下邮件是否已经送到:
- openssl s_client -crlf -connect cloud.linuxidc.net:993
- 1 login roudy@linuxidc.net "mypassword"
- 2 LIST """*"
- 3 SELECT INBOX
- 4 UID fetch 3:3(UID RFC822.SIZE FLAGS BODY.PEEK[])
这个应该返回SPAM为邮件增加了一组标记的数据,看上去像这样:
- X-DSPAM-Result:Innocent
- X-DSPAM-Processed:SunOct516:25:482014
- X-DSPAM-Confidence:1.0000
- X-DSPAM-Probability:0.0023
- X-DSPAM-Signature:5431710c178911166011737
- X-DSPAM-Factors:27,
- Received*Postfix+with,0.40000,
- Received*with+#+id,0.40000,
- like+#+#+#+ham,0.40000,
- some+#+tonight,0.40000,
- Received*certificate+requested,0.40000,
- Received*client+certificate,0.40000,
- Received*for+roudy,0.40000,
- Received*Sun+#+#+#+16,0.40000,
- Received*Sun+#+Oct,0.40000,
- Received*roudy+#+#+#+Oct,0.40000,
- eat+some,0.40000,
- Received*5+#+#+16,0.40000,
- Received*cloud.linuxidc.net+#+#+#+id,0.40000,
- Roudy+#+#+#+to,0.40000,
- Received*Oct+#+16,0.40000,
- to+#+#+ham,0.40000,
- Received*No+#+#+requested,0.40000,
- Received*linuxidc.net+#+#+Oct,0.40000,
- Received*256+256,0.40000,
- like+#+#+some,0.40000,
- Received*ESMTPS+id,0.40000,
- how'd+#+#+to, 0.40000,
- tonight+Yours, 0.40000,
- Received*with+cipher, 0.40000
- 5 LOGOUT
很好!你现在已经为你服务器上的用户配置好自适应垃圾邮件过滤。当然,每个用户将需要在开始的几周里培训过滤器。要标记一则信息为垃圾,只需要在你的任意设备(电脑,平板,手机)上将它移动到叫“垃圾箱”或“废纸篓”的目录里。否则它将被标记为有用。