Install and configure Postfix with Cyrus-SASL+Cyrus-IMAP+MySQL

12/3/2006来源:Qmail人气:9260

Install and configure Postfix with Cyrus-SASL + Cyrus-IMAP + MySQL v1

*********************************************************************************
作者:独蝎 (LanceLoTest)
Mail: LanceLoTest@hotmail.com
Msn: LanceLoTest@hotmail.com

版权宣告:
这是篇共享的文件,任何人都欢迎转载,请 保持文章的完整性 以及 出处连结
好让后来读这篇 Howto 的人可以寻线找到这篇 Howto 的最新版本,仅供学术用途,谢谢。

这份 Howto 的最新版本,可以由此查阅 (不定期更新)
繁体 Howto: http://doc.uniorg.net/postfix/index.php
简体 Howto http://doc.uniorg.net/postfix/index1.php
UO-小筑 http://www.uniorg.net/viewthread.php?tid=14062
最后更新日期:August 08, 2004
*********************************************************************************


注意事项

在开始之前,请先更新你的 ports
# cd /usr/ports ; make update

颜色与标记
红色:要下的指令
绿色:有两种可能,一为 系统 output 的讯息 ,二为 要增加至档案的内容
黄色:不确定是否可省下的步骤,可以先照做无妨
##:双井号为注解


目键 Table of Contents

适用对象与目标
感谢
记录
前言
简介
安装前的缓身
写这份 Howto 时所使用的软体版本
安装与设定 MySQL
安装与设定 pam_mysql
安装 cyrus-sasl2-saslauthd
用 TLS 来建立 SMTP 和 IMAP 的安全连线
安装与设定 cyrus-imap
安装与设定 postfix
使用 Expect + script + PHP 完成信箱的建立
资源


适用对象与目标

此份 Howto 适用于 FreeBSD 4.x/5.x 的使用者,小弟在此两种版本皆测试过,本 Howto 的目标在建立一个完善的邮件伺服器 (Mail server) 系统,通过 SASL 认证 (authentication) 来收发邮件、TLS 加密连线,和使用 MySQL 做为储存使用者帐号/密码等资料的资料库,以及搭配 PHP 完成一系列的帐号和信箱的建立 (如会员在PHP论坛注册后可立即启用信箱)。


感谢

cdr, 星雨的帮助,好让这篇 Howto 越来越完整


记录

  • June 06, 2004 -- 开始接触 mail server。
  • June - July, 2004 -- 花了一个多月时间在测试 mail server。
  • August 02, 2004 -- 大呼万岁,初步完成设定,并查阅相关资料,为此篇 Howto 做准备。
  • August 03, 2004 -- 开始着手写 Howto,并不断的在 FreeBSD 4.x/5.x 间测试每个步骤(steps)。
  • Augest 06, 2004 -- Howto 大致完成,并学到一个小技巧,用 PHP 搭配 expect 写 script 来实现一贯自动化建立信箱。
  • Augest 07, 2004 -- 持续补充一些观念及说明。在做最后测试的同时发现 ports 里头的 Cyrus-IMAP 版本有更新了,且多了一些新名词及新功能不知什东西来着 @@,也不知新版本如何跟 MySQL 连接,看来又是一场耗劫,所以小弟决定这篇 Howto 就先到此告个段落,待小弟测试完新功能时再行补上。
  • Augest 08, 2004 -- 经过测试,此 Howto 适用于最新版本的 Cyrus-Imap2.2.8。
  • Augest 09, 2004 -- 试着安装与测试 Anti-virus, spam,一装好启动时就有关于 perl module 的问题,没经验过,不知该如何解决,keep trying @@|


前言

这份 Howto 是小弟这一个月半以来,第一次玩 Mail server 的一点私人心得笔记,在过程中,不知有多少个夜晚是泡面和牛奶陪我渡过,到处搜寻相关资料,看遍了 google 及许多 mailing-list 的文件,也有耐心的反反覆覆的安装所有相关软体数十遍,但它不动就是不动。经过一翻的折腾,所有的功能一项项的慢慢正常启动服务了,心里甚是高兴。也许是那不服输的精神感动了老天爷,让小弟的 Mail server 得以服役执勤中,小弟始终深信老天爹是疼憨小孩的 ^_^

有鉴于各软体官网文件的说明不够浅显易懂(也许小弟程度差) 以及网路上的相关资料不够齐全 or 已过时不适用于新版本上,中文的相关资料更是少之又少,于是乎,小弟兴起了写 Howto 的念头,把这一个月半以来花的长时间与精神写份心得分享给大家,好让各位少走一点冤枉路,省去些宝贵时间与精神,在此也感谢软体开发者以及书写文件的前辈们,好让我们这些后生晚辈们有个指引的方向来使用这优秀的 Mail server。

另外,小弟想让这份 Howto 变成一份好的文件资源,但小弟懂得实在不多,菜得很,在此希望众前辈们能多多提供点意见及补充说明,请不吝惜指令,小弟尤衷的敬佩也感激各位点点滴滴的贡献,也希望中文使用者群的水平能越来越高,谢谢。


简介

建构一个完善安全的邮件伺服器系统,需要包含 SMTP, POP3/IMAP, SASL, TLS, Anti-Virus/Spam。

