Zimbra Antispam &Antivirus机制分析

原创 2018年04月16日 15:51:05

Zimbra的投递逻辑是:

Postfix smtpd ->Postfix queue -> amavisd(内容过滤) -> Postfixsmtpd -> Postfix queue -> deliver

其中,amavisd是一个perl写的内容过滤系统,以smtp协议接收postfix的请求,然后调用SpamAssassin引擎以及clamav杀毒引擎进行处理。

amavisd处理之后如果发现是垃圾邮件或者病毒,有几个可能的处理方式:

a) 直接丢弃或者放到隔离区,这样就不用再经过一次Postfix了

b) 告诉前端的Postfix queue邮件需要拒收,由前端的Postfix负责退信

c) 通过SMTP协议重新把邮件放回Postfix队列

这个存在的问题是:

1. 前端没有控制机制,假如压力测试的时候以垃圾邮件为样本进行测试,然后把信头的From设置成一个连接不上的域名,就可以使得Postfix堆积大量的退信;

2. amavisd是调用SpamAssassin作为反垃圾引擎的,其处理能力比较慢,在测试机尝试用一个线程通过smtp协议直接绕开Postfix前端发信到amavisd,处理速度是每分钟6封左右;

 (处理的时候整个系统基本都在swap, 4G的物理内存都用光了, 4个Java进程,每个进程占用500M内存。另外有5个amavisd进程,每个占用150M内存)。

3. 分析过amavisd进程,其大概处理过程如下:

5288 1261636569.403345accept() # 接收一个连接

5288 1261636570.712165read(9, "MAIL FROM:<pqf@aaaaa.com>\r\n", 4096) = 27

1.   从socket读取邮件内容,并保存到/opt/zimbra/data/amavisd/tmp/amavis-20091221T172325-05288/目录下,这个目录包含一个parts目录,parts保存的是分解后的bodypart

2.   现在开始连接clamav杀毒, 杀毒还是很快的,半秒就返回结果了

5288 1261636572.371280 connect(12,

sa_family=AF_INET, sin_port=htons(3310),sin_addr=inet_addr("127.0.0.1")

, 16) = 0

5288 1261636572.371380 sendto(12, "CONTSCAN/opt/zimbra/data/amavis"..., 73, 0, NULL, 0) = 73

5288 1261636572.798982 recvfrom(12,"", 8192, 0,

sa_family=AF_INET, sin_port=htons(38000),sin_addr=inet_addr("127.0.0.1")
, 0)

= 0

3.   现在是SpamAssassin的RBL, URLBL检查

5288 1261636573.504577 bind(12,

sa_family=AF_INET, sin_port=htons(44663),sin_addr=inet_addr("0.0.0.0")
, 16) = 0
5288 1261636573.504625 connect(12,
sa_family=AF_INET, sin_port=htons(53),sin_addr=inet_addr("192.168.170.13"), 16) = 0
5288 1261636573.504699 getsockopt(12, SOL_SOCKET, SO_RCVBUF, 223338434560,4)= 0
5288 1261636573.557825 getpeername(12, sa_family=AF_INET, sin_port=htons(53),sin_addr=inet_addr("192.168.170.13")
, [226060277865
51312]) = 0

4.   现在开始做Bayes检查

5288 1261636573.977665open("/opt/zimbra/data/amavisd/.spamassassin/bayes_toks", O_RDONLY) =13

5.   做一点优化,Bayes检查过的记录下来,下次遇到同样内容的无需再次Bayes

5288 1261636573.990256open("/opt/zimbra/data/amavisd/.spamassassin/bayes_seen", O_RDONLY) =14

6.   现在开始连接Postfix后端的smtpd(10025端口)

5288 1261636576.386879 connect(12,
sa_family=AF_INET, sin_port=htons(10025),sin_addr=inet_addr("127.0.0.1")
, 16) = 0
5288 1261636576.414884 select(16, 12,[], 12,
35, 0) = 1 (in 12,left 35, 0
)
5288 1261636576.415113 read(12, "220 zmbtest.mailtech.cn ESMTPPo"..., 16384) = 39

