Postfix+Dovecot+Roundcube+MySQL架设完整Webmail系统

最近在原先postfix smtp的基础上进行改造,架设了个完整的Webmail/SSL的邮件系统。

软件使用的是Postfix 2.8.3 + Dovecot 2.0.13 + Roundcube 0.5作为邮件系统,PostfixAdmin 2.1.0作为后台管理,MySQL 5.5.12作为数据库系统,所有软件均通过源码编译安装。

===========================================

  1. 软件安装

===========================================

Postfix:http://www.postfix.org/download.html

本例中Postfix使用Dovecot作为SASL的验证,所以不需要再安装Cyrus-SASL了。因为有用到MySQL的库文件,所以编译之前需要把 /usr/local/mysql/lib加到/etc/ld.so.conf里面,ldconfig刷新缓存,否则postfix make install的时候会提示找不到mysql的库文件。

makefile设置以支持dovecot,mysql和ssl:

make makefiles 'CCARGS=-DHAS_MYSQL -I/usr/local/mysql/include -DUSE_TLS -DUSE_SASL_AUTH -DDEF_SERVER_SASL_TYPE="dovecot"' 'AUXLIBS=-L/usr/local/mysql/lib -lmysqlclient -lz -lm -lssl -lcrypto'

然后是常规的

make && make install

Dovecot:http://www.dovecot.org/download.html

Dovecot是一个开源的POP3/IMAP服务器软件,开发时就是以安全性作为重点之一考虑的,同时更新快速,与Cyrus IMAP相比效率与安全性都更高,缺点是相应的文档更新较慢,而且应用不如Cyrus广。

Dovecot的编译参数很简单,我用以下的命令编译安装:

./configure --with-mysql --with-zlib --with-ssl && make && make install

安装完之后把源码目录里面的doc/example-config里面的所有配置文件拷到/usr/local/etc/dovecotdovecot-initd.sh拷到/etc/init.d/dovecot

Roundcube

Roundcube是一个以PHP编写的网页邮件客户端。由于使用了Ajax,Roundcube的UI做得很漂亮,而且功能也很全面,比起之前使用的Squirrelmail功能上强过不少。(SquirrelMail的UI实在是太丑了)

由于使用了PHP,Roundcube要求PHP本身必须支持IMAP。PHP的IMAP支持是通过U of Washington的IMAP客户端实现的,如果使用二进制包安装的话可以直接安装php5-imap,否则的话按以下步骤编译安装PHP:

首先下载IMAP客户端:ftp://ftp.cac.washington.edu/imap/imap-2007e.tar.gz

这个已经很久没有更新了,最新的版本就是2007e。下载下来解压,make slx SSLINCLUDE=/usr/include/openssl/编译。

编译完之后执行以下命令:

cp c-client/c-client.a /usr/local/lib/libc-client.a
cp c-client/\*.h /usr/local/include/

然后重新编译php,加上--with-imap参数。

Roundcube的安装要在Postfix和Dovecot都安装成功之后进行。

===========================================

  1. 系统准备+数据库配置

===========================================

由于使用的是虚拟邮件帐户形式(即邮箱用户非Linux系统上实际存在的用户,而是存在于数据库中以提高系统安全性),需要创建对应的虚拟邮件帐户。

useradd -r -d /var/vmail -s /sbin/nologin -c "Virtual Mailbox" vmail
mkdir /var/vmail
chown -R vmail:vmail /var/vmail

然后建数据库,使用Postfixadmin的最新版本(我用的是2.3.4)。

PostfixAdmin有写好了的Schema,我稍微做了下修改导入数据库。修改DATABASE_MYSQL.TXT:

我删除了postfixadmin的部分,同时根据需要修改Postfix数据库的密码,最后把语句中所有的engine=MyISAM删掉,然后导入数据库:

mysql -uroot -p \< DATABASE_MYSQL.TXT

然后修改下config.inc.php,把domain_in_path设置为YES,domain_in_name设成NO。

最后用postfixadmin建立个邮件帐户,记下用户名和密码。

这里有一个问题,Postfixadmin在以上设置的情况下,记录的Maildir并不是username/,而是domain/username/,这样会造成Roundcube的访问混乱。我的做法是在数据库里面手动改回username/,这样邮件存放的目录就是/var/vmail/domain/username了,如有更好的方法望不吝告知,谢谢。

===========================================

  1. Postfix、Dovecot设置

===========================================

在进行此步前请确认Postfix可以正常地发邮件,参考/2010/12/470,确认成功了再进行下一步。

接下来修改/etc/postfix/main.cf,在文件最后加上以下段落:

# Virtual mailbox settings.
virtual_mailbox_base = /var/vmail
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_uid_maps = static:xxx
virtual_gid_maps = static:xxx
virtual_transport = virtual
message_size_limit = 10240000
virtual_mailbox_limit = 209715200
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_virtual_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, the user's maildir has exceeded the quota.
virtual_overquota_bounce = yes
# SASL settings
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $mydomain
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_invalid_hostname, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient
# TLS settings
smtpd_tls_cert_file = /etc/postfix/mysite.crt
smtpd_tls_key_file = /etc/postfix/mysite.key
smtpd_tls_security_level = may
smtp_skip_4xx_greeting = yes
smtp_skip_5xx_greeting = yes

virtual_uid_mapsvirtual_gid_maps改成vmail用户的uid和gid。注意myhostnamemydestination的值不能一样,否则postfix收不到邮件。