现存有好多种不同的 SMTP server 举凡 Sendmail, QMail, Exim, and Postfix,为何小弟独忠于 Postfix ,选它做为 MTA (Mail Transfer Agent) 呢?小弟查阅了许多国外的讨论区,对 Postfix 评价都是蛮高的,它的速度快、可扩充、有弹性 (flexibility)、模组化 (modular) 以及高安全性 (security),吸引了我,它人性化的设定也挺容易上手。

IMAP server 的部分,比较有名的几套 Courier-IMAP, UW-IMAP, and Cyrus-IMAP,会选择 Cyrus-IMAP 也是因在国外讨论区看了许多的讨论,总观各方的优缺点所做的决定。关于信件储存的方式,Courier-IMAP 使用 MailDir,UW-IMAP 使用 standard, low performance Unix Mailbox style,而 Cyrus 则是使用它自己独立的资料库。Courier-IMAP 和 Cyrus-IMAP 有提供 容量限制 (quotas) 的功能来替代系统中原有的 filesystem quotas,而 filesystem quotas 它不会提醒你容量是否快要满了,当容量满时,filesystem quotas 就立即停止接收新的 mail,另一方面,Cyrus-IMAP 提供的 "soft-quotas" 功能,它会侦察使用了多少空间以及数量,当接近容量限制 (quota) 时,它会亲切的提醒你,要你做好准备。一旦 quota 界满时,它会再次的向 user 发出警告,期间如有 mail 传入,它会退回 (bounced back) 该 mail,并且解释说该使用者信箱已满。这样贴切的功能,让遗失 mail 的机率降为更低。


安装前的缓身

什么是 MTA, MDA, MUA ?
MTA (Mail Transfer Agent) 这服务可帮我们把 mail 传送给其它 mail server ,它也可帮我们接受外部主机寄来的信件,所有的 SMTP servers 都可称为 MTA。

MDA (Mail Delivery Agent) 这服务是用来把 MTA 所接受的 mail 传递 至 使用者 mailbox 的里头,所有的 SMTP servers 也都可称为 MDA,但并非所有的 MDA 都是 SMTP server,举例如 PRocmail 则是个单纯的 MDA。

MUA (Mail User Agent) 就是 mail client 端的软体,它帮我们传送与接受 mail,使用者透过它来跟 mail server 沟通,一般使用者与它有最直接的接触,也是最熟悉的,常见的 MUA 有 Outlook express, Kmail, Mozilla Thunderbird 等,小弟在此推荐使用 Open Source 的 Mozilla-Thunderbird ,它有 for Windows, linux, Mac OS X 等的版本。
Mozilla Thunderbird 官网: http://www.mozilla.org/products/thunderbird/
中文站: http://www.csie.ntu.edu.tw/~r91034/mozilla/

什么是 SMTP ?
SMTP (Simple Mail Transfer Protocol) 简言之是用来发送 mail 的协定,一般使用 port 25。

什么是 POP3 ?
POP3 (Post Office Protocol, Version 3) 简言之是用来接收 mail 的协定,一般使用 port 110。

什么是 IMAP ? 跟 POP3 类似,但功能更强大,一般使用 port 143。

POP3 vs. IMAP
POP3 储存 mail 的方式是把所有的 mails 存于一个 File 里面。而 IMAP 储存 mail 的方式是每封 mail 即是一个档案,这样有个好处是,如果硬碟有某一段坏轨,也不致于损失惨重。

POP3 client 端连线到 POP3 server 端时,会把 mail 下载至本地端的电脑里头,下载完成后,server 即会把这些 刚下载的 mails 给删除,这样一来的缺点是,你只能在这台电脑上阅读你的 mail,如果你是需要到处跑,随时随地要收取 mail 的人,那么 POP3 便不符合你的需求,因为你无法在别台电脑阅读先前下载好的 mails。

IMAP4 储存所有用户的 mails 于 server 中,IMAP client 端连线到 IMAP server 端时,会下载该 mail 的 标头档 (header),如果你想要阅读该封 mail 的内容,你则会从 server 下载备份(copy) 的 mail 至你的本机,然后你便可阅读它了。如果你(client) 删除了某一封 mail,同样的 server 端也会删除此封 mail。由于所有的 mail 都是储存于 server 中,所以你可以在任何异地,经过认证 (authenticate) 后下载/阅读你的 mail。

如果你 or 你的用户经常不固定使用同一台电脑来收取 mail,那么,IMAP 会是比较好的选择。反之,如果你只想要个比较简易的邮件系统,那么选择 POP3 就够了。小弟建议使用 IMAP server,因为它也同样可以提供 POP server 的服务,如此一来,你可以比较有选择性的来设定其功能。


写这份 Howto 时所使用的软体版本

FreeBSD 4.x/5.x
mysql-server-4.0.20 (Cyrus-SASL 尚不支援 MySQL 4.1 版)
cyrus-sasl-2.1.19
cyrus-sasl-saslauthd-2.1.19
cyrus-imapd-2.2.8
db41-4.1.25_1
postfix-2.1.4,1
expect-5.38.0_3

请确认 /etc/services 里头是否有下列的 services,没有的话请自行新增:
smtp 25/tcp
smtp 25/udp
pop3 110/tcp
pop3 110/udp
imap 143/tcp
imap 143/udp
imsp 406/tcp
acap 674/tcp
imaps 993/tcp
pop3s 995/tcp
kpop 1109/tcp
sieve 2000/tcp
lmtp 2003/tcp
fud 4201/udp


安装与设定 MySQL

安装 MySQL 前,变更一下 MySQL 预设的安装路径 (非必要,依个人喜好)
# ee /usr/ports/databases/mysql40-server/Makefile
DB_DIR?= /var/db/mysql
改成 DB_DIR?= /usr/local/mysql

