CNGNU Postfix邮件系统系列指南之一

Postfix + Cyrus-IMAP + Cyrus-SASL + MySQL + IMP
完全指南


 

作者:王兴宇 <wxy@cngnu.org>

版本:0.71

版权:GPL

发布日期:2003-02-04

 

目录

1.  概述

1.1.  目的

1.2.  更新历史

1.3.  TODO

1.4.  鸣谢

2.  系统功能

3.  系统基本前提

4.  安装MySQL

4.1. 下载

4.2. 编译与安装

4.3. 运行

4.4. 测试

4.5.  建立数据库

5.  安装pam_mysql

5.1.  下载

5.2.  编译与安装

5.3.  配置

6.  配置Cyrus-SASL

6.1.  配置

6.2. 运行

7.  安装Postfix

7.1.  下载

7.2.  编译与安装

7.3.  配置

7.4.  运行

7.5.  测试

8.  安装Cyrus-IMAP

8.1.  下载

8.2.  编译与安装

8.3.  配置

8.4.  运行

8.5.  测试

9.  安装IMP

9.1.  下载

9.2.  配置Apache/PHP

9.3.  配置Horde

9.4.  配置Imp

9.5.  配置Turba

9.6.  测试IMP

10.  其它

10.1.  启动脚本

10.2.  整体测试


 

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.  更新历史

1.3.  TODO

1.4.  鸣谢

  谢谢lesson.ward、Yunping Zhu、Temp、bjchenxu的指正。也感谢Chinaunix.netanti-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 (
ID int(10) unsigned NOT NULL auto_increment,
USERNAME varchar(128) NOT NULL default '',
PASSWORD varchar(40) NOT NULL default '',
FORWARD varchar(128) NOT NULL default '',
DOMAIN varchar(64) NOT NULL default '',
MAIL varchar(64) NOT NULL default '',
FILTER varchar(64) NOT NULL default 'OK',
PARTITION varchar(32) NOT NULL default 'default',
QUOTA int(11) NOT NULL default '10485760',
STATUS tinyint(4) NOT NULL default '1',
PRIMARY KEY (ID),
UNIQUE KEY USERNAME (USERNAME),
UNIQUE KEY MAIL (MAIL)
) TYPE=MyISAM;

 

INSERT INTO USER (USERNAME,PASSWORD,FORWARD,DOMAIN,MAIL)

VALUES ('trueuser','$1$pi.WVgBx$a3dUCzBnbY76jnZlqWQCQ/',

'trueuser','cngnu.org','trueuser@cngnu.org'),
('virtualuser@cngnu.org','$1$pi.WVgBx$a3dUCzBnbY76jnZlqWQCQ/',

'virtualuser~cngnu.org','cngnu.org','virtualuser@cngnu.org');

 

[root@mail root]# mysql < mail.sql

  在MySQL中创建邮件用户数据库,并添加两个测试邮箱:

  上面的mail数据库的USER表用来保存用户信息:

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=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/newaliases /usr/bin/newaliases.orig

