CNGNU Postfix邮件系统系列指南之一
Postfix
+ Cyrus-IMAP + Cyrus-SASL
+ MySQL + IMP
完全指南
作者:王兴宇 <wxy@cngnu.org>
版本:0.71
版权:GPL
发布日期:2003-02-04
目录
1. 概述
1.1. 目的
本文试图介绍如何在一个Linux平台上安装一套功能完整的邮件系统。这里我们以Postfix做SMTP服务器、Cyrus-IMAP做 POP3/IMAP4服务器、通过Cyrus-SASL对存储在MySQL数据库中的用户进行验证和授权,并且使用IMP来提供一个完善的WEBMAIL 界面。
这个邮件系统的设计目标是提供一个可扩充的、具备大多数功能的邮件系统。
本文的最新版本可以在这里找到:http://www.cngnu.org/technology/Postfix_I.html。如果希望使用Courier-IMAP替代了Cyrus-IMAP做IMAP/POP3服务器,可以参阅本文的姊妹篇http://www.cngnu.org/technology/Postfix_II.html。
有关本文所涉及的技术问题,请到http://www.anti-spam.org.cn/forums/的邮件技术版讨论,我会尽快回复的,请勿就技术问题给我发邮件。
本文的版权遵循GPL,可以在不删除版权信息和注明修改的情况下任意传播。
1.2. 更新历史
- 2002-05-21 第一次发布,版本0.20。
- 2002-08-13 修正一些错误,版本0.21。
- 2002-08-23 修正一些错误,版本0.22。
- 2002-09-12 在RedHat Linux Advance Server V2.1上进行了测试,修正了一些错误,版本0.30。
- 2002-12-12 修正了一些错误,添加了IMP部分的内容,版本0.31。
- 2003-01-30 修正了一些错误,添加了非明文密码部分的内容,版本0.32。
- 2003-02-05 修正了一些错误,版本0.33
- 2003-03-26 使用了SASL V2和Cyrus-IMAP 2,支持使用db4的新的Linux发行版,如RedHat 8.0和Mandrake 9.0,并以RedHat 8.0为示范平台。修正了一些错误,版本0.40。
- 2003-03-28 修正了一些错误,特别感谢bjchenxu,版本0.41。
- 2003-09-24 添加了虚拟域功能,修正了一些笔误,版本0.50。
- 2003-10-13 修正了虚拟域的错误,版本0.51。
- 2003-12-02 修正了部分错误,版本0.52。如果没有其它的输入错误问题,本文将不再更新。
- 2004-01-29 做了较大的改动,版本0.70。以AS3为示范平台。令人疯狂的是当我即将完成这次的修改时,居然因为DreamWeaver的一个脚本错误导致我一天一 夜的辛苦工作消失的干干净净。我哭~。本次的修改涉及SASL、MySQL和Cyrus-IMAP等各个部分,遵照最小修改的原则,凡是AS3中提供的部 件可用,我将不再重新编译,这可能对移植到其它平台或版本有较大的困难。
- 2004-02-04 修正了一些笔误。
1.3. TODO
- 增加邮件列表功能
- 增加SSL部分的内容
- 翻译:希望有能力的朋友可以翻译这篇文章为英文,这样国外的朋友也可以看到
1.4. 鸣谢
谢谢lesson.ward、Yunping Zhu、Temp、bjchenxu的指正。也感谢Chinaunix.net和anti-spam.org.cn的各位朋友的关注和建议。
参考文档:http://www.delouw.ch/linux/Postfix-Cyrus-Web-cyradm-HOWTO/html/index.html。在这篇文章撰写之初,参考过该文章,目前该文章也在不断更新,大家也可以看看。
2. 系统功能
系统逻辑结构:
+---------------------------------------------------+
| |
| 25/25 25/25 110/993 143/995 80/443 |
| Incoming Outgoing POP3 IMAP WEB-MAIL |
| /\ /\ /\ /\ /\ |
| || || || || || |
| \/ \/ \/ \/ \/ |
+-------------------+---------------+---------------+
| Postfix | | IMP |
| | +---------------+
| | Cyrus-IMAP |
| +-----------+-------------------------------+
| | Cyrus-SASL |
| +-------------------------------------------+
| | saslauthd |
| +-------------------------------------------+
| | PAM |
| +-------------------------------------------+
| | pam_mysql |
+-------+-------------------------------------------+
| MySQL |
+---------------------------------------------------+
整个系统对外的界面包括几个部分,用来发信的SMTP、用来收信的POP3和IMAP、以及一个WEB界面的邮件使用系统。这里没有提供WEB界面的管理工具,需要大家自行依据实际需要开发。如果需要商业应用,可以购买CEM产品(http://cngnu.net/products/cem/),其中包括了完善的管理界面和优化的邮件服务器环境。
MySQL作为系统中存储数据的核心,它存储了用户的信息。这个信息不但用于POP3/IMAP和SMTP AUTH的认证需要,而且也为Postfix提供了本地接收者的列表和转发功能。
认证流程比较繁琐。整个认证是通过Cyrus-SASL来做的,通过运行一个守护进程saslauthd来监听认证需求。saslauthd这里使用了pam认证方式通过pam_mysql插件对MySQL数据库进行查找。
系统支持虚拟域用户和非虚拟域邮箱。
为什么选择这些部件组成这套邮件系统呢?
选择Postfix作为MTA,是因为它是一个非常优秀的MTA服务器,它不但性能卓越,对sendmail的兼容性好,支持和多种其它软件的隅合,而且本身就带有很强的反垃圾邮件功能。
选择MySQL作为存储用户信息的部分,是因为一方面MySQL本身是一个轻量级的数据库,在处理少量数据时非常快速,而且通过关系型数据库可以更方便地管理用户信息和提供更多用户特性(如基本每用户的过滤控制),此外还消除了因为使用系统用户所带来的安全隐患。
选择Cyrus-SASL作为认证机制,是因为它是一个标准的认证层,多数软件都支持它的认证。
选择Cyrus-IMAP作为IMAP/POP3服务器,是因为它的IMAP/POP实现效率很高,要比Courier-IMAP的实现要高一些,虽然它因此而使用的Maildir/格式与标准的QMAIL定义的格式有所不同。
这个系统将来可能的改进有几个方面:一是使用更高版本的Cyrus-SASL,直接支持对MySQL的查询认证,避免了使用saslauthd =>pam=>pam_mysql这样罗嗦的环节;二是使用更高版本的Cyrus-IMAP,对虚拟域有更加直接的支持,不用像现在这样需要 做别名转发才能实现。
3. 系统基本前提
本文以Linux系统为目标平台,支持多数的Linux平台如RedHat 7.x/8.x/9.x/AS2.1/AS3、Mandrake 8.x/9.x等,理论上也会支持其他的Linux发行版,甚至其他的UNIX系统。
这里以RedHat Linux Advance Server Enterprise V 3.0 (以下简称AS3)为说明平台。我采用了最基本的AS3安装,只选择了“Web Server”、“Dns Name Server”、“MySQL Database Server”、“Development Tools”和“Kernel Development”等软件包组(“Core”和“Base”组是默认必选的软件包)。
除此外,还需要额外安装以下RPM:
1、php-mysql-4.3.2-8.ent.i386.rpm(在CD3)
4. 安装MySQL
4.1. 下载
AS3默认是只包含MySQL除了服务器程序外的部分的,所以需要从RPMFIND下载MySQL的源RPM重建(最好使用源码包,采用MySQL.com提供的RPM和BIN包都可能在其它使用mysql的部分编译时候出现错误)。
[root@mail root]# cd /usr/src [root@mail src]# wget ftp://rpmfind.net/linux/redhat/enterprise/3/en/os/i386/SRPMS/mysql-3.23.58-1.src.rpm |
4.2. 编译与安装
[root@mail src]# rpmbuild --rebuild mysql-3.23.58-1.src.rpm [root@mail src]# cd redhat/RPMS/i386 [root@mail i386]# rpm -ivh mysql-server-3.23.58-1.i386.rpm |
为提高MySQL的安全性,使之只监听在本地打环端口,修改/etc/my.cnf:
[root@mail i386]# cd [root@mail root]# vi /etc/my.cnf |
在[mysqld]小节里面添加:
bind-address=127.0.0.1 |
并设置其开机时候自动运行:
[root@mail root]# chkconfig --level 0123456 mysqld on |
4.3. 运行
启动命令如下:
[root@mail i386]# /etc/init.d/mysqld start |
4.4. 测试
启动MySQL后,首先检查日志/var/log/messages有无错误信息,然后检查进程,应该有如下进程存在:
[root@mail root]# pstree | grep mysqld |-safe_mysqld---mysqld |
接着检查端口,应该有如下端口打开:
[root@mail root]# netstat -an | grep LISTEN tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN |
4.5. 建立数据库
MySQL安装配置好以后,创建如下SQL脚本mail.sql:
CREATE DATABASE mail; GRANT ALL ON mail.* TO mail@localhost IDENTIFIED BY "secret"; FLUSH PRIVILEGES; USE mail; CREATE TABLE USER ( INSERT INTO USER (USERNAME,PASSWORD,FORWARD,DOMAIN,MAIL) VALUES ('trueuser','$1$pi.WVgBx$a3dUCzBnbY76jnZlqWQCQ/', 'trueuser','cngnu.org','trueuser@cngnu.org'), 'virtualuser~cngnu.org','cngnu.org','virtualuser@cngnu.org'); |
[root@mail root]# mysql < mail.sql |
在MySQL中创建邮件用户数据库,并添加两个测试邮箱:
- 非虚拟域邮箱“trueuser”,密码是“testpw”
- 虚拟域邮箱“virtualuser@cngnu.org”,密码是“testpw”
上面的mail数据库的USER表用来保存用户信息:
- USERNAME和PASSWORD字段就是用户名和MD5-Crypt密码。USERNAME不但作为认证的字段,而且是本地邮箱查找条件(见下面的Postfix的virtual.mysql)。这里采用了加密密码是为了更好的安全性。对于
- 非虚拟域邮箱:USERNAME字段是邮件的本地部分(“@”前面的部分)
- 虚拟域邮箱:USERNAME字段是邮件地址全称
- FORWARD字段默认是指向用户的“存储邮箱”名的(Cyrus-IMAP所管理的邮箱名称),即进行本地投递;如果FORWARD字段是另外一个用户名或者邮件地址,则该邮件被转发到别的用户或其它邮件地址。对于
- 非虚拟域邮箱:其存储邮箱与用户名相同
- 虚 拟域邮箱:为了支持多个域,考虑到不同的域可能拥有相同的用户名(本地部分),所以使用邮件全称作为用户的登录名(POP/IMAP的登录名和SMTP认 证的登录名),但是由于Cyrus-IMAP不直接支持虚拟域(虽然可以创建带“@”的邮箱,在Cyrus-IMAP的2.2.x版本支持虚拟域,但是目 前该版本还是测试版),不能在邮件的本地部分包含“@”,所以实际的存储邮箱名把“@”替换为“~”。(参见下面Cyrus-IMAP部分描述)
- DOMAIN字段用来快速找出某个域下存在的邮箱,仅为管理方便使用。
- MAIL字段是邮件地址 全称。对于非虚拟域邮箱,它包含了本地部分外的域部分;对于虚拟域邮箱,它和USERNAME字段一样。一方面是为了管理方便使用,同时该字段还用来做全 局过滤控制FILTER的查找条件(见FILTER字段及下面Postfix的filter.mysql)。
- FILTER字段用于控制该邮箱是否接受服务器的全局邮件过滤。该值设置为“OK”或为空表示对该邮箱不进行过滤;设置为“DUNNO”表示对该邮箱进行Postfix中定于的全局过滤。该值可以是任何合法的Postfix的access过滤规则。
- PARTITION字段用于指明邮箱存储的Cyrus-IMAP邮件分区。可以建立多个不同的邮件分区。仅为了管理方便使用。
- QUOTA字段指定邮箱的磁盘限额。仅为了管理方便使用。
- STATUS字段用来指示该用户是否有效,可以通过修改该值为0来临时禁止某个用户。
5. 安装pam_mysql
5.1. 下载
http://sourceforge.net/projects/pam-mysql/
[root@mail root]# cd /usr/src [root@mail src]# wget http://telia.dl.sourceforge.net/sourceforge/pam-mysql/pam_mysql-0.5.tar.gz |
注:如果不能访问该网站取得pam_mysql,请自行使用代理服务器访问。
5.2. 编译与安装
编译pam_mysql:
[root@mail src]# tar -zxf pam_mysql-0.5.tar.gz [root@mail src]# cd pam_mysql |
修改pam_mysql.c的源代码,去掉调试消息:
[root@mail pam_mysql]# vi +54 pam_mysql.c |
将如下一行:
#define DEBUG |
修改为:
/* #define DEBUG */ |
然后编译:
[root@mail pam_mysql]# make [root@mail pam_mysql]# cp pam_mysql.so /lib/security |
有些情况下,这个编译会报错,但是如果编译能生成pam_mysql.so模块,还是可以用的。
5.3. 配置
创建/etc/pam.d/mail,它用来支持Cyrus-IMAP的imap认证、pop认证和Postfix的smtp认证:
[root@mail pam_mysql]# cd /etc/pam.d [root@mail pam.d]# echo auth sufficient pam_mysql.so user=mail passwd=secret \ > host=localhost db=mail table=USER usercolumn=USERNAME passwdcolumn=PASSWORD \ > crypt=1 sqllog=0 > /etc/pam.d/mail [root@mail pam.d]# echo account required pam_mysql.so user=mail passwd=secret \ > host=localhost db=mail table=USER usercolumn=USERNAME passwdcolumn=PASSWORD \ > crypt=1 sqllog=0 >> /etc/pam.d/mail [root@mail pam.d]# echo auth sufficient pam_unix_auth.so >> /etc/pam.d/mail [root@mail pam.d]# echo account sufficient pam_unix_acct.so >> /etc/pam.d/mail |
这里前面两行是指通过mysql数据库来认证用户,后面两行指是通过UNIX的基本方式认证用户(即系统用户)。这里我们之所以保留UNIX系 统认证模式,是因为我们下面要通过系统用户cyrus来管理cyrus-imap邮箱。不过你也可以选择将这个管理帐号cyrus放入mysql认证数据 库里面,只需要你在上面的数据库里面添加一个cyrus用户。
通过给上面的crypt赋予不同的值可以使用多种密码存储方式:
- crypt=0:表示使用明文来存储密码。这样存储的好处是简单,但是不够安全。
- crypt=1:表 示使用UNIX系统的DES加密密码方式来存储。即通常的UNIX的/etc/passwd(老式系统加密口令存储在这里)或/etc/shadow(较 为新的系统加密口令存放在这里)中存储的加密口令。加密口令有两种,一种是普通的des加密的,也叫crypt(),这种密码是13位长,前面两个字符是 加密种子;还有一种是使用了MD5算法增强了的,也叫MD5 crypt(),这种密码的加密种子是以$1$开头的12个字符,密码长度不定。
- crypt=2:表示使用mysql的SQL函数password()加密方式来存储。
- crypt=3:表示使用md5的散列方式来存储。这种方式和MD5 crypt()是不一样的。
一般如果从系统用户迁移到使用数据库的虚拟用户时,可以使用crypt=1方式,系统会自动辨别两种加密口令。如果需要开发用户修改口令的功能时,C和Perl里面的crypt函数不能支持MD5 crypt()口令,需要使用额外的编程或模块来支持。
做个符号链接/etc/pam.d/imap,它用来支持Cyrus-IMAP的imap认证:
[root@mail pam.d]# [ -f imap ] && mv imap imap.orig [root@mail pam.d]# ln -s mail imap |
同样创建/etc/pam.d/pop ,它用来支持Cyrus-IMAP的pop3认证:
[root@mail pam.d]# [ -f pop ] && mv pop pop.orig [root@mail pam.d]# ln -s mail pop |
同样创建/etc/pam.d/smtp ,它用来支持Postfix的smtp auth认证:
[root@mail pam.d]# [ -f smtp ] && mv smtp smtp.orig [root@mail pam.d]# ln -s mail smtp |
系统上可能已经存在了这些文件,将原来的改名备份或删除即可。
6. 配置Cyrus-SASL
6.1. 配置
AS3默认安装的Cyrus-SASL可以满足这套邮件系统的需要,一般不必重新编译。
设置Postfix使用SASL的saslauthd认证守护进程来支持smtp auth认证,并只打开了plain和login认证模块:
[root@mail pam.d]# cd [root@mail root]# echo pwcheck_method: saslauthd > /usr/lib/sasl2/smtpd.conf [root@mail root]# echo mech_list: plain login >> /usr/lib/sasl2/smtpd.conf |
Cyrus-IMAP的SASL配置不使用标准的sasl语法,它的配置文件放在/etc/imapd.conf中,详细配置在Cyrus-IMAP部分说明。
配置saslauthd使用PAM认证方案:
[root@mail root]# vi /etc/sysconfig/saslauthd |
内容如下:
MECH=pam |
修改/etc/sysconfig/saslauthd并将saslauthd设置为自动运行
[root@mail root]# chkconfig --level 0123456 saslauthd on |
6.2. 运行
运行saslauthd守护进程,并使其使用pam认证模式来提供认证信息:
[root@mail root]# /etc/rc.d/init.d/saslauthd start |
整个系统使用的认证机制比较复杂。所有的应用(SMTP、IMAP、POP3等)都采用SASL2的saslauthd来认证;而 saslauthd是通过它所支持的PAM模式来借助pam_mysql接口对存储在MySQL数据库中用户信息进行认证的。请参阅上面的系统结构以了解 认证流程。
7. 安装Postfix
7.1. 下载
http://www.postfix.org/ftp-sites.html
[root@mail root]# cd /usr/src [root@mail src]# wget http://postfix.energybeam.com/source/official/postfix-2.0.16.tar.gz |
7.2. 编译与安装
如果你的系统上原来有sendmail,先将其停止并将其文件改名:
[root@mail src]# /etc/init.d/sendmail stop [root@mail src]# chkconfig --level 0123456 sendmail
off [root@mail src]# mv /usr/bin/mailq /usr/bin/mailq.orig [root@mail src]# mv /usr/sbin/sendmail /usr/sbin/sendmail.orig |
然后添加两个组:postfix和maildrop和一个用户:postfix
[root@mail src]# groupadd -g 400 postfix [root@mail src]# groupadd -g 401 postdrop [root@mail src]# useradd -u 400 -g 400 -c postfix -M -d/no/where -s/no/shell postfix |
这里的组和用户的ID是系统中未使用的ID。
编译Postfix,并支持mysql和sasl:
[root@mail src]# tar -xvzf postfix-2.0.16.tar.gz [root@mail src]# cd postfix-2.0.16 [root@mail postfix-2.0.16]# make -f Makefile.init makefiles \ > 'CCARGS=-DUSE_SASL_AUTH -DHAS_MYSQL -I/usr/include/mysql -I/usr/include/sasl' \ > 'AUXLIBS=-L/usr/lib/mysql -L/usr/lib/sasl2 -lmysqlclient -lsasl2 -lz -lm' [root@mail postfix-2.0.16]# make install |
安装时,安装程序会提问一些问题,可以直接按回车采用默认值。
这里切记要指定正确的SASL2的INCLUDE和LIB位置。由于现在很多linux发行版上都已经带有了sasl,如果不指定的话,很可能会使用了不同版本的头文件和库,在这种情况下,每次连接SMTP时,smtpd就会发生致命错误“Fatal: SASL per-connection server init...”而崩溃。
给postfix用户做一个系统别名,并将超级用户的邮箱转发到一个普通用户。使用/etc/postfix/aliases别名数据库:
[root@mail postfix-2.0.16]# cd /etc/postfix [root@mail postfix]# echo 'root: virtualuser@cngnu.org' >> /etc/postfix/aliases |
生成/etc/postfix/aliases别名数据库:
[root@mail postfix]# postalias /etc/postfix/aliases |
生成/etc/postfix/virtual的DB库:
[root@mail postfix]# postmap virtual |
保留db格式的virtual库是为了系统临时增加转发方便起见。
7.3. 配置
修改/etc/postfix/master.cf中的关于cyrus的配置,(cyrus的命令行和以前有不兼容的地方,确保你的cyrus的参数如下使用了-r ${sender}参数):
[root@mail postfix]# vi master.cf |
将如下两行:
cyrus unix - n n - - pipe user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} |
修改为:
cyrus unix - n n - - pipe user=cyrus argv=/usr/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} |
这里要把cyrus的路径修改为你的cyrus实际安装路径(我们下面会将cyrus-imap安装到/usr/cyrus)。 记着user=...这行前面是以空格缩进的(是上一行的续行)。
[root@mail postfix]# vi main.cf |
修改/etc/postfix/main.cf的配置:
myhostname = mail.cngnu.org mydomain = cngnu.org myorigin = $mydomain mydestination = $mydomain,$myhostname mynetworks_style = host
alias_maps = hash:/etc/postfix/aliases alias_database = hash:/etc/postfix/aliases home_mailbox = Maildir/ mailbox_transport = cyrus fallback_transport = cyrus virtual_maps = hash:/etc/postfix/virtual,mysql:/etc/postfix/virtual.mysql smtpd_sasl_auth_enable = yes broken_sasl_auth_clients = yes smtpd_sasl_security_options = noanonymous smtpd_recipient_restrictions = |
如果希望支持更多的虚拟域,可以在mydestination参数后面加上你所要支持的域即可。
通过virtual和virtual.mysql为系统提供了邮箱本地查询表。
使用了SASL来进行SMTP发信认证。
通过smtpd_recipient_restrictions提供了基本的反垃圾邮件功能。首先允许本地网络(这里是本机)和通过SASL认 证的用户可以使用本服务器发信;然后检查每个用户的全局邮件过滤功能是否打开,如果关闭则不进行后面的反垃圾邮件检查;其后是一些Postfix支持的基 本反垃圾邮件功能。
创建/etc/postfix/virtual.mysql,它提供了本地用户和邮件转发功能。FORWARD字段默认是指向用户的存储邮箱名 的(Cyrus-IMAP所管理的邮箱名称),即进行本地投递;如果FORWARD字段是另外一个用户名或者邮件地址,则该邮件被转发到别的用户或其它邮 件地址。对于
- 非虚拟域邮箱:其存储邮箱与用户名相同
- 虚拟域邮箱:为了支持多个域,考虑到不同的域可能拥有相同的用 户名(本地部分),所以使用邮件全称作为用户的登录名(POP/IMAP的登录名和SMTP认证的登录名),但是由于Cyrus-IMAP不直接支持虚拟 域,不能在邮件的本地部分包含“@”,所以实际的存储邮箱名把“@”替换为“~”。
[root@mail postfix]# vi virtual.mysql |
# # mysql config file for alias lookups on postfix # # the user name and password to log into the mysql server hosts = localhost user = mail password = secret # the database name on the servers dbname = mail # the table name table = USER select_field = FORWARD where_field = USERNAME additional_conditions = and STATUS = 1 limit 1 |
[root@mail postfix]# vi filter.mysql |
# # mysql config file for filter flag on postfix # # the user name and password to log into the mysql server hosts = localhost user = mail password = secret # the database name on the servers dbname = mail # the table name table = USER select_field = FILTER # OK : ignore filter # DUNNO : filter where_field = MAIL additional_conditions = and STATUS = 1 limit 1 |
7.4. 运行
启动命令如下:
[root@mail postfix]# /usr/sbin/postfix start |
7.5. 测试Postfix
启动Postfix后,首先检查日志/var/log/messages有无错误信息,然后检查进程,应该有如下进程存在:检查端口及进程:
[root@mail postfix]# pstree |grep master |-master-+-pickup |
接着检查端口,应该有如下端口打开:
[root@mail postfix]# netstat -an |grep LISTEN tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN |
再检测SMTP服务是否正常:
[root@mail postfix]# telnet localhost 25 Trying 127.0.0.1... |
使用如下命令测试postfix的SMTP的认证(这里仅测试了“virtualuser@cngnu.org”,“trueuser”请自行测试):
PLAIN认证方式:
[root@mail postfix]# perl -MMIME::Base64 -e \ > 'print encode_base64("virtualuser\@cngnu.org\000virtualuser\@cngnu.org\000testpw");' [root@mail postfix]# telnet localhost 25 Trying 127.0.0.1... EHLO cngnu 250-mail.cngnu.org 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-XVERP 250 8BITMIME AUTH PLAIN dmlydHVhbHVzZXJAY25nbnUub3JnAHZpcnR1YWx1c2VyQGNuZ251Lm9yZwB0ZXN0cHc== 235 Authentication successful QUIT 221 Bye Connection closed by foreign host. [root@mail postfix]# perl -MMIME::Base64 -e \ > 'print encode_base64("trueuser\000trueuser\000testpw");' |
LOGIN认证方式:
[root@mail postfix]# perl -MMIME::Base64 -e \ > 'print encode_base64("virtualuser\@cngnu.org");' dmlydHVhbHVzZXJAY25nbnUub3Jn [root@mail postfix]# perl -MMIME::Base64 -e \ > 'print encode_base64("testpw");' dGVzdHB3 [root@mail postfix]# telnet localhost 25 Trying 127.0.0.1... EHLO cngnu 250-mail.cngnu.org 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-XVERP 250 8BITMIME AUTH LOGIN 334 VXNlcm5hbWU6 dmlydHVhbHVzZXJAY25nbnUub3Jn 334 UGFzc3dvcmQ6 dGVzdHB3 235 Authentication successful QUIT 221 Bye Connection closed by foreign host. [root@mail postfix]# perl -MMIME::Base64 -e \ > 'print encode_base64("trueuser");' dHJ1ZXVzZXI= [root@mail postfix]# perl -MMIME::Base64 -e \ > 'print encode_base64("testpw");' dGVzdHB3 |
此时,由于还没有安装Cyrus-IMAP以及创建邮箱,所以还不能提交邮件,请继续下一步。
这里使用Perl里面的MIME::Base64模块(如果需要安装:perl -MCPAN -e 'install MIME::Base64;')来取得这个验证串:perl -MMIME::Base64 -e 'print base64_encode("用户名\000用户名\000密码");'来得到MIME-Base64编码的验证串(“\000”是八进制的ASCII (0)字符)。此外,你也可以使用mmencode来生成,mmencode可以在metamail这个包里面找到。
8. 安装Cyrus-IMAP
8.1. 下载
http://asg.web.cmu.edu/cyrus/download/
[root@mail postfix]# cd /usr/src [root@mail src]# wget ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-imapd-2.1.16.tar.gz |
8.2. 编译与安装
在RedHat系列的Linux中,其Kerberos的头文件不在标准的地方,所以需要在编译配置前用env命令指定。此外取消对ucdsnmp的支持:
[root@mail src]# tar -zxf cyrus-imapd-2.1.16.tar.gz [root@mail src]# cd cyrus-imapd-2.1.16 [root@mail cyrus-imapd-2.1.16]# env CPPFLAGS=-I/usr/kerberos/include \ > ./configure --with-cyrus-prefix=/usr/cyrus \ > --with-sasl=/usr/lib/sasl2 --with-auth=unix \ > --without-ucdsnmp --with-krb=/usr/kerberos [root@mail cyrus-imapd-2.1.16]# make depend [root@mail cyrus-imapd-2.1.16]# make all CFLAGS=-O [root@mail cyrus-imapd-2.1.16]# make install |
如果编译时提示没有找到com_err.h,请复制当前目录的et目录下面的com_err.h到/usr/include:
[root@mail cyrus-imapd-2.1.16]# cp et/com_err.h /usr/include |
Cyrus-IMAP的安装脚本有问题,cyradm(现在使用的是Perl版本,原来的TCL版本不再支持)所需要的perl模块被安装到一些不在Perl的标准@INC的目录里,需要手工安装。
[root@mail cyrus-imapd-2.1.16]# cd perl/imap [root@mail imap]# perl Makefile.PL [root@mail imap]# make install |
8.3. 配置
创建主配置文件/etc/cyrus.conf:
[root@mail imap]# cd ../.. [root@mail cyrus-imapd-2.1.16]# cp master/conf/small.conf /etc/cyrus.conf |
添加cyrus-imap的管理账号cyrus,并设置密码为“cyrus”(实际应用中可以使用更加复杂的密码),但是没有指定有效的SHELL,以防止使用它来登录:
[root@mail cyrus-imapd-2.1.16]# useradd -g mail -M -s/no/shell -d/var/imap cyrus [root@mail cyrus-imapd-2.1.16]# passwd cyrus Changing password for user cyrus New password: cyrus BAD PASSWORD: it it too short Retype new password: cyrus passwd: all authentocation tokens updated successfully |
创建IMAP配置文件/etc/imapd.conf,管理员是cyrus:
[root@mail cyrus-imapd-2.1.16]# vi /etc/imapd.conf |
configdirectory: /var/imap partition-default: /var/spool/imap admins: cyrus sasl_pwcheck_method: saslauthd sasl_mech_list: plain unixhierarchysep: yes altnamespace: yes |
在/etc/imapd.conf中使用了unixhierarchysep: yes的配置可以创建带“.”的邮箱。邮件存储分区在/var/spool/imap,可以针对需求设定多个分区或其它位置。关于imapd.conf可 以参阅Cyrus-IMAP的文档来配置其他可用的参数。
建立Cyrus-IMAP服务器的目录结构:
[root@mail cyrus-imapd-2.1.16]# mkdir -p /var/imap/sieve [root@mail cyrus-imapd-2.1.16]# mkdir /var/spool/imap [root@mail cyrus-imapd-2.1.16]# chown -R cyrus:mail /var/imap [root@mail cyrus-imapd-2.1.16]# chown -R cyrus:mail /var/spool/imap [root@mail cyrus-imapd-2.1.16]# su -s/bin/bash cyrus bash-2.05$ tools/mkimap bash-2.05$ exit |
这里tools/mkimap这个实用程序在cyrus-imap的源程序目录里面。
创建日志:
[root@mail cyrus-imapd-2.1.16]# echo local6.debug /var/log/imapd.log >> /etc/syslog.conf [root@mail cyrus-imapd-2.1.16]# echo auth.debug /var/log/auth.log >> /etc/syslog.conf [root@mail cyrus-imapd-2.1.16]# /etc/rc.d/init.d/syslog restart |
设置邮件限额:
[root@mail cyrus-imapd-2.1.16]# chattr -R +S /var/imap/user [root@mail cyrus-imapd-2.1.16]# chattr -R +S /var/imap/quota [root@mail cyrus-imapd-2.1.16]# chattr -R +S /var/spool/imap |
由于Cyrus-IMAP的主控进程和Postfix的主控进程名字一样,容易混淆而且不方便控制,所以将Cyrus-IMAP服务器的主控进程做个别名连接:cyrusd。
[root@mail cyrus-imapd-2.1.16]# cd /usr/cyrus/bin [root@mail bin]# ln -s master cyrusd |
8.4. 运行
启动命令如下:
[root@mail bin]# /usr/cyrus/bin/cyrusd& |
8.5. 测试Cyrus-IMAP
启动Cyrus-IMAP后,首先检查日志/var/log/messages、/var/log/imapd.log和/var/log/auth.log有无错误信息,然后检查进程,应该有如下进程存在:
[root@mail bin]# pstree |grep cyrusd |-cyrusd |
接着检查端口,应该有如下端口打开:
[root@mail bin]# netstat -an |grep LISTEN tcp 0 0 0.0.0.0:110 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:143 0.0.0.0:* LISTEN |
现在创建邮箱。
使用cyradm来创建和删除邮箱,它是Cyrus-IMAP自己带的交互式管理界面,现在的版本是用Perl写的。你也可以直接调用 Cyrus::IMAP::Admin模块创建自己的CGI或脚本来做邮箱管理,可以参考Cyrus::IMAP::Shell模块的程序。
对于非虚拟域邮箱,只需要创建同用户名相同的邮箱(邮件的本地部分)。
对于虚拟域邮箱,为了将虚拟域用户区别开来,我们希望使用用户的邮件全称来做它的邮箱名(其POP3/IMAP的登录名和邮箱名是一样的),但是虽然 Cyrus-IMAP允许你创建带有“@”的邮箱,但是Cyrus-IMAP的deliver不支持邮件的本地部分带有“@”的邮箱,以至于不能正常递 交。我们采用了以下步骤来解决这个问题:
- 首先,在cyradm中创建两个邮箱,一个是邮件地址全称做邮箱名,我们称之为“地址邮箱”;一个通过将邮件地址其中的“@”换成了“~”做邮箱名,我们称之为“存储邮箱”。
- 然后,退出cyradm,在邮件分区的user目录下(这里是/var/spool/imap/user),找到刚才创建的邮箱。在文件系统中删除“地址邮箱”,并将“存储邮箱”做个符号链接,名字就是刚刚删除的“地址邮箱”。
- 最后,设置数据库中的FORWARD字段,使之将邮件投递到“存储邮箱”。
之所以这样做的原因是,通过在cyradm中创建两个邮箱,通知了Cyrus-IMAP系统中存在“地址邮箱”,删除地址邮箱,并将其作为“存 储邮箱”的别名是希望通过它能访问到实际存储邮件的“存储邮箱”。(另外请注意,邮箱名称中的点实际在文件系统中是用“^”代表的)
[root@mail bin]# cyradm --user cyrus localhost IMAP Password: mail.cngnu.org> cm user/cyrus mail.cngnu.org> sq user/cyrus STORAGE 10485760 mail.cngnu.org> cm user/trueuser mail.cngnu.org> sq user/trueuser STORAGE 10485760 mail.cngnu.org> cm user/virtualuser~cngnu.org mail.cngnu.org> cm user/virtualuser@cngnu.org mail.cngnu.org> sq user/virtualuser~cngnu.org STORAGE 10485760 mail.cngnu.org> lm user/INBOX (\HasNoChildren) mail.cngnu.org> quit [root@mail bin]# cd /var/spool/imap/user [root@mail user]# ls cyrus trueuser virtualuser~cngnu^org virtualuser@cngnu^org [root@mail user]# rm -rf tester\@cngnu\^org [root@mail user]# ln -s tester~cngnu^org tester@cngnu^org |
如果要删除一个IMAP邮箱,需要先给管理员cyrus授予C(Create)和D(Delete)的权限才可以删除。
[root@mail user]# cyradm --user cyrus localhost IMAP Password: mail.cngnu.org> cm user/testdel mail.cngnu.org> lm user/INBOX (\HasNoChildren) mail.cngnu.org> sam user/testdel cyrus cd mail.cngnu.org> dm user/testdel mail.cngnu.org> lm user/INBOX (\HasNoChildren) mail.cngnu.org> quit [root@mail user]# rm -rf testdel |
再检测POP3和IMAP服务:
[root@mail user]# telnet localhost 110 +OK mail.cngnu.org Cyrus POP3 v2.1.16 server ready USER virtualuser@cngnu.org +OK Name is a valid mailbox PASS testpw +OK Maildrop locked and ready QUIT +OK [root@mail bin]# imtest -m login -a virtualuser@cngnu.org
localhost |
9. 安装IMP
9.1. 下载
http://www.horde.org/horde/
http://www.horde.org/imp/3.2.2/
http://www.horde.org/turba/
[root@mail user]# cd /usr/src [root@mail src]# wget ftp://ftp.horde.org/pub/horde/horde-2.2.4.tar.gz [root@mail src]# wget ftp://ftp.horde.org/pub/pear/pear-1.1.tar.gz [root@mail src]# wget ftp://ftp.horde.org/pub/imp/imp-3.2.2.tar.gz [root@mail src]# wget ftp://ftp.horde.org/pub/turba/turba-1.2.1.tar.gz |
9.2. 配置Apache与PHP
IMP对PHP的环境要求较高。所以通常需要升级PHP包,并安装由Horde定制后的PEAR包。
修改/etc/php.ini,将register_globals功能打开。
register_globals = On |
安装PEAR包,在AS3中,它位于/usr/share/pear下:
[root@mail src]# tar zxf /usr/src/pear-1.1.tar.gz [root@mail lib]# cd /usr/share [root@mail lib]# /bin/cp -Rf /usr/src/pear/* pear |
最后重新启动Apache:
[root@mail lib]# /etc/rc.d/init.d/httpd restart |
9.3. 配置Horde
安装Horde:
[root@mail lib]# cd /var/www/html [root@mail html]# tar zxf /usr/src/horde-2.2.4.tar.gz [root@mail html]# mv horde-2.2.4 horde [root@mail html]# cd horde/scripts/db [root@mail db]# mysql < mysql_create.sql [root@mail db]# cd ../../config [root@mail config]# for foo in *.dist; do cp $foo `basename $foo .dist`;done |
然后修改config目录下面的horde.php。
[root@mail config]# vi horde.php |
修改162行:
$conf['prefs']['driver'] = 'none'; |
为:
$conf['prefs']['driver'] = 'sql'; |
修改171行至176行,将其注释去掉并写入horde数据库的口令:
// $conf['prefs']['params']['phptype'] = 'mysql'; |
为:
$conf['prefs']['params']['phptype'] = 'mysql'; |
这里我们没有修改horde数据库的默认的数据库设置,如果在实际使用中,至少应该取一个比较复杂的密码。
再来修改config目录下面的registry.php。
[root@mail config]# vi registry.php |
修改23行至24行,将其注释去掉:
// $this->registry['auth']['login'] = 'imp'; |
为:
$this->registry['auth']['login'] = 'imp'; |
然后修改119、138行激活IMP和Turba:
'status' => 'inactive' |
为:
'status' => 'active' |
最后在浏览器中访问如下URL测试Horde需要的环境是否满足:
http://你的邮件服务器的IP/horde/test.php |
如果发现有红色的提示,可能需要修改你的PHP的安装和配置(参见上一节),然后再重新测试。
9.4. 配置IMP
安装IMP:
[root@mail config]# cd .. [root@mail horde]# tar zxf /usr/src/imp-3.2.2.tar.gz [root@mail horde]# mv imp-3.2.2 imp [root@mail horde]# cd imp/config [root@mail config]# for foo in *.dist; do cp $foo `basename $foo .dist`;done |
然后修改config目录里面的conf.php:
[root@mail config]# vi conf.php |
修改37行:
$conf['menu']['apps'] = array(); |
为:
$conf['menu']['apps'] = array('turba'); |
修改57行:
$conf['user']['allow_resume_all'] = false; |
为:
$conf['user']['allow_resume_all'] = true; |
修改63行:
$conf['user']['allow_resume_all_in_drafts'] = false; |
为:
$conf['user']['allow_resume_all_in_drafts'] = true; |
然后修改prefs.php:
[root@mail config]# vi prefs.php |
将自动维护功能关闭,修改426、427行:
'value' => 1, |
为:
'value' => 0, |
再注释773行:
'value' => '', |
为:
//'value' => '', |
取消注释774行:
// 'value' => 'localsql', |
为:
'value' => 'localsql', |
最后修改servers.php:
[root@mail config]# vi servers.php |
注释除“cyrus”服务器外的所有服务器配置,然后修改“cyrus”服务器的配置为:
$servers['cyrus'] = array( |
9.5. 配置Turba
安装Turba:
[root@mail config]# cd ../.. [root@mail horde]# tar zxf /usr/src/turba-1.2.1.tar.gz [root@mail horde]# mv turba-1.2.1 turba [root@mail horde]# cd turba/config [root@mail config]# for foo in *.dist; do cp $foo `basename $foo .dist`;done |
然后修改config目录里面的conf.php:
[root@mail config]# vi conf.php |
修改32行:
$conf['menu']['apps'] = array(); |
为:
$conf['menu']['apps'] = array('imp'); |
然后修改config目录里面的sources.php:
[root@mail config]# vi sources.php |
修改146行:
'password' => '*****'; |
为:
'password' => 'horde'; |
最后,添加turba数据库表:
[root@mail config]# cd ../scripts/drivers [root@mail config]# mysql horde <turba.sql |
9.6. 测试IMP
最后在浏览器中访问如下URL:
http://你的邮件服务器的IP/horde/ |
输入用户名virtualuser@cngnu.org和密码testpw登录(或trueuser)。
10. 其他
10.1. 启动脚本
可以编写一个启动脚本/etc/rc.d/init.d/mailsys来启动这些进程,这样就不需要单独启动postfix和cyrusd了:
#!/bin/bash |
[root@mail root]# chmod 755 /etc/rc.d/init.d/mailsys [root@mail root]# chkconfig --level 0123456 mailsys on [root@mail root]# chkconfig --level 0123456 sendmail off |
10.2. 整体测试
创建邮箱后,测试发信功能:
[root@mail root]# mail virtualuser@cngnu.org Subject: test by me this is a test. . CC: [root@mail root]# mailq Mail queue is empty [root@mail root]# tail /var/log/maillog |
使用mailq来查看邮件队列是否有错误,并查看/var/log/mail/*是否有错误信息。如果一切正常,说明信件已经发送到tester了。
测试收信,先测试POP3:
[root@mail root]# telnet localhost 110 +OK mail.cngnu.org Cyrus POP3 v2.1.16 server ready USER virtualuser@cngnu.org +OK Name is a valid mailbox PASS testpw +OK Maildrop locked and ready LIST 1 400 TOP 1 10 Return-Path: <root@cngnu.org> this is a test. . QUIT +OK |
再测试IMAP:
[root@mail root]# imtest -m login -a virtualuser@cngnu.org
localhost . select inbox . fetch 1:1 (FLAGS BODY[HEADER.FIELDS (DATE FROM)]) ) |
最后测试IMP,在浏览器中访问如下URL:
http://你的邮件服务器的IP/horde/ |
输入用户名virtualuser@cngnu.org和密码testpw登录。
你也可以使用任何其它的邮件客户端程序来测试,如kmail、Outlook Express等等。
OK,到此为止,我们的邮件系统就架设完毕了。如果有任何问题,请到http://www.anti-spam.org.cn/forums/的mail版讨论。