开始安装 MySQL,第一次安装的话需要花比较久的时间,可以趁此时休息一会儿。
# cd /usr/ports/databases/mysql40-server;make install clean

安装完后,如果是第一次安装的话,请执行以下指令来建立储存 MySQL 基本资料的资料库
# /usr/local/bin/mysql_install_db

改变 MySQL 相关目录档案之存取权限
# chown -R mysql:mysql /usr/local/share/mysql ##参数 -R 指说该将目录下所有的档案/目录 owner 改为一样的
# chown -R mysql:mysql /usr/local/mysql
# chmod -R 755 /usr/local/mysql
# chmod 744 /usr/local/share/mysql/mysql.server
# chmod 750 /usr/local/etc/rc.d/mysql-server.sh


启动 mysql
# /usr/local/share/mysql/mysql.server start

登入资料库,如果是第一次登入的话,请直接执行 mysql ,无需密码。
# mysql

设定 MySQL 的 root 权限,设完后,下次登入 MySQL 请用此指令 mysql -u root -p
mysql> SET PASSWord FOR root=PASSWORD('MyPassword');

建立新的 MySQL 使用者,帐号 postfix 密码 secret
mysql> GRANT ALL ON mailbox.* TO postfix@localhost IDENTIFIED BY "secret";

做完以上动作以后,下此指令做即时更新以上新增的资料
mysql> FLUSH PRIVILEGES;

建立新的资料库,命名为 mailbox
mysql> CREATE DATABASE mailbox;

建立 mailbox 此资料库之资料表 user 及栏位 ID,username,password,status
mysql> USE mailbox;
CREATE TABLE user (
ID int(10) unsigned NOT NULL auto_increment,
username varchar(128) NOT NULL default '',
password varchar(40) NOT NULL default '',
status tinyint(4) NOT NULL default '1',
PRIMARY KEY (ID),
UNIQUE KEY username (username)
) TYPE=MyISAM;

新增信箱的使用者,在此我们使用 standard Unix DES-based encryption algorithm 的加密演算法来为我们的密码加密,我们可以使用 PHP 的 function crypt() 来生成我们要加密的密码
# ee /www/crypt.php
$MyPassword = "pass";
echo crypt($MyPassword);
?>

如果你手边没有 PHP 可用,这儿也提供给你 http://doc.uniorg.net/postfix/crypt.php 来生成加密码做测试用。

新增帐号 test 密码 pass, 加密后为 $1$cFT9pmty$ZyZDAy7x0/PJYRKWA8y9f/,我们把它 insert 进资料库
mysql> INSERT INTO user (username,password) VALUES ('test','$1$cFT9pmty$ZyZDAy7x0/PJYRKWA8y9f/');

在此,我们一同新增另个帐号 cyrus 密码 pwd,稍候会用此做为 Cyrus-IMAP 的管理员帐号,加密后的密码为 $1$JjMXx6cp$yN0jNQK8jUZyDbVETVRy5/,同样的把它 insert 进资料库。
mysql> INSERT INTO user (username,password) VALUES ('cyrus','$1$YJioMytK$ChI.ZaAehGbKJnbaAsxm11');


安装与设定 pam_mysql

安装 pam_mysql
# cd /usr/ports/security/pam-mysql;make install clean
这儿有一些 pam_mysql 文件 /usr/local/share/doc/pam_mysql

建立捷径
# ln -s /usr/local/lib/pam_mysql.so /usr/lib/pam_mysql.so

设定 pam
※ for FreeBSD 4.x Users Only! (FreeBSD 5.x 的 user 请看后半段)
接着编辑 ee /etc/pam.conf,如果已经有这个档的话,找到以下两行,在其前面加上 # 注解起来
# imap auth required pam_unix.so try_first_pass
# pop3 auth required pam_unix.so try_first_pass


# echo smtp auth required pam_mysql.so user=postfix passwd=secret \
host=localhost db=mailbox table=user usercolumn=username \
passwdcolumn=password crypt=1 sqllog=0 >> /etc/pam.conf

# echo smtp account sufficient pam_mysql.so user=postfix passwd=secret \
host=localhost db=mailbox table=user usercolumn=username \
passwdcolumn=password crypt=1 sqllog=0 >> /etc/pam.conf

# echo imap auth required pam_mysql.so user=postfix passwd=secret \
host=localhost db=mailbox table=user usercolumn=username \
passwdcolumn=password crypt=1 sqllog=0 >> /etc/pam.conf

# echo imap account sufficient pam_mysql.so user=postfix passwd=secret \
host=localhost db=mailbox table=user usercolumn=username \
passwdcolumn=password crypt=1 sqllog=0 >> /etc/pam.conf

# echo auth sufficient pam_unix.so >> /etc/pam.conf

# echo account sufficient pam_unix.so >> /etc/pam.conf


※ for FreeBSD 5.x Users Only!
# echo auth required pam_mysql.so user=postfix passwd=secret \
host=localhost db=mailbox table=user usercolumn=username \
passwdcolumn=password crypt=1 sqllog=0 >> /etc/pam.d/smtp

# echo account sufficient pam_mysql.so user=postfix passwd=secret \
host=localhost db=mailbox table=user usercolumn=username \
passwdcolumn=password crypt=1 sqllog=0 >> /etc/pam.d/smtp