7.   一次处理结束
5288 1261636577.432211 flock(8, LOCK_EX <unfinished ...>
5288 1261636577.673285 <... flock resumed> ) = 0
5288 1261636577.673408 select(8, 57, NULL, NULL, NULL <unfinished ...>

可以看出, amavisd处理邮件一共花费了8秒(邮件20k左右,是一封html邮件),主要花时间在接收邮件之后分拆并保存到临时文件,以及Bayes检查这两部分。当然,这个测试有点极端的是测试的时候内存严重不足,swap的情况非常严重(但是系统已经有4G物理内存了,java进程是吃内存的大头)

Coremail的处理机制明显比Zimbra的优越

首先,Coremail在前端已经在客户段尝试投递邮件的时候,已经实时的检查了邮件,如果认为邮件是垃圾邮件的,立即就reject,而不是像Zimbra那样先进入队列。

其次,对于垃圾邮件,如果size小于100K的,Coremail甚至不会涉及IO操作就可以直接reject邮件(>100K的邮件将会使用队列文件临时保存,如果拒收的最后会删除邮件)。Zimbra是任何邮件都需要先进入队列的, 需要起码四五次IO(一次进入队列,几个分解邮件保存每个part一个文件的操作, 以及若干SpamAssassin做Bayes需要的IO读写操作, 然后还有一次退信涉及的几个IO)

就算是正常邮件,Coremail需要把邮件接收下来了,IO操作也远小于Zimbra. Coremail只需要写一次队列文件,然后由da负责投递,da投递的时候,如果需要杀毒的,会由da负责分拆邮件,每个附件保存成一个小文件,查毒后删除。而Zimbra, 则首先需要由Postfix的smtpd进程接收邮件并写一次队列文件,然后由qmgr进程把队列文件mv到qmgr目录,再把文件通过网络传给amavisd,amavisd在处理的时候会把邮件分成几个part, 每个part创建一个小文件,然后查毒。查毒完毕之后Zimbra会调用SpamAssassin进行Antispam检查,检查通过的,会再连接Postfix,把邮件放回队列,而这会导致一次额外的创建队列文件操作。也就是,正常情况下,Zimbra会比Coremail多了一次创建文件操作以及起码两次的mv文件操作。

除了IO之外,Zimbra的瓶颈还在于cpu的使用以及内存使用,因为使用了SpamAssassin, 这个perl开发的软件效率特别地下,另外amavisd也是用perl来分拆邮件body然后做antivirus检查的,strace分析发现这两个部分的耗时特别高。而内存使用高主要是因为有几个java进程,不过具体为什么java要这么多内存,就要William协助分析一下了

后来Tanyi在调研Zimbra的时候找到网上有人说过mailscanner + postfix的效率比amavisd + postfix的效率要高,到mailscanner的网站(http://www.mailscanner.info/cobalt.html)查看了一下,发现原理上确实如此。

mailscanner的原理是利用postfix的header_check机制,配置postfix, 把所有进入队列的邮件,先mv到hold目录, 然后由mailscanner直接扫描hold目录,通过的邮件再放回incoming, 不通过的邮件则reject。
这个机制确实省了一点IO(使用amavisd的话,通过检查的需要再发回队列,多了一次创建队列文件),但是按照之前的分析,整个过滤系统的瓶颈不在postfix本身,也不在amavisd,而是在amavisd所调用的SpamAssassin。而mailscanner本身也只是框架,没有Antispam能力,最终还是要依赖SpamAssassin进行antispam过滤
所以就算Zimbra使用了mailscanner, 效率也不会提高多少。另外,为了节省这些不是关键的IO,需要使用非标准的postfix接口(mailscanner会以postfix协议直接处理postfix的队列文件,postfix修改了文件结构的话,mailscanner需要跟着修改),导致维护成本的增高,也是得不偿失


Antispam,反垃圾,反作弊[转载]

Antispam,反垃圾,反作弊[原创]http://FullSearch.Com 中文全文检索网 2006-2-5 15:59:10 sigz ...
  • metago
  • metago
  • 2006-04-19 21:49:00
  • 1441

搜索引擎antispam系统设计指南[转]

搜索引擎antispam系统设计指南[转] http://FullSearch.Com 中文全文检索网 2006-5-31 14:15:51 张俊林 关键词:antispam 搜索引antispam系...
  • zhanghefu
  • zhanghefu
  • 2007-04-23 13:05:00
  • 1611

Zimbra 安装 SSL 证书

Zimbra是一家提供专业的电子邮件软件开发供应商,主要提供Zimbra Collaboration Server协作服务器套件、Zimbra Desktop邮件管理软件等邮件方面的软件,不过最近由于...
  • wanglei_storage
  • wanglei_storage
  • 2016-06-23 12:10:55
  • 1366

zimbra 邮件服务器是设置黑名单

最近公司邮件服务器 zimbra 老是收到一些奇奇怪怪的邮件,所以需要对一些特殊的邮件地址进行设置。如果在amavisd.conf.in中,对某个邮箱加分。会碰到很特殊的情况,其他权限弄的分很高。导致...
  • wanglei_storage
  • wanglei_storage
  • 2016-05-04 11:50:41
  • 1080

zimbra修改默认7071管理端口的方法

修改管理端口: 以修改端口7071为8888为例 1.      zmprov命令修改zimbraAdminPort端口 [root @mail ~]$su - zimbra [zimbra@...
  • ocean20
  • ocean20
  • 2012-04-25 15:46:13
  • 5027

Windows下Zimbra字体设置(字体小的问题)

新装了个邮件客户端Zimbra,想找个开源的,可以跨平台的,就选这个了。     装完就遇到个问题,默认的中文字体太小了,看上去都变形了。在网上找了找解决办法,多数是Linux的,有个win的 把...
  • shiy118
  • shiy118
  • 2012-11-09 09:11:17
  • 2620

Zimbra邮件服务器的安装与配置

1.      下载Zimbra 官网地址:http://www.zimbra.com/downloads 下载说明: a)      版本: zimbra有两个大版本:Open Source...
  • zzban
  • zzban
  • 2013-03-06 09:12:36
  • 28899

基于Zimbra搭建的邮箱服务器

好长时间没有搭建了 ,昨天重新搭建了一下 ,觉得很有必要记载一下 。           Zimbra提供一套开源协同办公套件包括WebMail,日历,通信录,Web文档管理和创作。它最大的特色在于其...
  • wang8329300
  • wang8329300
  • 2016-04-02 10:04:42
  • 442

Zimbra mta 报错解决方法

登陆 https://192.168.10.18:7071  提示报错解决方法 登陆zimbra用户 su zimbra 报错服务状态 zmcontrol status Host hanzh...
  • hanzheng260561728
  • hanzheng260561728
  • 2016-05-07 22:16:50
  • 2396

Zimbra 8.5GA垃圾邮件过滤设置的5种方法

http://itgeeker.net/zimbra-8-5-5-ways-setup-spam-email-filter/ 1.提高特定域名权值 zimbra垃圾邮件过滤的第一不,可以通...
  • u012460952
  • u012460952
  • 2015-09-10 13:45:23
  • 3070
收藏助手
不良信息举报
您举报文章:Zimbra Antispam &Antivirus机制分析
举报原因:
原因补充:

(最多只允许输入30个字)