作者:王兴宇 <wxy@cngnu.org>
版本:0.21
版权:GPL
发布日期:2002-8-13
目录
本文试图介绍如何在一个Linux平台上安装一套功能完整的邮件系统。这里我们以Postfix做SMTP服务器、Cyrus-IMAP做POP3/IMAP4服务器、通过Cyrus-SASL对存储在MySQL数据库中的用户进行验证和授权。
这个邮件系统的设计目标是提供一个可扩充的、具备大多数功能的邮件系统。
本文的最新版本可以在这里找到:
本文的版权遵循GPL,可以在不删除版权信息和注明修改的情况下任意传播。
谢谢lesson.ward、Yunping Zhu的指正。
参考文档:http://www.delouw.ch/linux/Postfix-Cyrus-Web-cyradm-HOWTO/html/index.html
系统逻辑结构:
+---------------------------------------------------------------------------------------+ | | | 25/25 25/25 110/993 143/995 80/443 110/993 143/995 | | Incoming Outgoing POP3 IMAP WEB-MAIL POP3 IMAP | | /\ /\ /\ /\ /\ /\ /\ | | || || || || || || || | | \/ \/ \/ \/ \/ \/ \/ | +-----------------------+--------------------+---------------------+--------------------+ | Postfix | | SqWebmail | | | | +----------+----------+ | | | Cyrus-IMAP | Courier-IMAP | | +-----------+-------------------------------+-------------------------------+ | | Cyrus-IMAP | | +---------------------------------------------------------------------------+ | | PAM | | +---------------------------------------------------------------------------+ | | pam_mysql | +-----------+---------------------------------------------------------------------------+ | MySQL | +---------------------------------------------------------------------------------------+
本文以Linux系统为目标平台,支持多数的Linux平台如RedHat 7.x、Mandrake 8.x等,理论上也会支持其他的Linux发行版,甚至其他的UNIX系统。
这里以Mandrake 8.2为说明平台。
该系统除了基本的操作系统部分外,还需要确认系统中安装如下的RPM:
一、gcc:
1. libgcc3.0-3.0.4-2mdk
2. gcc-2.96-0.76mdk
3. gcc-c++-2.96-0.76mdk
4. gcc-cpp-2.96-0.76mdk
二、db3:
1. libdb3.3-devel-3.3.11-7mdk
2. libdb3.3-3.3.11-7mdk
3. db3-utils-3.3.11-7mdk
三、pam:
1. pam-0.75-20mdk
2. pam-devel-0.75-20mdk
四、apache(仅在需要SqWebmail时)
1. apache-conf-1.3.23-4mdk
2. apache-1.3.23-4mdk
3. apache-common-1.3.23-4mdk
4. apache-modules-1.3.23-4mdk
除此之外,其他需要的部分以源码方式编译。
http://www.mysql.com/downloads/
wget http://www2.linuxforum.net/mirror/mysql/Downloads/MySQL-3.23/mysql-3.23.49.tar.gz
编译MySQL:
# cd /usr/src
# tar -xvzf mysql-3.23.49.tar.gz # cd mysql-3.23.49
# ./configure --prefix=/usr/local/mysql --enable-assembler --with-innodb
# make # make install |
初始化数据库:
# /usr/local/mysql/bin/mysql_install_db |
安装引导脚本:
# cp /usr/local/mysql/share/mysql/mysql.server /etc/init.d/mysqld # cd /etc/rc.d/rc3.d # ln -s ../init.d/mysqld S90mysql # ln -s ../init.d/mysqld K90mysql |
加载链接库:
# ln -s /usr/local/mysql/include/mysql /usr/include/mysql # ln -s /usr/local/mysql/lib/mysql /usr/lib/mysql
# echo /usr/lib/mysql >> /etc/ld.so.conf # ldconfig |
为了提高安全性,在系统中添加一个“mysql”用户,并将MySQL数据库目录的属主设为“mysql”:
# useradd –d/usr/local/mysql mysql # chown –R mysql /var/lib/mysql |
然后,修改/etc/init.d/mysqld,使其只监听localhost的端口,将如下的一行
$bindir/safe_mysqld --datadir=$datadir --pid-file=$pid_file& |
修改为:
$bindir/safe_mysqld --datadir=$datadir --pid-file=$pid_file --bind-address=127.0.0.1& |
然后启动MySQL:
# /etc/init.d/mysql start |
创建MySQL的邮件用户数据库,并添加一个管理用户“cyrus”和一个测试用户“tester”:
# PATH=”$PATH”:/usr/local/mysql/bin;export PATH # mysql mysql mysql> CREATE DATABASE mail; mysql> GRANT ALL ON mail.* TO mail@localhost -> IDENTIFIED BY "secret"; mysql> FLUSH PRIVILEGES; mysql> USE mail; mysql> CREATE TABLE user ( -> username varchar(32) NOT NULL default '', -> password varchar(32) binary NOT NULL default '', -> forward varchar(128) NOT NULL default '', -> status int(11) NOT NULL default ‘1’, -> UNIQUE KEY username (username) -> );
mysql> INSERT INTO user VALUES -> (‘cyrus’,’cyrus’,’cyrus’,1);
mysql> INSERT INTO user VALUES -> (‘tester’,’testpw’,’tester’,1);
mysql> \q |
一些软件对mysql的本地连接使用的另外一个位置的sock入口,做个软连接:
# ln –s /tmp/mysql.sock /var/lib/mysql/mysql.sock |
http://sourceforge.net/projects/pam-mysql/
wget http://prdownloads.sourceforge.net/pam-mysql/pam_mysql-0.4.7.tar.gz
编译pam_mysql:
# tar -xvzf pam_mysql-0.4.7.tar.gz # cd pam_mysql # make # cp pam_mysql.so /lib/security |
创建/etc/pam.d/imap,它用来支持Cyrus-IMAP的imap认证:
# echo auth sufficient pam_mysql.so user=mail passwd=secret host=localhost db=mail table=user \ usercolumn=username passwdcolumn=password crypt=0 >> /etc/pam.d/imap # echo account required pam_mysql.so user=mail passwd=secret host=localhost db=mail table=user \ usercolumn=username passwdcolumn=password crypt=0 >> /etc/pam.d/imap |
同样创建/etc/pam.d/pop ,它用来支持Cyrus-IMAP的pop3认证:
# cd /etc/pam.d # ln –s imap pop |
同样创建/etc/pam.d/smtp ,它用来支持Postfix的smtp auth认证:
# cd /etc/pam.d # ln -s imap smtp |
http://asg.web.cmu.edu/cyrus/download/
wget ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-sasl-1.5.27.tar.gz
编译Cyrus-sasl,只支持需要的plain和login认证方式:
# tar -zxvf cyrus-sasl-1.5.27.tar.gz # cd cyrus-sasl-1.5.27 # ./configure --disable-sample --disable-saslauthd --disable-pwcheck --disable-cram --disable-digest \ --disable-krb4 --disable-gssapi --disable-anon --enable-plain --enable-login
# make # make install
# ln -s /usr/local/lib/sasl /usr/lib/sasl |
加载链接库:
# echo /usr/local/lib >> /etc/ld.so.conf # echo /usr/local/lib/sasl >> /etc/ld.so.conf # ldconfig |
注意,这里使用的是SASL V1,目前SASL V2和Postfix配合上可能还有问题。
设置Postfix使用SASL来支持smtp auth认证:
# echo pwcheck_method: pam > /usr/lib/sasl/smtpd.conf |
Cyrus-IMAP的SASL配置不使用标准的sasl语法,它的配置文件放在/etc/imapd.conf中,详细配置在Cyrus-IMAP部分说明。
http://www.postfix.org/ftp-sites.html
wget http://postfix.energybeam.com/source/official/postfix-1.1.7.tar.gz
如果你的系统上原来有sendmail,先将其停止并将其文件改名:
# /etc/init.d/sendmail stop # mv /usr/bin/newaliases /usr/bin/newaliases.OFF # mv /usr/bin/mailq /usr/bin/mailq.OFF # mv /usr/sbin/sendmail /usr/sbin/sendmail.OFF |
然后添加两个组:postfix和maildrop和一个用户:postfix
# groupadd –g 12345 postfix # groupadd -g 54321 postdrop # useradd –u 12345 –g 12345 -d/dev/null -s/bin/false postfix |
这里的组和用户的ID是系统中未使用的ID。
编译Postfix,并支持mysql和sasl:
# tar -xvzf postfix-1.1.7.tar.gz # cd postfix-1.1.7
# make -f Makefile.init makefiles 'CCARGS=-DUSE_SASL_AUTH -DHAS_MYSQL -I/usr/include/mysql' \ 'AUXLIBS=-L/usr/lib/mysql -lmysqlclient –lsasl -lz -lm' # make install |
安装时,安装程序会提问一些问题,可以直接按回车采用默认值。
将用户postfix添加到/etc/aliases中:
# echo ‘postfix: root’ >> /etc/aliases |
修改/etc/postfix/master.cf中的cyrus的配置,将如下一行:
flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user} |
修改为:
flags=R user=cyrus argv=/usr/local/cyrus/bin/deliver –r ${sender} -m ${extension} ${user} |
修改/etc/postfix/main.cf的配置:
myhostname = mail00.cngnu.org mydomain = cngnu.org myorigin = cngnu.org mydestination = $mydomain,$myhostname
mailbox_transport = cyrus virtual_maps = hash:/etc/postfix/virtual,mysql:/etc/postfix/mysql-virtual.cf
smtpd_sasl_auth_enable = yes smtpd_recipient_restrictions = permit_sasl_authenticated permit_auth_destination reject broken_sasl_auth_clients = yes smtpd_sasl_security_options = noanonymous |
创建/etc/postfix/mysql-virtual.cf,它提供了本地用户和邮件转发功能。forward字段和username字段值默认是相同的,此时邮件本地递交到用户邮箱:username里面;forward是另外一个邮件地址或用户时,邮件转发到新的地址。此外,由于Postfix对于邮箱区别大小写,通过virtual功能的重写,可以保证大小写的邮件地址都可以正确接收。
# # 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' |
http://asg.web.cmu.edu/cyrus/download/
wget ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-imapd-2.0.16.tar.gz
编译Cyrus-IMAP,并取消kerberos支持(在Redhat中,kerberos库有问题,很难编译通过,Mandrake则可以通过;此外,我们也不需要kerberos的支持):
# tar -zxf cyrus-imapd-2.0.16.tar.gz # cd cyrus-imapd-2.0.16
# ./configure --with-cyrus-prefix=/usr/local/cyrus --with-sasl=/usr/local/lib/sasl --without-krb –-with-auth=unix
# make depend # make all CFLAGS=-O # make install |
由于Cyrus-IMAP的主控进程和Postfix的主控进程名字一样,容易混淆而且不方便控制,所以将Cyrus-IMAP服务器的主控进程做个别名连接:cyrusd。
# cd /usr/local/cyrus/bin # ln –s master cyrusd |
Cyrus-IMAP的安装脚本有问题,没有安装cyradm(现在使用的是perl版本,原来的tcl版本不再支持)所需要的perl模块,手工安装:
# cd - # cd perl/imap # make install |
创建主配置文件/etc/cyrus.conf:
# cp master/conf/normal.conf /etc/cyrus.conf |
创建IMAP配置文件/etc/imapd.conf,管理员是cyrus:
configdirectory: /var/imap partition-default: /var/spool/imap admins: cyrus sasl_pwcheck_method: pam |
建立Cyrus-IMAP服务器的目录结构:
# useradd -g mail cyrus
# mkdir –p /var/imap/sieve # mkdir /var/spool/imap
# chown –R cyrus:mail /var/imap # chown –R cyrus:mail /var/spool/imap
# su cyrus $ tools/mkimap $ exit |
创建日志:
# touch /var/log/imapd.log /var/log/auth.log # echo local6.debug /var/log/imapd.log >> /etc/syslogd.conf # echo auth.debug /var/log/auth.log >> /etc/syslogd.conf
# /etc/rc.d/init.d/syslog restart |
设置邮件限额:
# cd /var/imap # chattr +S user quota user/* quota/* # chattr +S /var/spool/imap /var/spool/imap/* |
MySQL在前面配置的时候已经启动。
启动命令如下:
# /etc/init.d/mysqld start |
启动命令如下:
# /usr/sbin/postfix start |
或:
# /etc/rc.d/init.d/sendmail start |
启动命令如下:
# /usr/local/cyrus/bin/cyrusd& |
可以编写一个启动脚本mailsystem来启动这些进程:
#!/bin/bash # author : xingyu.wang <wxy@cngnu.org> 2002/5/19 # Deliver Agent, which provide POP3 and IMAP4 services for user and # deliver mail to local mailbox. # Source function library. # Source networking configuration.
# Check that networking is up. [ -f /usr/sbin/postfix ] || exit 0 [ -f /usr/local/cyrus/bin/cyrusd ] || exit 0
RETVAL=0 start() { echo -n $"Starting $prog: " echo -n $"SMTP " echo -n $"POP3 IMAP4 " /usr/local/cyrus/bin/cyrusd > /dev/null 2&>1 & RETVAL=$?
stop() { /usr/sbin/postfix stop > /dev/null 2&>1 & echo -n $"POP3 IMAP4 " killproc `pidof cyrusd` # See how we were called. exit $RETVAL |
为了清楚起见,以下输入的命令用红色字体标示,系统显示信息用黑色字体标示。
启动MySQL后,首先检查日志/var/log/messages有无错误信息,然后检查进程,应该有如下进程存在:
# pstree | grep safe-mysqld
|-safe-mysqld---safe-mysqld---safe-mysqld
|
接着检查端口,应该有如下端口打开:
# netstat -an | grep LISTEN
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN |
再使用如下命令测试MySQL:
# mysql mail -u mail –p Enter password: (secret) Welcome to the MySQL monitor. Commands end with ; or \g. Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> show tables; +------------------+ | Tables_in_mail | +------------------+ | user | +------------------+1 rows in set (0.00 sec) mysql> select * from user; +----------+----------+----------------------------+--------+ | USERNAME | PASSWORD | FORWARD | STATUS | +----------+----------+----------------------------+--------+ | cyrus | cyrus | cyrus | 1 | +----------+----------+----------------------------+--------+ | tester | testpw | tester | 1 | +----------+----------+----------------------------+--------+ 1 rows in set (0.00 sec) mysql> \q Bye |
启动Postfix后,首先检查日志/var/log/messages有无错误信息,然后检查进程,应该有如下进程存在:检查端口及进程:
# pstree |grep master
|-master-+-pickup
|
接着检查端口,应该有如下端口打开:
# netstat -an |grep LISTEN
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
|
再检测SMTP服务是否正常:
# telnet localhost 25 Trying 127.0.0.1... |
使用如下命令测试postfix的SMTP的认证:
PLAIN认证方式:
# printf ‘tester\0000tester\0000testpw’|mmencode dGVzdGVyAHRlc3RlcgB0ZXN0cHc=
# telnet localhost 25 Trying 127.0.0.1... EHLO cngnu 250-mail00.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 dGVzdGVyAHRlc3RlcgB0ZXN0cHc= 235 Authentication successful QUIT 221 Bye Connection closed by foreign host. |
LOGIN认证方式:
# printf ‘tester’ |mmencode dGVzdGVy # printf ‘testpw’ |mmencode dGVzdHB3
# telnet localhost 25 Trying 127.0.0.1... EHLO cngnu 250-mail00.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 dGVzdGVy 334 UGFzc3dvcmQ6 dGVzdHB3 235 Authentication successful QUIT 221 Bye Connection closed by foreign host. |
启动Cyrus-IMAP后,首先检查日志/var/log/messages、/var/log/imapd.log和/var/log/auth.log有无错误信息,然后检查进程,应该有如下进程存在:
# pstree |grep cyrusd
|-cyrusd
|
接着检查端口,应该有如下端口打开:
# netstat -an |grep LISTEN
tcp 0 0 0.0.0.0:993 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:995 0.0.0.0:* 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
|
再检测POP3和IMAP服务:
# telnet localhost 110 +OK mail00.cngnu.org Cyrus POP3 v2.0.16 server ready USER tester +OK Name is a valid mailbox PASS testpw +OK Maildrop locked and ready QUIT +OK # imtest -m login -a tester localhost
|
现在创建邮箱。使用cyradm来创建邮箱,它是Cyrus-IMAP自己带的交互式管理界面,现在的版本是用Perl写的。你也可以直接调用Cyrus::IMAP::Admin模块创建自己的CGI或脚本来做邮箱管理,可以参考Cyrus::IMAP::Shell模块的程序。
# cyradm -u cyrus localhost IMAP Password: (cyrus) mail00.cngnu.org> cm user.cyrus mail00.cngnu.org> cm user.tester mail00.cngnu.org> lm user.cyrus user.tester mail00.cngnu.org> quit |
创建邮箱后,测试发信功能:
# mail tester Subject: test by me this is a test. . CC: # mailq Mail queue is empty # tail /var/log/mail/*
|
使用mailq来查看邮件队列是否有错误,并查看/var/log/mail/*是否有错误信息。如果一切正常,说明信件已经发送到tester了。
测试收信,先测试POP3:
# telnet localhost 110 +OK mail00.cngnu.org Cyrus POP3 v2.0.16 server ready USER tester +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:
# imtest -m login -a tester localhost . select inbox . fetch 1:1 (FLAGS BODY[HEADER.FIELDS (DATE FROM)]) ) |
你也可以使用任何其它的邮件客户端程序来测试,如kmail、Outlook Express等等。
OK,到此为止,我们的邮件系统就架设完毕了。