# echo auth sufficient pam_unix.so >> /etc/pam.d/smtp

# echo account sufficient pam_unix.so >> /etc/pam.d/smtp

# ln -s /etc/pam.d/smtp /etc/pam.d/imap

方才 pam 的设定,其中
※ crypt=0 表示储存的密码为明码,这对人类而言,是易读易懂,但是不安全。
※ crypt=1 表示储存的密码为经由 UNIX系统中的 DES 所编码过的密码,据悉,它这有两种加密方式;一种为普通的 DES 加密方式,也叫 crypt(),加密后的密码有 13 位元长,另一种则为使用 md5 演算法加密的,也叫 md5 crypt(),可说是 DES 的加强版,特点是以 $1$ 为开头,加密后的密码长度不定。
※ crypt=2 表示是用 MySQL 内建的函数 password() 所加密的密码。


安装 cyrus-sasl2-saslauthd

安装 cyrus-sasl2-saslauthd 时,会自动一并安装 cyrus-sasl2
先编辑它的 Makefile
# cd /usr/ports/security/cyrus-sasl2-saslauthd/ ; ee Makefile
在 CONFIGURE_ARGS 这段新增那三个参数
## CONFIGURE_ARGS=
--enable-sql \
--with-mysql=/usr/local/lib/mysql \
--with-dblib=none \

开始安装 Cyrus-sasl2-saslauthd
# make WITH_BDB_VER=41 install clean

设定启动 FreeBSD 时执行 saslauthd,在 /etc/rc.conf 新增此行 saslauthd_enable="YES"

for FreeBSd 4.x Users 要多下此指令
# ln -s /usr/local/lib/sasl2 /usr/lib/sasl2

请认有无此档,并且连结到正确路径
# ls -l /usr/local/lib/sasl2/libsql.so.2
libsql.so.2 -> /usr/local/lib/mysql/libmysqlclient.so.12
如果没有 libsql.so.2 此档,或者连到非以上路径,请下此指令
# ln -s /usr/local/lib/mysql/libmysqlclient.so.12 /usr/local/lib/sasl2/libsql.so.2

启动 saslauth daemon,注意,saslauthd 必需在 IMAP or POSTFIX 前启动
# /usr/local/etc/rc.d/saslauthd.sh start

为了要让 saslauth daemon 支援 PAM,saslauthd 必须随着 -a pam 参数一同启动,检验看看
# ps ax|grep sasl
10174 ?? Is 0:00.10 /usr/local/sbin/saslauthd -a pam ##后面有 -a pam

每做一个动作后,请查看 log 有无什么错误讯息,用 tail 指令,只会列出最后的几行
# tail /var/log/maillog
# tail /var/log/messages


用 TLS 来建立 SMTP 和 IMAP 的安全连线

在你设置 TLS 安全连线之前,你必须先建立自己的认证码 (certificates)。为了要更深入了解 一读由 O'Reilly 出版,John Viega, Matt Messier, Pravir Chandra 所著作得书 "Network Security with OpenSSL"。但如果你尚抽不出时间的话,你可以用以下的方式来快速的建立你的 CA (Certificate Authority)。
# mkdir /ca
# chown root:wheel /ca
# chmod 0700 /ca
# cd /ca

Create Your Own Certificate Authority
Note: when asked for Common Name (e.g., YOUR name) you have to provide server name, or the request will be useless. Do not enter yours (administrator) name you can create client p12 certificate with openssl pkcs12 -export command

建立你私人的 CA key (请记得你的密码!):
# openssl genrsa -des3 -out /ca/ca.key 1024
Enter pass phrase for /ca/ca.key: password ##在此输入你想要的密码(六码以上)

Create CA certificate (ca.crt) and sign it with the CA's private key (ca.key)
# openssl req -new -x509 -days 365 -key /ca/ca.key -out /ca/ca.crt
Enter pass phrase for /ca/ca.key: password ##输入 CA key 的密码
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----

Country Name (2 letter code) [AU]: TW ##二字母国家代码
State or Province Name (full name) [Some-State]: Taiwan
Locality Name (eg, city) []: Taipei

Organization Name (eg, company) [Internet Widgits Pty Ltd]: UO ##公司名称
Organizational Unit Name (eg, section) []: UO
Common Name (eg, YOUR name) []: mydomain.net ##这儿一定要输入 server name/domain name
Email Address []: mymail@hotmail.com

Create an unsigned certificate (this is for SSL enabling your service)
Create a certificate (server.pem) and a certificate signing request or CSR (req.pem).
# openssl req -new -nodes -out /tmp/req.pem -keyout /ca/server.pem
Country Name (2 letter code) [AU]: TW
State or Province Name (full name) [Some-State]: Taiwan
Locality Name (eg, city) []: Taipei
Organization Name (eg, company) [Internet Widgits Pty Ltd]: UO
Organizational Unit Name (eg, section) []: UO
Common Name (eg, YOUR name) []: mydomain.net
Email Address []: mymail@hotmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: password ##输入个较复杂的密码,不易被破解的
An optional company name [] ##这可以空着不填

Important:
-nodes option means that your key is sitting unencrypted on your hard disk. That may pose some security risk.

Sign Your Certificate With Your CA's Key
Using your CA's private key (ca.key) and certificate (ca.crt) sign the CSR (req.pem) and create a signed certificate (signed_req.pem)
# cp /tmp/req.pem /ca
# openssl x509 -req -CA /ca/ca.crt -CAkey /ca/ca.key -days 365 -in req.pem -out signed_req.pem -CAcreateserial

