偏执企鹅 - 为你的 Postfix 服务器添加 Clam Antivirus
Linux Journal 2004 年度编辑选择奖安全工具的得主是 ClamAV,一个 100% 免费和开源的病毒扫描器,它运行在 Linux 上,但扫描的病毒影响多种平台(参见 Linux Journal,2004 年 8 月刊)。正如 Reuven Lerner 在颁奖文章中指出的那样,“ClamAV 正在给商业病毒检查程序带来真正的竞争压力。”
在本月的专栏中,我将向您展示如何在您的 Postfix 电子邮件网关上利用 ClamAV 的强大功能。在此过程中,您还将学习一些关于 Amavisd-new 的知识,这是一个强大的电子邮件处理守护进程,它充当电子邮件服务器(如 Postfix 和 Sendmail)与邮件扫描工具(如 ClamAV 和 SpamAssassin)之间的关键管道。
我即将描述的场景绝不是使用 ClamAV 的唯一好方法。但这确实是我个人最常遇到的场景;它当然是典型的。假设我们有一个 SMTP 网关,它接收所有发往我们组织的 Internet 电子邮件,并且我们希望配置该 SMTP 网关来预先过滤邮件中的病毒(图 1)。我们可以将网关配置为将邮件传递到本地邮箱,或者它可以将所有内容中继到内部邮件服务器。以下所有内容的工作方式相同,与传递方法无关。