其中TLS的设置非必需,如果不打算使用TLS的话可以删掉。使用TLS的情况下,如果想在公网上接收邮件,根据RFC2487smtpd_tls_security_level必须设置为may,不能是encrypt,否则无法收取来自其他MTA的邮件(log里面会有Must issue a STARTTLS command first的错误消息)。

然后修改/etc/postfix/master.cf,取消-o smtpd_tls_security_level=may-o smtpd_sasl_auth_enable=yes前面的注释,同时取消smtps及下面两行的注释(-o smtpd_tls_wrappermode=yes-o smtpd_sasl_auth_enable=yes)以开启465端口的SSL支持。465端口主要是为了Outlook的支持,因为Outlook 对25端口上的STARTTLS支持不好。

最后添加Postfix对于MySQL的查询命令:

/etc/postfix/mysql_virtual_alias_maps.cf

user = postfix
password = yourpostfixpassword
hosts = localhost
dbname = postfix
table = alias
select_field = goto
where_field = address
additional_conditions = and active = '1'
#query = SELECT goto FROM alias WHERE address='%s' AND active = '1'

/etc/postfix/mysql_virtual_domains_maps.cf

user = postfix
password = yourpostfixpassword
hosts = localhost
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and active = '1'
#query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'

/etc/postfix/mysql_virtual_mailbox_limit_maps.cf

user = postfix
password = yourpostfixpassword
hosts = localhost
dbname = postfix
table = mailbox
select_field = quota
where_field = username
additional_conditions = and active = '1'
#query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1'

/etc/postfix/mysql_virtual_mailbox_maps.cf

user = postfix
password = yourpostfixpassword
hosts = localhost
dbname = postfix
table = mailbox
select_field = CONCAT(domain,'/',maildir)
where_field = username
additional_conditions = and active = '1'
#query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1'

至此Postfix的配置就算完成了,接下来修改Dovecot配置。

首先修改/usr/local/etc/dovecot/dovecot.conf,在protocols里修改支持的邮箱协议,我只开放了imap。

然后修改dovecot-sql.conf.ext,修改以下字段:

driver=mysql
connect = host=localhost dbname=postfix user=postfix password=yourpostfixpassword
password_query = SELECT username as user, password, '/var/vmail/%d/%n' as userdb_home, 'maildir:/var/vmail/%d/%n' as userdb_mail, xxx AS userdb_uid, xxx AS userdb_gid
FROM mailbox WHERE username = '%u' AND active = '1'
user_query = SELECT '/var/vmail/%d/%n' as home, 'maildir:/var/vmail/%d/%n' as mail, xxx AS uid, xxx AS gid, concat('dirsize:storage=', quota) AS quota
FROM mailbox WHERE username = '%u' AND active = '1'

uid和gid按vmail的修改。

接下来修改conf.d/10-auth.conf

auth_username_translation =/@@
auth_mechanisms = plain login

去掉!include auth-sql.conf.ext前面的#注释。

然后是10-mail.conf

mail_location = maildir:/var/vmail/%d/%n

接下来是10-master.conf

去掉imap端口前的注释,如果希望imap只监听993(imaps)的话把imap的port从143改成0,这样dovecot就不会监听143端口了。

unix_listener /var/spool/postfix/private/auth里面把usergroup都改成postfix,mode改为660。

10-ssl.conf取决于是否使用TLS,如果没有的话一定要把ssl=yes改成ssl=no,并注释掉ssl_cert和ssl_key。

最后修改auth-sql.conf.ext,passdb和userdb都这样改:

driver=sql
args = /usr/local/etc/dovecot/dovecot-sql.conf.ext

到此dovecot的配置应该完成了,

/etc/init.d/postfix restart && /etc/init.d/dovecot restart

可以用mail跟自己发封信测试下。

===========================================

  1. Roundcube安装/设置

===========================================

Roundcube:http://roundcube.net/download

下载后解压按说明安装,imap和smtp测试时用户名使用完整邮箱,否则测试通不过。

Roundcube的配置界面很直观,不做更多介绍了。有两个插件需要装上,修改config/main.inc.php,找到plugins那行,在括号中加入'markasjunk', 'password'以启用标记垃圾邮件和修改密码的插件。

markasjunk需要一个垃圾邮件的文件夹,这个很好设置。password需要修改配置文件,否则无法使用。

修改password里面的config.inc.php$rcmail_config['password_db_dsn'] 修改成连接数据库的方式,例如:

mysqli://postfix:yourpostfixpassword@unix(/tmp/mysql.sock)/postfix

如果在密码中有特殊字符(比如@)的话需要转换成转义字符。格式:%xx,xx是字符的Hex值。

然后修改:

$rcmail_config['password_query'] = 'UPDATE `mailbox` SET `password` = %c, modified=now() WHERE `username` = %u LIMIT 1';

这样应该就可以了。

测试下用Roundcube发送接收邮件是否正常,没有问题的话最后修改iptables,加入相应的防火墙规则。

PS:Roundcube的汉化不是很完全,个人渣翻译了下主程序,Mark as junk和Password,有需要的可以下载,下载后解压到roundcube根目录就可以使用了。地址:/assets/files/2011/05/trans.rar

本文参考了以下资源:

http://johnny.chadda.se/article/mail-server-howto-postfix-and-dovecot-with-mysql-and-tlsssl-postgrey-and-dspam/

http://www.php.net/manual/en/imap.requirements.php

http://www.linuxquestions.org/questions/linux-software-2/compiling-php-with-imap-and-imap-ssl-546986/

http://www.postfix.org/TLS_README.html