Concatenate the signed request with certificate to produce a certificate that can be loaded into your web/mail server
# cat signed_req.pem >> /ca/server.pem

View the fingerprint of a certificate
# cp /usr/src/crypto/openssl/apps/cert.pem /ca
# openssl x509 -subject -dates -fingerprint -in cert.pem

The short can look as follows:
# openssl req -new -nodes -out req.pem -keyout key.pem
Country Name (2 letter code) [AU]: TW
State or Province Name (full name) [Some-State]: Taiwan
Locality Name (eg, city) []: Taipei
Organization Name (eg, company) [Internet Widgits Pty Ltd]: UO
Organizational Unit Name (eg, section) []: UO
Common Name (eg, YOUR name) []: mydomain.net
Email Address []: mymail@hotmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: password ##输入个较复杂的密码,不易被破解的
An optional company name [] ##这可以空着不填

# openssl rsa -in key.pem -out server.pem
# openssl x509 -in req.pem -out ca-cert -req -signkey server.pem -days 999
# cat ca-cert >> server.pem


安装与设定 cyrus-imap

安装任何版本的 cyrus 时,预设会自动安装 db3,如果你选择了 db4.x,安装结果将会是 db3 和 db4.x 皆会安装于你的系统中。有两种版本的 Berkeley db 同时存在时,cyrus-sasl 的认证功能将会无法正常使用。基于这个原因,你必须手动的来更改所要使用的 Berkeley db 版本。

这里我们使用 Berkeley db41:
编辑 cyrus-imapd22 的 Makefile 档
# cd /usr/ports/mail/cyrus-imapd22;ee Makefile
找到此段
.if defined(WITH_BDB_VER)
USE_BDB_VER= ${WITH_BDB_VER}
.else
USE_BDB_VER= 3
把 USE_BDB_VER= 3 改成 USE_BDB_VER= 41

安装 Cyrus-IMAP
# cd /usr/ports/mail/cyrus-imapd22 ; make install clean

设定启动 FreeBSD 执行 imapd,在 /etc/rc.conf 新增此行 cyrus_imapd_enable="YES"

把 postfix 加入 cyrus 群组
# pw groupmod cyrus -m postfix

检验 cyrus 群组的使用者有哪些
# pw groupshow cyrus
cyrus:*:60:postfix

建立 cyrus-imapd 所需的目录
# /usr/local/cyrus/bin/mkimap
# mkdir /var/adm
# touch /var/adm/imapd.log /var/adm/auth.log

# touch /var/imap/annotations.db ; chown cyrus:cyrus /var/imap/annotations.db
# chmod 750 /var/imap
# chmod 750 /var/spool/imap

启动 cyrus-imap
# /usr/local/etc/rc.d/imapd.sh start

每做一个动作后,请查看 log 有无什么错误讯息,用 tail 指令,只会列出最后的几行
# tail /var/log/maillog
# tail /var/log/messages

测试 cyrus-imap 是否能正常运作
# telnet localhost imap
Trying ::1...
Connected to localhost.
Escape character is '^]'.
* OK examples.net Cyrus IMAP4 v2.2.8 server ready ##此行一定要有

. logout##要登出请输入 . logout,[点 . 后面有空白]
如有看到类似以上的讯息,恭喜你,你的 cyrus-imap 正常运作中

每做一个动作后,请查看 log 有无什么错误讯息,用 tail 指令,只会列出最后的几行
# tail /var/log/maillog
# tail /var/log/messages

建立使用者信箱所需之目录
# mkdir /var/imap/user
# cd /var/imap/user
# mkdir a b c d e f g h i j k l m n o p q r s t u v w x y z
# chown -R cyrus:cyrus /var/imap/user

设定 cyrus-imap,编辑 imapd.conf
# ee /usr/local/etc/imapd.conf
configdirectory: /var/imap
partition-default: /var/spool/imap
##是否允许匿名登入;认证后才登入是个好主意,请把它设为 no
allowanonymouslogin: no
##是否允许使用明码;安全因素考量,用加密过后的比较妥,请把它设为 no,不知为何 Cyrus-Imapd 2.2.8 把这设为 no 会有错误,所以先把它 # 注解起来
#allowplaintext: no
##限定的信箱容量达多少百分比 (%) 时,系统发出警告
quotawarn: 90
##设置 cyrus server 的管理员为 cyrus
admins: cyrus
##预设的信箱容量 (kilobytes)
autocreatequota: 10000
singleinstancestore: yes
duplicatesuppression: yes
##设为 no 才不会把不是 8-bit 的 characters 给 reject 掉
reject8bit: no
##每封 mail 大小的最大值 (bytes)
maxmessagesize: 7000
sieveusehomedir: false
sievedir: /var/imap/sieve
sasl_minimum_layer: 0
sasl_pwcheck_method: saslauthd
#sasl_auto_transition: no
##此选项列出允许的 mechanisms/authentication methods
sasl_mech_list: plain login cram-md5 digest-md5
tls_cert_file: /var/imap/server.pem
tls_key_file: /var/imap/server.pem
tls_ca_file: /usr/local/etc/postfix/server.pem
lmtp_over_quota_perm_failure: no
lmtp_allowplaintext: no
#tls_cipher_list: TLSv1:SSLv3:!DES:!HIGH:@STRENGTH
tls_cipher_list: ALL:!ADH:RC4+RSA:+SSLv2:@STRENGTH