图 1. 我们的示例电子邮件架构
在高容量设置中,我们可以在独立的扫描服务器上而不是本地 SMTP 网关上完成所有病毒扫描;这里描述的所有工具都可以在这种方式下良好地工作。但为了简单起见,并且因为它是一种常见的做法,我们将直接在 SMTP 网关上运行病毒扫描器。
我们将使用 Postfix 作为我们的邮件传输代理 (MTA),因为它很流行、安全且可以与 ClamAV 很好地协同工作。但是 Postfix 无法直接与 ClamAV 交互,至少不是可靠地交互。ClamAV 在解析实际的电子邮件消息方面还不太擅长,而不是数据流。因此,我们需要引入一个名为 Amavisd-new 的辅助守护进程。
Amavisd-new 是另一个免费和开源的工具,它在生命中的唯一目的是在 MTA(如 Postfix 和 Sendmail)与防病毒和反垃圾邮件实用程序(如 ClamAV 和 SpamAssassin)之间充当事务代理。 除此之外,Amavisd-new 擅长将 MIME 电子邮件附件转换为扫描器可以理解的传统数据文件。
Amavisd-new 的守护进程 amavisd 可以通过多种协议进行通信,包括 SMTP 和 LMTP 电子邮件协议,以及 UNIX 套接字。在这里,我们将 amavisd 配置为通过 TCP 端口 10024 上的 SMTP 侦听电子邮件,通过使用 ClamAV 的本地 UNIX 套接字与 ClamAV 通信,并通过 TCP 端口 10025 将电子邮件和扫描结果发送回 Postfix。图 2 说明了电子邮件如何流经我们的 SMTP 网关。
ClamAV 和 Amavisd-new 都是用 Perl 编写的,并且依赖于许多 Perl 模块。因此,我建议您查找并使用您的发行版的这两个工具的最新版本的二进制包。当尝试手动安装所有内容时,您应该更容易让 apt-get、Yum 或 up2date 自动处理出现的依赖关系。
ClamAV 网站除了是最新 ClamAV 源代码的所在地之外,还有一个页面列出了各种 Linux 发行版和其他操作系统的 ClamAV 二进制包的来源。对于 Red Hat 和 Fedora 用户,Dag Wieers 的页面(请参阅在线资源)提供了包含 ClamAV 和 Amavisd-new 的 Yum 存储库和 up2date 源。Amavisd-new 网站有指向 Amavisd-new 包的其他来源的链接,以及最新的 Amavisd-new 源代码。ClamAV 现在是 Debian 上从 sarge 版本开始的标准软件包,Amavisd-new 是 SuSE 9.1 的一部分。
如果您从源代码或独立软件包安装任何一个软件包,而不是使用 Yum、up2date 或 apt-get,请务必查看 Amavisd-new 的 INSTALL 说明的“先决条件”部分(请参阅资源)。ClamAV 的先决条件没有那么详细的文档记录。如有疑问,尝试一下rpm --test -iv clamav_packagename.rpm在您的 ClamAV RPM 上,看看您的系统缺少哪些必需的软件包,这没有坏处。
您的发行版很可能为 ClamAV 和 Amavisd-new 所需的各种 Perl 模块提供了软件包。任何未提供的都可以从 CPAN 或其他专门为您的发行版打包软件的第三方站点获得。
一旦您安装了 ClamAV 和 Amavisd-new,您就可以配置它们了。我们从 ClamAV 开始,它是两者中更简单的一个。ClamAV 的配置文件是 /etc/clamav.conf。要配置 ClamAV,请使用您选择的文本编辑器打开此文件。清单 1 显示了大多数人需要从默认值更改的参数。
清单 1. /etc/clamav.conf 中的非默认设置
# Example LogFile /var/log/clamd.log LogFileMaxSize 5M DatabaseDirectory /usr/share/clamav LocalSocket /usr/share/clamav/clamd.sock User clamav
第一行看起来很普通,但您必须将其注释掉。如果不注释掉,clamd 将无法运行。
两个 LogFile... 设置默认情况下被注释掉。取消注释它们以启用日志记录到您选择的文件,并在文件达到 LogFileMaxSize 中指定的大小时覆盖该文件。
DatabaseDirectory 至关重要。这是 ClamAV 保存其病毒签名数据库的地方——可以说是它的大脑。在我安装的 ClamAV RPM 中,clamd 守护进程被编译为使用 /usr/share/clamav 进行此设置,但包含的示例 clamav.conf 文件显示了注释掉的值 /var/lib/clamav,所以我取消注释此设置并将其更改为 /usr/share/clamav 以最大限度地减少混淆。
LocalSocket 确定 clamd 使用哪个套接字文件与外部世界(即 Amavisd-new)通信。如果您使用此设置(我建议您使用),请务必注释掉 TCPSocket 和 TCPAddr 的行。在我的 Genco 包中,LocalSocket 的此路径的默认值为 /tmp/clamd,但 /tmp 是世界可读/可写的。我建议您将此路径设置为 /usr/share/clamav/clamd.sock,并将 /usr/share/clamav 的权限设置为 rwxrwx。换句话说,删除其他用户的读/写/执行位。
清单 1 中的最后一个设置 User 指定了非特权用户帐户的名称,clamd 应该在初始化后以该帐户运行。clamd 必须以 root 身份启动,但如果此参数未注释且已设置,则 clamd 在完成初始化后会降级自身。
这就是我们大多数人在 /etc/clamav.conf 中需要设置的全部内容。但是在启动 clamd 之前,请确保您的系统具有 clamav 的帐户,并且您在 /etc/clamav.conf 中设置的任何路径的权限都已相应设置。为该帐户使用一个组 clamav 也是一个好主意。正如我们在下一节中看到的那样,这使得在 clamd 和 amavisd 之间共享某些资源变得更容易。
/etc/passwd 中 clamav 用户帐户的条目是
clamav:x:52:52:ClamAV Daemon:/:/bin/false
并且,/etc/group 中 clamav 组帐户的条目是
clamav:x:52:
一旦配置了 clamd,您只需输入命令即可启动它clamd。如果您从二进制包安装了 ClamAV,则您的系统可能在 /etc/init.d 中有一个 clamd 的 init 脚本。如果是这样,请务必启用它,以便 clamd 在启动时启动。否则,您需要创建并启用您自己的启动脚本。
与 clamd 一样,我们只需要编辑一个文件 /etc/amavisd.conf 即可配置 amavisd。但是,我们在这里还有更多工作要做。清单 2 显示了我的 /etc/amavisd.conf 文件中最重要的设置。
清单 2. /etc/amavisd.conf 中的重要设置
$daemon_user = 'amavis'; $daemon_group = 'clamav'; $mydomain = 'wiremonkeys.org'; $MYHOME = '/var/amavis'; $QUARANTINEDIR = '/var/virusmails'; $db_home = "$MYHOME/db"; $helpers_home = "$MYHOME/var"; $pid_file = "$MYHOME/var/amavisd.pid"; $lock_file = "$MYHOME/var/amavisd.lock"; $log_level = 2; $virus_admin = "mick\@$mydomain"; $mailfrom_notify_admin = "antivirus\@$mydomain"; $mailfrom_notify_spamadmin = "antivirus\@$mydomain"; ### http://www.clamav.net/ ['ClamAV-clamd', \&ask_daemon, ["CONTSCAN {}\n", "/usr/share/clamav/clamd.sock"], qr/\bOK$/, qr/\bFOUND$/, qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
清单 2 中的前两个设置 $daemon_user 和 $daemon_group 分别指定了 amavisd 应以哪个用户和组身份运行,分别为 amavis 和 clamav。正如我之前提到的,我喜欢为 amavisd 和 clamd 的所有文件使用一个公共组,因此让 amavisd 也以该组身份运行是有意义的。我的 amavis 帐户的 /etc/passwd 条目如下所示
amavis:x:53:52:Amavisd-new Daemon:/var/amavis:/bin/false
$mydomain 指定您组织的域名。$MYHOME 应设置为与您的 amavis 帐户的主目录相同的路径,它指定了 Amavisd-new 文件的根路径,通常为 /var/amavis。此目录应由 root 拥有且仅可由 root 写入。$QUARANTINEDIR 是您希望 amavisd 转储隔离的电子邮件消息的目录路径。此目录应由您的 amavis 用户帐户拥有且仅可由其写入。
$db_home,您可能需要取消注释它,它指定了 amavisd 应该将其数据库(例如包括缓存的扫描结果)保存在哪里。$helpers_home 指定了您希望 amavisd 保留其 SpamAssassin 设置和其他杂项的目录。$helpers_home 默认情况下可能会被注释掉。$db_home 和 $helpers_home 指定的目录应由您的 amavis 用户帐户拥有且仅可由其写入。
$pid_file 和 $lock_file 也可能被注释掉,可用于指定 amavisd 分别写入其 pidfile 和 lockfile 的位置。
$log_level 指定 amavisd 的日志消息应该有多详细,以 0 到 5 之间的数字表示,其中 5 最详细。默认值为 0,但我发现 2 是一个更有用的设置,但它不会使我的日志文件混乱。默认情况下,amavisd 将其日志消息发送到本地 syslog 系统下的邮件设施。换句话说,您的 amavisd 日志消息应该出现在与您的 Postfix 消息写入的相同位置。
接下来的四个设置涉及当检测到病毒或垃圾邮件消息时 amavisd 发起的电子邮件。$virus_admin 是您希望将病毒通知发送到的电子邮件地址。这必须是一个有效的电子邮件地址;如果您在此处设置的值尚不是,请更新您的本地别名文件。实际上,这可能应该是您,系统管理员的电子邮件地址。
也可以配置 amavisd 以向每条消息的预期收件人或其发件人发送通知,但大多数人觉得这很烦人,尤其是因为垃圾邮件和病毒电子邮件的发件人地址几乎总是伪造的。不要这样做。
$mailfrom_notify_admin 和 $mailfrom_notify_spamadmin 分别指定了当 amavisd 发送病毒或垃圾邮件通知时要使用的发件人地址。
最后,我们来到了 amavisd.conf 的真正魔力:ClamAV 的防病毒扫描器定义。在我的默认 /etc/amavisd.conf 文件中,整个部分都被注释掉了,所以我首先必须删除每行开头的 #。您可能需要或可能不需要自己执行此操作。
但是,您确实需要检查此部分中的 clamd 套接字路径。在清单 2 中,我已将我的从默认的 /var/run/clamav/clamd 更改为 /usr/share/clamav/clamd.sock,这与我在 /etc/clamav.conf 中定义的路径相同。
一旦您编辑了 /etc/amavisd.conf 并相应地设置了 amavisd 目录的权限,您就可以通过输入命令来启动守护进程amavisd不带任何参数。与 clamd 一样,您需要启用甚至可能首先为 amavisd 创建一个启动脚本,以便它在启动时启动。我建议将其设置为 clamd 首先启动。这样,当 amavisd 启动时,clamd 的套接字已经就位。
此外,与 clamd 一样,您应该以 root 身份启动 amavisd。它会将自身降级为您在 amavisd.conf 中指定的用户和组。
我们的 ClamAV 和 Amavisd-new 守护进程已配置并正在运行。只剩下几个任务,配置 Postfix 进行内容过滤和更新 ClamAV 的病毒数据库。
重要提示:以下内容假定 Postfix 已经配置好并成功执行其正常的接收/转发职责。
首先,使用您选择的文本编辑器打开 /etc/postfix/master.cf,并将清单 3 中的行添加到文件底部,如果它们尚不存在。
清单 3. 要添加到 /etc/postfix/master.cf 的行
smtp-amavis unix - - y - 2 smtp -o smtp_data_done_timeout=1200 -o disable_dns_lookups=yes 127.0.0.1:10025 inet n - n - - smtpd -o content_filter= -o local_recipient_maps= -o smtpd_client_restrictions= -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks, ↪reject_unauth_destination -o mynetworks=127.0.0.0/8 -o strict_rfc821_envelopes=yes -o smtpd_error_sleep_time=0 -o smtpd_soft_error_limit=1001 -o smtpd_hard_error_limit=1000
smtp-amavis 部分定义了 Postfix 的出站通信,使用 SMTP 协议,与 amavisd 通信。它对应于您应该在 /etc/postfix/main.cf 中添加或编辑的以下行
content_filter = smtp-amavis:[127.0.0.1]:10024
此行告诉 Postfix 将所有传入的电子邮件发送到本地系统 127.0.0.1,TCP 端口 10024(amavisd 的默认 SMTP 侦听端口)上,使用我们在 master.cf 中定义的 smtp-amavis 接口。您可以通过编辑 /etc/amavisd.conf 中的 $inet_socket_port 参数来更改 amavisd 的侦听端口。
清单 3 中的第二部分定义了 Postfix 应该在其上接受 amavisd 返回的消息的入站接口。换句话说,Postfix 在本地环回 IP 127.0.0.1 上的 TCP 端口 10025 上侦听,这是 amavisd 默认发送通知和转发消息的地址和端口。您可以通过编辑 /etc/amavisd.conf 中的参数 $notify_method 和 $forward_method 分别更改 amavisd 的通知和转发地址和端口。编辑 master.cf 和 main.cf 后,您需要重新启动或重新加载 Postfix。
在我们继续之前,让我们测试一下系统。最简单的测试方法是给自己发送一封包含以下字符串的电子邮件消息,这不是真正的病毒,而是一个名为 Eicar 测试签名的测试字符串
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
如果一切正常,amavisd 会向您在 amavisd.conf 的 $virus_admin 参数中指定的帐户发送一封电子邮件,并且该消息应隔离在 amavisd.conf 的 $QUARANTINEDIR 参数中指定的目录中。
我强烈建议在执行此测试时跟踪您的邮件日志。输入tail -f /var/log/mail,Postfix 和 amavisd 将在那里记录他们的操作。根据我自己的经验,这是识别问题的最快方法,特别是如果您像前面描述的那样增加了 amavisd 的日志详细程度。
此外,请务必至少使用干净的电子邮件进行一次测试,以确保您没有削弱 Postfix 接收和传递未过滤邮件的能力。
只剩下一件事要做,但这很重要:更新 ClamAV 的病毒签名数据库,并创建一个 cron 作业以每天自动执行此操作。ClamAV 包含一个名为 freshclam 的实用程序用于此目的。
因为使用 freshclam 是整个工作中最简单的任务,并且因为我现在基本上没有空间了,所以我留给您去探索 freshclam(1) 和 freshclam.conf(5) 手册页。只需说在正常实践中,您使用命令形式freshclam -l /path/to/logfile,其中 /path/to/logfile 指定您希望 freshclam 将其日志写入的文件。
建议您每隔几个小时运行一次 freshclam。最简单的方法是通过 -d 和 -c 启动选项以守护进程模式运行 freshclam。有关更多信息,请参阅 freshclam(1) 手册页。
有了这些,您现在应该拥有一个启用 ClamAV 的 SMTP 网关,或者至少已经开始朝着这个方向前进。如果您遇到问题,在线资源包括其他 Postfix 加 Amavisd-new 教程。祝你好运!
Mick Bauer,CISSP,是 Linux Journal 的安全编辑,也是明尼苏达州明尼阿波利斯的 IS 安全顾问。他是 使用 Linux 构建安全服务器(O'Reilly & Associates,2002)的作者。