[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 =
    permit_mynetworks,
    permit_sasl_authenticated,
    check_recipient_access mysql:/etc/postfix/filter.mysql,
    reject_invalid_hostname,
    reject_non_fqdn_hostname,
    reject_unknown_sender_domain,
    reject_non_fqdn_sender,
    reject_non_fqdn_recipient,
    reject_unknown_recipient_domain,
    reject_unauth_pipelining,
    reject_unauth_destination,
    permit

  如果希望支持更多的虚拟域,可以在mydestination参数后面加上你所要支持的域即可。

  通过virtual和virtual.mysql为系统提供了邮箱本地查询表。

  使用了SASL来进行SMTP发信认证。

  通过smtpd_recipient_restrictions提供了基本的反垃圾邮件功能。首先允许本地网络(这里是本机)和通过SASL认 证的用户可以使用本服务器发信;然后检查每个用户的全局邮件过滤功能是否打开,如果关闭则不进行后面的反垃圾邮件检查;其后是一些Postfix支持的基 本反垃圾邮件功能。

  创建/etc/postfix/virtual.mysql,它提供了本地用户和邮件转发功能。FORWARD字段默认是指向用户的存储邮箱名 的(Cyrus-IMAP所管理的邮箱名称),即进行本地投递;如果FORWARD字段是另外一个用户名或者邮件地址,则该邮件被转发到别的用户或其它邮 件地址。对于

[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...
Connected to localhost.
Escape character is '^]'.
220 mail.cngnu.org ESMTP Postfix
QUIT
221 Bye
Connection closed by foreign host.

  使用如下命令测试postfix的SMTP的认证(这里仅测试了“virtualuser@cngnu.org”,“trueuser”请自行测试):

  PLAIN认证方式:

[root@mail postfix]# perl -MMIME::Base64 -e \

> 'print encode_base64("virtualuser\@cngnu.org\000virtualuser\@cngnu.org\000testpw");'
dmlydHVhbHVzZXJAY25nbnUub3JnAHZpcnR1YWx1c2VyQGNuZ251Lm9yZwB0ZXN0cHc=

 

[root@mail postfix]# telnet localhost 25

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.cngnu.org ESMTP Postfix

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");'
dHJ1ZXVzZXIAdHJ1ZXVzZXIAdGVzdHB3

 

  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...
Connected to localhost.
Escape character is '^]'.
220 mail.cngnu.org ESMTP Postfix

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不支持邮件的本地部分带有“@”的邮箱,以至于不能正常递 交。我们采用了以下步骤来解决这个问题:

  1. 首先,在cyradm中创建两个邮箱,一个是邮件地址全称做邮箱名,我们称之为“地址邮箱”;一个通过将邮件地址其中的“@”换成了“~”做邮箱名,我们称之为“存储邮箱”。
  2. 然后,退出cyradm,在邮件分区的user目录下(这里是/var/spool/imap/user),找到刚才创建的邮箱。在文件系统中删除“地址邮箱”,并将“存储邮箱”做个符号链接,名字就是刚刚删除的“地址邮箱”。
  3. 最后,设置数据库中的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)
user/trueuser (\HasNoChildren)
user/virtualuser~cngnu.org (\HasNoChildren)
user/virtualuser@cngnu.org (\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)
user/testdel (\HasNoChildren)
user/trueuser (\HasNoChildren)
user/virtualuser~cngnu.org (\HasNoChildren)
user/virtualuser@cngnu.org (\HasNoChildren)

mail.cngnu.org> sam user/testdel cyrus cd

mail.cngnu.org> dm user/testdel

mail.cngnu.org> lm

user/INBOX (\HasNoChildren)
user/testdel (\HasNoChildren)
user/trueuser (\HasNoChildren)
user/virtualuser~cngnu.org (\HasNoChildren)
user/virtualuser@cngnu.org (\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
C: C01 CAPABILITY
S: * OK mail.cngnu.org Cyrus IMAP4 v2.1.16 server ready
S: * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ NAMESPACE UIDPLUS ID NO_ATOMIC_RENAME UNSELECT MULTIAPPEND SORT THREAD=ORDEREDSUBJECT THREAD=REFERENCES IDLE
S: C01 OK Completed
Password: testpw
C: L01 LOGIN virtualuser@cngnu.org {6}
+ go ahead
C: <omitted>
L01 OK User logged in
Authenticated.
Security strength factor: 0
. logout
* BYE LOGOUT received
. OK Completed

 

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']['hostspec'] = 'localhost';
// $conf['prefs']['params']['username'] = 'horde';
// $conf['prefs']['params']['password'] = '*****';
// $conf['prefs']['params']['database'] = 'horde';
// $conf['prefs']['params']['table'] = 'horde_prefs';

  为:

$conf['prefs']['params']['phptype'] = 'mysql';
$conf['prefs']['params']['hostspec'] = 'localhost';
$conf['prefs']['params']['username'] = 'horde';
$conf['prefs']['params']['password'] = 'horde';
$conf['prefs']['params']['database'] = 'horde';
$conf['prefs']['params']['table'] = 'horde_prefs';

  这里我们没有修改horde数据库的默认的数据库设置,如果在实际使用中,至少应该取一个比较复杂的密码。

 

  再来修改config目录下面的registry.php。

[root@mail config]# vi registry.php

  修改23行至24行,将其注释去掉:

// $this->registry['auth']['login'] = 'imp';
// $this->registry['auth']['logout'] = 'imp';

  为:

$this->registry['auth']['login'] = 'imp';
$this->registry['auth']['logout'] = '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,
'locked' => false,

  为:

'value' => 0,
'locked' => true,

  再注释773行:

'value' => '',

  为:

//'value' => '',

  取消注释774行:

// 'value' => 'localsql',

  为:

'value' => 'localsql',

 

  最后修改servers.php:

[root@mail config]# vi servers.php

  注释除“cyrus”服务器外的所有服务器配置,然后修改“cyrus”服务器的配置为:

$servers['cyrus'] = array(
'name' => 'Cyrus IMAP Server',
'server' => 'localhost',
'protocol' => 'imap/notls',
'port' => 143,
'folders' => '',
'namespace' => 'INBOX.',
'maildomain' => 'cngnu.org',
'realm' => 'cngnu.org',
'preferred' => ''
);

 

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
#
# mailsys This shell script takes care of starting and stopping
# Postfix and Cyrus-IMAP.
# author : xingyu.wang <wxy@cngnu.org> 2004/1/18
#
# chkconfig: 2345 80 30
# description: Postfix is a Mail Transport Agent, which is the program
# that moves mail from one machine to another.Cyrus-IMAP is a Mail # Deliver Agent, which provide POP3 and IMAP4 services for user and # deliver mail to local mailbox. # # processname: mailsys # pidfile: /var/run/mailsys.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ ${NETWORKING} = "no" ] && exit 0 [ -f /usr/sbin/postfix ] || exit 0 [ -f /usr/cyrus/bin/cyrusd ] || exit 0 RETVAL=0 prog="Mail System" start() { # Start daemons. echo -n $"Starting $prog: " echo -n $"SMTP " /usr/sbin/postfix start > /dev/null 2>&1 & echo -n $"POP3 IMAP4 " /usr/cyrus/bin/cyrusd > /dev/null 2>&1 & RETVAL=$? if [ $RETVAL -eq 0 ]; then touch /var/lock/subsys/mailsys success $"$prog start" else failure $"$prog start failure" fi echo return $RETVAL } stop() { # Stop daemons. echo -n $"Shutting down $prog: " echo -n $"SMTP " /usr/sbin/postfix stop > /dev/null 2>&1 & echo -n $"POP3 IMAP4 " killproc cyrusd RETVAL=$? if [ $RETVAL -eq 0 ]; then rm -f /var/lock/subsys/mailsys success $"$prog stop" else failure $"$prog stop failure" fi echo return $RETVAL } # See how we were called. case "$1" in start) start ;; stop) stop ;; restart|reload) stop start RETVAL=$? ;; *) echo $"Usage: $0 {start|stop|restart}" exit 1 esac exit $RETVAL

 

[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>
X-Sieve: CMU sieve 2.2
Return-Path: <root@cngnu.org>
Received: by mail. (Postfix, from userid 0)
id 5F1EF90005; Sat, 18 Jan 2004 02:16:43 +0800 (CST)
To: tester@cngnu.org
Subject: test by me
Message-Id: <20040118021643.5F1EF90005@mail.cngnu.org>
Date: Sat, 18 Jan 2004 02:16:43 +0800 (CST)
From: root@cngnu.org (root)

this is a test.

.

QUIT

+OK

  再测试IMAP:

[root@mail root]# imtest -m login -a virtualuser@cngnu.org localhost
C: C01 CAPABILITY
S: * OK mail.cngnu.org Cyrus IMAP4 v2.1.16 server ready
S: * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ NAMESPACE UIDPLUS ID NO_ATOMIC_RENAME UNSELECT MULTIAPPEND SORT THREAD=ORDEREDSUBJECT THREAD=REFERENCES IDLE
S: C01 OK Completed
Password:
C: L01 LOGIN virtualuser {6}
+ go ahead
C: <omitted>
L01 OK User logged in
Authenticated.
Security strength factor: 0

. select inbox
* FLAGS (\Answered \Flagged \Draft \Deleted \Seen)
* OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen \*)]
* 1 EXISTS
* 1 RECENT
* OK [UIDVALIDITY 1021736432]
* OK [UIDNEXT 3]
. OK [READ-WRITE] Completed

. fetch 1:1 (FLAGS BODY[HEADER.FIELDS (DATE FROM)])
* 1 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS (DATE FROM)] {68}
Date: Mon, 20 May 2002 09:26:09 +0800 (CST)
From: wxy@cngnu.org

)
. OK Completed
. logout
* BYE LOGOUT received
. OK Completed

 

  最后测试IMP,在浏览器中访问如下URL:

http://你的邮件服务器的IP/horde/

  输入用户名virtualuser@cngnu.org和密码testpw登录。

 

  你也可以使用任何其它的邮件客户端程序来测试,如kmail、Outlook Express等等。

 

  OK,到此为止,我们的邮件系统就架设完毕了。如果有任何问题,请到http://www.anti-spam.org.cn/forums/的mail版讨论。