# SQL info 这些设定目前还用不到
#sasl_auxprop_plugin: sql
#sasl_sql_engine: mysql
#sasl_sql_hostnames: localhost
#sasl_sql_user: postfix
#sasl_sql_passwd: secret
#sasl_sql_database: mailbox
#sasl_sql_statement: select password from user where username = '%u'
#sasl_sql_verbose: true

由于 imapd.conf 有设置启动 TLS 安全连线,所以请复制之前建立好的 certificate (server.pem)
# cp /ca/server.pem /var/imap/server.pem
# chown cyrus:mail /var/imap/server.pem
# chmod 600 /var/imap/server.pem

设定完后,执行以下指令来重新启动 cyrus-imap
# /usr/local/etc/rc.d/imapd.sh restart

每做一个动作后,请查看 log 有无什么错误讯息,用 tail 指令,只会列出最后的几行
# tail /var/log/maillog
# tail /var/log/messages

使用 imtest 此工具来测试 Cyrus-IMAP 的认证是否有正常运作,参数 -a 后接使用者名
# imtest -m login -a test -p imap localhost
S: * OK mydomain.net Cyrus IMAP4 v2.2.8 server ready
C: C01 CAPABILITY
S: * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS NAMESPACE UIDPLUS ID NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND BINARY SORT THREAD=ORDEREDSUBJECT THREAD=REFERENCES ANNOTATEMORE IDLE STARTTLS
S: C01 OK Completed

Please enter your password: pass ##在此输入密码
C: L01 LOGIN star {4}
S: + go ahead
C:
S: L01 OK User logged in
Authenticated.
Security strength factor: 0

. logout ##(要登出请输入 . logout,[点 . 后面有空白])
* BYE LOGOUT received
. OK Completed
Connection closed.


每做一个动作后,请查看 log 有无什么错误讯息,用 tail 指令,只会列出最后的几行
# tail /var/log/maillog
# tail /var/log/messages

再次测试 Cyrus-IMAP,参数 -a 后接使用者名
# imtest -t "" -a test localhost
S: * OK mydomain.net Cyrus IMAP4 v2.2.8 server ready
C: C01 CAPABILITY
S: * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS NAMESPACE U
IDPLUS ID NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND BINARY SORT THREAD=ORDE
REDSUBJECT THREAD=REFERENCES ANNOTATEMORE IDLE STARTTLS
S: C01 OK Completed
C: S01 STARTTLS
S: S01 OK Begin TLS negotiation now
verify error:num=18:self signed certificate
TLS connection established: TLSv1 with cipher AES256-SHA (256/256 bits) ## TLS 安全连线已建立
C: C01 CAPABILITY
S: * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS NAMESPACE U
IDPLUS ID NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND BINARY SORT THREAD=ORDE
REDSUBJECT THREAD=REFERENCES ANNOTATEMORE IDLE AUTH=LOGIN AUTH=PLAIN SASL-IR
S: C01 OK Completed
C: A01 AUTHENTICATE LOGIN
S: + VXNlcm5hbWU6

Please enter your password: testpw ##输入你的密码
C: c3Rhcg==
S: + UGFzc3dvcmQ6
C: c3Rhcg==
S: A01 OK Success (tls protection) ##在 TLS 安全连线之下成功登入
Authenticated.
Security strength factor: 256 ##这儿应为 256

. logout ##(要登出请输入 . logout,[点 . 后面有空白])
* BYE LOGOUT received
. OK Completed
Connection closed.


每做一个动作后,请查看 log 有无什么错误讯息,用 tail 指令,只会列出最后的几行
# tail /var/log/maillog
# tail /var/log/messages

cyradm 是在安装 Cyrus-IMAP 时一同安装上的附属工具,主要功能是建立及管理信箱,我们在此使用 cyradm 此工具来建立使用者信箱
# cyradm localhost --user cyrus ##参数 --user 后面接管理员帐号 (在 imapd.conf 里设置的 admins: cyrus)
IMAP Password: cyrus ##输入 IMAP 管理员的密码

使用 cyradm 的指令 cm (Create mailbox) 建立一个叫 test 的信箱
localhost> cm user.test

使用 cyradm 的指令 lm (List mailbox) 列表信箱。
localhost> lm

如果你的 /usr/local/etc/imapd.conf 里头有设 autocreatequota: 10000 此参数的话,那么预设的信箱容量为 10MB,如你想要为这信箱特别设个不同的容量,可以经由使用 cyradm 的指令 setquota 来设置信箱容量。
localhost> setquota user.test 10000

如果想要删除信箱的话,必须先设定管理员对该 mailbox 有 all 权限
localhost> setaclmailbox user.test cyrus all ##管理员 cyrus 对 信箱 test 有 all 权限

使用 cyradm 的指令 dm (Delete mailbox) 删除信箱
localhost> dm user.test

查看更多 cyradm 相关指令
localhost> help

登出 cyradm
localhost> quit

建立完信箱以后可以下此指令看到新建的使用者信箱。
# ll /var/spool/imap/user


安装与设定 postfix

# cd /usr/ports/mail/postfix ; make install clean ; rehash
选择这些选项
[X] SASL
[X] TLS
[X] DB41
[X] MySQL

开始安装中,需要一些时间,可以趁此时休息一下

接着会问个问题,回答 y
Would you like to activate Postfix in /etc/mail/mailer.conf [n]? y

安装完后的提示讯息,请跟着讯息指示来做
Also, you will want to disable some Sendmail-specific daily maintenance
routines in your /etc/periodic.conf file:
编辑 periodic.conf,并把原有的选项改成下列
# ee /etc/periodic.conf
daily_clean_hoststat_enable="NO"
daily_status_mail_rejects_enable="NO"
daily_status_include_submit_mailq="NO"
daily_submit_queuerun="NO"

安装完后执行
# /usr/local/sbin/postalias /etc/aliases
# /usr/local/sbin/postmap /usr/local/etc/postfix/transport

设置开机时启动 postfix,新建一个捷径
# ln -s /usr/local/sbin/postfix /usr/local/etc/rc.d/postfix.sh

编辑 smtpd.conf
# ee /usr/local/lib/sasl2/smtpd.conf
pwcheck_method: saslauthd
mech_list: plain login cram-md5 digest-md5
## 以下选项还用不到
#log_level: 3
#auxprop_plugin: sql
#sql_engine: mysql
#sql_hostnames: localhost
#sql_user: postfix
#sql_passwd: secret
#sql_database: mailbox
#sql_select: select password from user where username='%u'
#sql_verbose: true


设定 Postfix,它有两个主要的设定档 main.cfmaster.cf
编辑 master.cf
# ee /usr/local/etc/postfix/master.cf
ctrl + y 搜寻此字串 /cyrus/bin/deliver 找到后,改为 /usr/local/cyrus/bin/deliver
接着按 ctrl + x 继续搜寻刚刚的字串,找到后,同样改为 /usr/local/cyrus/bin/deliver

编辑 main.cf
# ee /usr/local/etc/postfix/main.cf
soft_bounce = no
queue_directory = /var/spool/postfix
command_directory = /usr/local/sbin
daemon_directory = /usr/local/libexec/postfix
mail_owner = postfix
default_privs = nobody
## 本机的 hostname
myhostname = mail.mydomain.net
## 本机的 domain
mydomain = mydomain.net
myorigin = $myhostname
myorigin = $mydomain
##postfix 收信的网卡IP
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
local_recipient_maps =
unknown_local_recipient_reject_code = 550
relay_domains = $mydestination
mailbox_transport = lmtp:unix:/var/imap/socket/lmtp
luser_relay = $local@other.host
smtpd_banner = $myhostname ESMTP $mail_name
debug_peer_level = 2
debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
xxgdb $daemon_directory/$process_name $process_id %26amp; sleep 5
sendmail_path = /usr/local/sbin/sendmail
newaliases_path = /usr/local/bin/newaliases
mailq_path = /usr/local/bin/mailq
setgid_group = maildrop
html_directory = no
manpage_directory = /usr/local/man
sample_directory = /usr/local/etc/postfix
readme_directory = no

##设置启动 SASL 寄件登入认证##
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
#smtp_sasl_password_maps = hash:/usr/local/etc/postfix/smtp_sasl_pass
#smtp_sasl_password_maps = mysql:/etc/postfix/mysql_auth.conf
#smtpd_sasl_local_domain = $mydomain
smtpd_sasl_local_domain =

##设置启动 TLS 安全连线##
##启用 TLS
smtpd_use_tls = yes
##只有在 user 使用 TLS安全连线时,postfix 才会执行 smtp auth command

smtpd_tls_auth_only = yes
smtpd_tls_loglevel = 3
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 600s
smtpd_tls_cert_file = /usr/local/etc/postfix/server.pem
smtpd_tls_key_file = $smtpd_tls_cert_file
smtpd_tls_dcert_file = /usr/local/etc/postfix/server.pem
smtpd_tls_dkey_file = $smtpd_tls_dcert_file
#smtpd_tls_CApath = /usr/local/etc/postfix

##检查寄件人的 email address 与 domain##smtpd_sender_restrictions = 	permit_mynetworks	permit_sasl_authenticated	reject_non_fqdn_sender	reject_unknown_sender_domain	# check_sender_access hash:/usr/local/etc/postfix/access	# check_client_access hash:/usr/local/etc/postfix/network_table	# check_relay_domains	# warn_if_reject

##检查收件人的 email 与 domain##smtpd_recipient_restrictions = 	permit_mynetworks	permit_sasl_authenticated	permit_auth_destination	permit_mx_backup	check_relay_domains	reject_unknown_recipient_domain	reject_non_fqdn_recipient	reject_unauth_destination	reject

##检查SMTP连线来源IP (包括 用户端Outlook 与 邮件主机Sendmail 等等)##smtpd_client_restrictions = 	permit_mynetworks	permit_sasl_authenticated	reject_unauth_pipelining	reject_unknown_client	# check_client_access hash:/usr/local/etc/postfix/access	# check_client_access regexp:/usr/local/etc/postfix/access_regexp	# reject_rbl_client relays.osirusoft.com	# reject_rbl_client relays.ordb.org	# check_client_access hash:/usr/local/etc/postfix/network_table	# check_relay_domains

详情,请 man smtpd

由于 main.cf 有设置启动 TLS 安全连线,所以请复制之前建立好的 certificate (server.pem)
# cp /ca/server.pem /usr/local/etc/postfix/server.pem
# chmod 600 /usr/local/etc/postfix/server.pem
# chown cyrus:mail /usr/local/etc/postfix/server.pem

启动 Postfix
# /usr/local/etc/rc.d/postfix.sh start

每次设完 main.cf, master.cf, smtpd.cf 时都要记得下此指令来重新启动 postfix
# postfix reload

用此指令列出 Postfix 所支援的 lookup table types,详请 man postconf
# postconf -m

用此指令列出目前所有在 main.cf available 的设定
# postconf -n

测试 postfix
# telnet localhost 25
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.mydomain.net ESMTP Postfix

ehlo mydomain.net ##输入此指令
250-mail.mydomain.net
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS ##确定有无此行,表示 TLS 运作中
250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5 ##列出允许的 mechanisms/authentication methods
250-AUTH=PLAIN LOGIN DIGEST-MD5 CRAM-MD5 ##如果 smtpd_tls_auth_only = yes 有设的话,这两行 250-AUTH PLAIN.... 会不见
250 8BITMIME ##接着,底下我们尝试在本机寄信
mail from:test@mail.mydomain.net ## mail from:寄件人
250 Ok
rcpt to:others@hotmail.com ## rcpt to:收件人
250 Ok
data ##输入此指令,代表要开始写 mail 的内容
354 End data with .
hi,,this is a test mail ##这里是 mail 的内容
. ##输入一个点,表示结束书写这封 mail,并传出 mail
250 Ok: queued as 141B3115D7
quit ##登出
221 Bye


查看 log 记录
# cat /var/log/maillog
postfix/smtp to=, relay=mx3.hotmail.com, delay=14, status=sent ## status=sent;成功寄出

检查看有哪些 Mail 没有 sent 出去
# mailq
Mail queue is empty ## empty 没有待发邮件。如不是看到此讯息,可稍等一下,有时会 delay 一下

删除传不出去的 Mail by Queue_ID
# postsuper -d Queue_ID

也可以一次全部删除传不出去的 mail
# postsuper -d ALL


使用 Expect + script + PHP 完成信箱的建立 使用 expect 来实现自动化建立信箱,expect 是用 script 来跟其它的 interactive programs 沟通用的软体 expect 相关资源

安装 expect
# cd /usr/ports/lang/expect/
# make install clean

写个 script 来和 PHP 搭配建立信箱
# ee /tmp/shCyradm.sh
script 内容如下
#!/usr/local/bin/expect
spawn cyradm localhost --user [lindex $argv 0]
set adminpass [lindex $argv 1]
set adduser [lindex $argv 2]
expect "adminpass:"
send "$adminpass\r"
send "cm user.$adduser\r"
send "lm\r"
send "quit\r"
expect eof


存档后离开,并执行 shCyradm.sh (执行后请稍过几秒钟不要动它,expect 会自动为我们输入)
# /tmp/shCyradm.sh cyrus pwd username ##参数说明,参数 1. cyrus 为我们之前在 imapd.conf 设定的 admins: cyrus 为管理员 参数 2. pwd 是我们之前为 cyrus 建立在 MySQL 里头的密码 参数 3. username 是想要建立的信箱帐号
spawn cyradm localhost --user cyrus
IMAP Password:
localhost> cm user.imlala
localhost> lm
user.username (\HasNoChildren)
##可以看到信箱已建立
更详细的用法,请 man expect

PHP 搭配 expect 自动建立信箱的简单范例
if ($_POST['action']=="ok" %26amp;%26amp; $_POST['adduser']!=""){
echo "Start creating mailbox for $_POST[adduser] , please wait...";
##底下这行的 /www/test/postfix/shCyradm.sh 请改为你的 shCyradm.sh 所在路径,
## 第一个参数 cyrus 为管理员,第二个参数 pwd 为密码,log_cyradm.txt 可查看讯息记录
$cmd = "/www/test/postfix/shCyradm.sh cyrus pwd $_POST[adduser] >> log_cyradm.txt";
exec($cmd);
echo "Done...
";
echo "返回";
exit;
}
?>



建立信箱需等待约十秒
输入欲建立信箱之帐号:





资源

官网网址/文件
Postfix 官网文件
Cyrus-SASL and Cyrus-IMAP
MySQL

相关 Howto
For FreeBSD User 的 Howto,cdr 写得 Howto,写得不错,作者也蛮亲切的,小弟有部分 Howto 也是跟着这的
Howto install postfix-cyrus-openldap-sa-amavisd with enabled SSL/TLS ver 2
For FreeBSD User 的 Howto,有不错的参考价值,其中的解释让小弟认知不少
Postfix + Cyrus-SASL + Cyrus-IMAPD + PgSQL HOWTO
For FreeBSD User 的 Howto,教你一步一步怎么做
安装 postfix 傻瓜篇
For FreeBSD User 的 Howto
Postfix-Cyrus-MySQL-replex-SquirrelMail
For Linux User 的 Howto,有不错的参考价值,其中的解释让小弟认知不少
Postfix + Cyrus-IMAP + Cyrus-SASL + MySQL + IMP 完全指南
For Linux User 的 Howto,还有特别介绍 Web-Cyradm
Postfix-Cyrus-Web-cyradm-HOWTO
For Linux User 的 Howto,英文
Postfix SMTP AUTH (and TLS) HOWTO
For Debian User 的 Howto,有不错的参考价值,其中的解释让小弟认知不少
Tutorial: ISP-style Email Service with Debian-Sarge and Postfix (2.x)

讨论文章
不错的讨论文
www.bsdforum.org
www.bsdforum.org

有关 expect 的网站
expect 官网
ftp下载
怎在一个 shell script 中或在背景执行 'ftp'、'telnet'等程序呢?
expect 范例教学

其它尚未归类
IMAP transfers from one mailbox to another

,