整理一下杂七杂八的postfix+extmail的mail服务器架设维护笔记

前提: 做好DNS的A记录,MX(Mail Exchange mail交换记录)
如:upkiller.com 192.168.1.123
    mx=mail.upkiller.com
    mail.upkiller.com=192.168.1.123
检查:
nslookup upkiller.com
nslookup -type=MX upkiller.com
输出结果:
upkiller.com       MX preference = 1, mail exchanger = mail.upkiller.com
mail.upkiller.com internet address = 192.168.1.123
mail server的备份:可以设置多个邮件交换记录,设置MX优先级,安装多台的主机实现
如:
;Host Address (A记录)
mail1.upkiller.com
mail2.upkiller.com
;Mail Exchanges (MX记录)
upkiller.com IN MX 1 mail1.upkiller.com
upkiller.com IN MX 2 mail2.upkiller.com
邮件传递顺序,优先MX记录,如没有MX记录,尝试将邮件传给该域的A记录ip地址。
----------------------------------------------------------------------------
SMTP状态码:
2xx 答应要求
4xx 遇到暂时性的错误
5xx 发生永久性问题
------------------------------------------------------------------------------
一 ,安装cyrus-sasl-2.1.22(Simple Authentication and Security Layer)
简单的验证和安全层,smtp发信认证。
ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-sasl-2.1.22.tar.gz
tar -zxvf cyrus-sasl-2.1.22.tar.gz
./configure --prefix=/usr/local/sasl2
--disable-gssapi
--disable-anon
--disable-sample
--disable-digest
--enable-plain
--enable-login
--enable-sql
--with-mysql=/usr/local/mysql
--with-mysql-includes=/usr/local/mysql/include/mysql
--with-mysql-libs=/usr/local/mysql/lib/mysql
--with-authdaemond=/usr/local/courier-authlib/var/spool/authdaemon/socket
make
make install

rm /usr/lib/libsasl
关闭原有的sasl链接新的(重要):
mv /usr/lib/libsasl2.a   /usr/lib/libsasl2.a.OFF
mv /usr/lib/libsasl2.la   /usr/lib/libsasl2.la.OFF
mv /usr/lib/libsasl2.so.2.0.19   /usr/lib/libsasl2.so.2.0.19.OFF
mv /usr/lib/sasl2   /usr/lib/sasl2.OFF
rm /usr/lib/libsasl2.so
rm /usr/lib/libsasl2.so.2
ln -sv /usr/local/sasl2/lib/*   /usr/lib

postfix 2.3以后的版本会分别在/usr/local/lib和/usr/local/include中
搜索sasl库文件及头文件,故还须将其链接至此目录中:
ln -sv /usr/local/sasl2/lib/*   /usr/local/lib
ln -sv /usr/local/sasl2/include/sasl/*   /usr/local/include

创建运行时需要的目录并调试启动
mkdir -pv /var/state/saslauthd
/usr/local/sasl2/sbin/saslauthd -v //看看版本是不是2.1.22    
/usr/local/sasl2/sbin/saslauthd -a shadow pam -d //正常不会报错
启动并测试
/usr/local/sasl2/sbin/saslauthd -a shadow pam
/usr/local/sasl2/sbin/testsaslauthd -u root -p password //正常显示0: OK "Success"成功
配置库文件搜索路径,让postfix能找到sasl:
echo "/usr/local/sasl2/lib" >> /etc/ld.so.conf
echo "/usr/local/sasl2/lib/sasl2" >> /etc/ld.so.conf
ldconfig -v
ldconfig -v | grep sasl2 //看看有没有什么错误
加入开机自启动:
echo "/usr/local/sasl2/sbin/saslauthd -a shadow pam" >> /etc/rc.local
错误FAQ:
1,authentication mechanisms: getpwent pam rimap shadow
    echo "/usr/local/sasl2/lib" >> /etc/ld.so.conf
    echo "/usr/local/sasl2/lib/sasl2" >> /etc/ld.so.conf
    ldconfig -v
-----------------------------------------------------------------------
二,安装postfix-2.4.5:(Mail Transport agent(MTA)邮件传输代理)
下载:postfix-2.4.5.tar.gz源码包
rpm -e sendmail --nodeps //删除sendmail
//添加postfix用户组和帐号
groupadd -g 2525 postfix
useradd -u 2525 -g postfix -s /sbin/nologin -d /dev/null postfix
groupadd -g 2526 postdrop
useradd -g postdrop -u 2526 -s /bin/false postdrop
tar -zxvf postfix-2.4.5.tar.gz
配置postfix编译参数支持sasl,mysql验证:
make -f Makefile.init Makefiles \
'CCARGS=-DHAS_MYSQL -I/usr/local/mysql/include/mysql -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I/usr/local/sasl2/include/sasl' \
'AUXLIBS=-L/usr/local/mysql/lib/mysql -lmysqlclient -lz -lm -L/usr/local/sasl2/lib   -lsasl2'
(这里要注''这间要有一个空格)
make
make install
安装最后的选项:
install_root:[/]   (默认)
tempdir:[/home/postfix-2.4.5] /tmp
config_directory: [/etc/postfix] (默认)
daemon_directory:[/usr/libexec/postfix] /usr/local/postfix/libexec
command_directory:[/usr/sbin] /usr/local/postfix/sbin
queue_directory:[/var/spool/postfix] (默认)
sendmail_path: [/usr/sbin/sendmail] (默认)
newaliases_path: [/usr/bin/newaliases] (默认)
mailq_path: [/usr/bin/mailq] (默认)
mail_owner: [postfix] (默认)
setgid_group: [postdrop]   (默认)
html_directory: [no] (默认)
manpages: [/usr/local/man] /usr/local/postfix/man (默认)   
readme_directory: [no]
编译postfix错误FAQ:
cannot find -lmysqlclient
严格检查输入是否有误:),'AUXLIBS前面要有空格,或是把mysql库加入搜索路径:
echo /usr/local/mysql/lib/mysql >> /etc/ld.so.conf
ldconfig
最后:
生成别名二进制文件,这个步骤如果忽略,会造成postfix效率极低:
/usr/bin/newaliases
检验postfix是否支持sasl认证,如果输出为以下结果,则支持:
/usr/local/postfix/sbin/postconf   -a
cyrus
dovecot
/usr/local/postfix/sbin/postconf -m | grep mysql
mysql
没有的话需重新编译postfix。
------------------------------------------------------------
启动错误FAQ:
1,postsuper: fatal: scan_dir_push: open directory defer:Permission denied
postfix/postfix-script: fatal: Postfix integrity check failed!
进入postfix-2.4.5源码目录重新make install一遍即可
----------------------------------------------------------------------
三,配置基本postfix:

修改main.cf配置文件:
vi /etc/postfix/main.cf
myhostname = mail.upkiller.com     //主机名称
mydomain = upkiller.com      //域名
myorigin = $mydomain            //组织名称,邮件标头上面的 mail from 的那个地址
inet_interface = all       //监听的网卡接口
mydestination = $myhostname,localhost.$mydomain,localhost,$mydomain //指定postfix系统要接收到哪个域名的邮件
mynetworks = 127.0.0.0/8           //允许不使用smtp发信认证的网段
配置main.cf说明:
1,参数行和注释行是不能处在同一行中,参数不要加引号,=号两边的空格可有可无
2,被引用的参数并不一定要先定义,即顺序颠倒也无所谓。
3,如果参数同时拥有一个以上的值,参数之间可以用逗号,空格|tab,或换行字符隔开。
4,如果参数太多无法放同一行,可以将它们放在不同的行中,只需要在每行前多置一个
    tab|空格即可;postfix会把第一个字符为(空格|tab)的行视为前一行的延续。
5,修改后立即生效,重载配置postfix reload,最好可以postfix stop;postfix start
启动postfix测试:

/usr/local/postfix/sbin/postfix check   //检查postfix的完整性(没有消息就是good)
/usr/local/postfix/sbin/postfix start
netstat -tnl | grep :25
建立收信测试帐号:
adduser upkiller
passwd upkiller
发信测试:
nc localhost 25
ehlo mail.upkiller.com
250-mail.upkiller.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
mail from:root@upkiller.com
rcpt to:upkiller@upkiller.com
data
subject:Postfix mail test!
postfix test!
.
quit
开启另一tty用upkiller登陆:
mail
"/var/spool/mail/upkiller": 1 message 1new
>N 1 root@upkiller.com Thu Seq 20 05:12 15/547 "Postfix mail test!"
cat /var/spool/mail/upkiller //储存upkiller用户的mail文件
测试成功。
---------------------------------------------------------------------
四,开启cyrus-sasl认证功能:
vi main.cf
#====================SASL========================  
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
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
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $domain
smtpd_sasl_security_options = noanonymous
smtpd_sasl_application_name = smtpd
smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)

#编辑smtpd.conf
vi /usr/local/lib/sasl2/smtpd.conf
内容:
pwcheck_method: saslauthd
mech_list: PLAIN LOGIN
重新启动postfix:
/usr/local/postfix/sbin/postfix stop
/usr/local/postfix/sbin/postfix start
测试:
adduser upkiller
passwd upkiller
//取base64编码
perl -MMIME::Base64 -e 'print encode_base64("upkiller")'
dxBraWxsZXI=
nc localhost 25
220 mail.upkiller.com ESMTP Postfix (2.4.5)
ehlo mail.upkiller.com
250-mail.upkiller.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN (看见这二行即成功)
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
auth login
334 VXNlcm5hbWU6
dXBraWxsZXI=
334 VXNlcm5hbWU6
dXBraWxsZXI=
235 2.0.0 Authentication successful
mail from:root@upkiller.com
rcpt to:upkiller@upkiller.com
data
subject:smtp authentication test!
test ok
.
quit

错误FAQ:
tail -f /var/log/maillog
1,fatal: SASL per-connection initialization failed
warning: /usr/local/libexec/postfix/smtpd: bad command startup
解决方法:
sasl2没装好,和旧的冲突,重新安装sasl2把sasl2装在/usr/local/sasl2下再关闭旧的
文件,连接新的,确保系统能找到的include和lib文件都是新编的,
再重编译postfix即可
2,NIS domain name not set NIS lookups disabled
提示没有启动NIS
alias_maps = $alias_database
强制postfix只使用本地的aliases资料库。

-------------------------------------------------------------
五,让postfix支持mysql的虚拟域和虚拟用户:
1、编辑/etc/postfix/main.cf,添加如下内容:
vi /etc/postfix/main.cf
#================ Virtual Mailbox Settings =====================#
# 指定用户邮箱所在的根目录
virtual_mailbox_base = /var/mailbox
#指定postfix如何去检索邮箱,这里是采用mysql
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
#指定postfix如何去检索虚拟域
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_alias_domains =
#指定postfix如何去检索虚拟别名
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
#邮件账号uid, 即postfix组id号(即/var/mailbox目录所有者的帐号)
virtual_uid_maps = static:2525
virtual_gid_maps = static:2525
#如果没有安装maildrop,则此处为virtual
virtual_transport = virtual
maildrop_destination_recipient_limit = 1
maildrop_destination_concurrency_limit = 1
#================ QUOTA Settings =============================#(邮箱限额)
#每封信的最大(10M),postfix的默认值是10M, 但这指的是邮件正文和编码后附件的总和
#, 经过#base64编码,附件的大小会增加35%左右, 因此这里设定可接受邮件的大小为14M  
message_size_limit = 14336000
virtual_mailbox_limit = 20971520
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
#指定postfix如何获得用户的quota信息(每个用户的邮箱大小)
virtual_mailbox_limit_maps =
mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
# 是否允许覆盖默认邮箱的大小
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, the user's maildir has overdrawn his diskspace quota, please Tidy your mailbox and try again later.
virtual_overquota_bounce = yes
2、添加为支持虚拟域和虚拟用户所用到的配置文件:
vi /etc/postfix/mysql_virtual_alias_maps.cf //虚拟别名:
user = extmail
password = extmail
hosts = localhost
dbname = extmail
table = alias
select_field = goto
where_field = address
additional_conditions = AND active = '1'
vi /etc/postfix/mysql_virtual_domains_maps.cf //虚拟域
user = extmail
password = extmail
hosts = localhost
dbname = extmail
table = domain
select_field = domain
where_field = domain
additional_conditions = AND active = '1'
vi /etc/postfix/mysql_virtual_mailbox_limit_maps.cf //虚拟邮箱容量
user = extmail
password = extmail
hosts = localhost
dbname = extmail
table = mailbox
select_field = quota
where_field = username
additional_conditions = AND active = '1'

vi /etc/postfix/mysql_virtual_mailbox_maps.cf //虚拟邮箱
user = extmail
password = extmail
hosts = localhost
dbname = extmail
table = mailbox
select_field = maildir
where_field = username
additional_conditions = AND active = '1'
//新建虚拟用户邮箱所在目录,postfix用户所有:
mkdir -pv /var/mailbox
chown -R postfix:postfix /var/mailbox

//开启smtp也从mysql中验证帐号:
vi /usr/local/lib/sasl2/smtpd.conf (/usr/lib/sasl2连接到该目录)
pwcheck_method: auxprop
auxprop_plugin: sql
mech_list: PLAIN LOGIN
sql_engine: mysql
sql_hostname: localhost
sql_user: extmail
sql_passwd: extmail
sql_database: extmail
sql_select: SELECT password FROM mailbox WHERE dxBraWxsZXI=
nc localhost 25
220 mail.upkiller.com ESMTP Postfix (2.4.5)
ehlo mail.upkiller.com
250-mail.upkiller.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN (看见这二行即成功)
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
auth login
334 VXNlcm5hbWU6
dXBraWxsZXI=
334 VXNlcm5hbWU6
dXBraWxsZXI=
235 2.0.0 Authentication successful

tail -f /var/log/mysqld/log.log
提示如下日志:
connect
postfix@localhost on postfix
SELECT password FROM mailbox WHERE username='upkiller@upkiller.com' and
domain='upkiller.com' and active='1'
tail -f /var/log/maillog
验证错误提示:
SASL login authentication failed: authentication failure
成功:connect from localhost.localdomain
把原先系统的cyruss-sasl删除,再重新编译cyrus-sasl和postfix:
rpm -e `rpm -qa | grep cyrus-sasl` --nodeps
一般都是没有安装和配置好courier authentication.
再做其它各种查询测试:
//邮箱
postmap -q 'maps' mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
SELECT maildir FROM mailbox WHERE username='maps'
//别名
postalias -q 'alias' mysql:/etc/postfix/mysql_virtual_alias_maps.cf
SELECT goto FROM alias WHERE address='alias'
--------------------------------------------------------------------------------
六,安装Courier authentication library:

新版本的imap不再包含authentication library,必须先安装 Courier authentication library
解压编译安装:
tar jxvf courier-authlib-0.59.3.tar.bz2
cd courier-authlib-0.59.3
./configure --prefix=/usr/local/courier-authlib \
--sysconfdir=/etc \
--without-authpam \
--without-authldap \
--without-authpwd \
--without-authshadow \
--without-authvchkpw \
--without-authpgsql \
--with-authmysql \
--with-mysql-libs=/usr/local/mysql/lib/mysql \
--with-mysql-includes=/usr/local/mysql/inculde/mysql \
--with-redhat \
--with-authmysqlrc=/etc/authmysqlrc \
--with-authdaemonrc=/etc/authdaemonrc \
#优化
     CFLAGS="-march=i686 -O2 -fexpensive-optimizations"  
     CXXFLAGS="-march=i686 -O2 -fexpensive-optimizations"
make
make install
chmod 755 /usr/local/courier-authlib/var/spool/authdaemon
cp /etc/authdaemonrc.dist   /etc/authdaemonrc
cp /etc/authmysqlrc.dist   /etc/authmysqlrc
编辑authdaemonrc(确保只使用mysql认证):
vi authdaemonrc  
authmodulelist="authmysql"
authmodulelistorig="authmysql"
daemons=10
DEBUG_LOGIN=2 (打开日志方便调试,调试成功之后再关闭)
编辑/etc/authmysqlrc 为以下内容,其中2525,2525 为postfix 用户的UID和GID:
MYSQL_SERVER localhost
MYSQL_PORT 3306               (指定你的mysql监听的端口3306)
MYSQL_USERNAME   extmail       (extmail数据库的所有者的用户名)
MYSQL_PASSWORD   extmail         (数据库帐户密码)
MYSQL_SOCKET   /tmp/mysql.sock
MYSQL_DATABASE   extmail
MYSQL_USER_TABLE   mailbox
MYSQL_CRYPT_PWFIELD   password
MYSQL_UID_FIELD   '2525'
MYSQL_GID_FIELD   '2525'
MYSQL_LOGIN_FIELD   username
MYSQL_HOME_FIELD   concat('/var/mailbox/',homedir)
MYSQL_NAME_FIELD   name
MYSQL_MAILDIR_FIELD   concat('/var/mailbox/',maildir)
注意:确认在这个文件中不能用空格键,只能用tab键。
确认只使用单引号,比如:'/var/mailbox/','UID','GID'
localhost不能用单引号
确认你的/etc/hosts文件中有localhost
编译时如果支持Ipv6可能导致错误
MYSQL_GID_FIELD 和MYSQL_UID_FIELD是maildrop的UID和GID,而不是MySQL的。
如果想使用md5密码,把MYSQL_CLEAR_PWFIELD password改成MYSQL_CRYPT_PWFIELD password

加入库搜索路径:
echo "/usr/local/courier-authlib/lib/courier-authlib" >> /etc/ld.so.conf
ldconfig -v
加入开机启动:
cp courier-authlib.sysvinit /etc/init.d/courier-authlib
chmod 755 /etc/init.d/courier-authlib
chkconfig --add courier-authlib
chkconfig --level 35 courier-authlib on
手动启动:
/usr/local/courier-authlibn/sbin/authdaemond start
检测是否启动成功:
pstree | grep authdaemond
--------------------------------------------
错误FAQ:
1,MYSQL_SERVER: command not found等一大堆参数错误
原来是
cp /etc/authmysqlrc.dist   /etc/authdaemonrc
时复制文件名错误:(
2,configure: error: --with-authmysql specified but no mysqlclient.so
checking for mysql_config... /usr/bin/mysql_config
checking for mysql_connect... no
checking for mysql_real_connect... no
rm /usr/bin/mysql_config
ln -s /usr/local/mysql/bin/mysql_config /usr/bin/mysql_config
再不行:
ln -s libmysqlclient.so.15 libmysqlclient.so.12
ln -s libmysqlclient.so.15 mysqlclient.so

--------------------------------------------------------------------------------
七,安装Courier-IMAP(提供POP3/IMAP服务):
tar jxvf courier-imap-4.1.3.tar.bz2
cd courier-imap-4.1.3
./configure --prefix=/usr/local/courier-imap \
--with-redhat \
--enable-unicode=utf-8,iso-8859-1,gb2312,gbk,gb18030 \
--disable-root-check \
--with-trashquota \
--without-ipv6 \
CPPFLAGS='-I/usr/local/courier-authlib/include' \LDFLAGS='-L/usr/local/courier-authlib/lib/courier-authlib' \
COURIERAUTHCONFIG='/usr/local/courier-authlib/bin/courierauthconfig'
make
make install
//建立配置文件
cd /usr/local/courier-imap/etc
ls *.dist | awk -F"." '{print "cp "$0" "$1""}' | sh
//打开pop3,imapd支持,修改MAILPATH
vi /usr/local/courier-imap/etc/pop3d
POP3DSTART=YES
MAILDIRPATH=/var/mailbox

vi /usr/local/courier-imap/etc/imapd
IMAPDSTART=YES
MAILPATH=/var/mailbox
//加入开机启动
cp courier-imap.sysvinit /etc/rc.d/init.d/courier-imapd
chmod 755 /etc/rc.d/init.d/courier-imapd
chkconfig --add courier-imapd
chkconfig --level 2345 courier-imapd on
service courier-imapd start
检测:
netstat -tnl |egrep "110|143"

新建虚拟用户邮箱所在的目录,并将其权限赋予postfix用户:
#mkdir –pv /var/mailbox
#chown –R postfix /var/mailbox
接下来重新配置SMTP 认证,编辑 /usr/local/lib/sasl2/smtpd.conf ,确保其为以下内容:
pwcheck_method: authdaemond
log_level: 3
mech_list: PLAIN LOGIN
authdaemond_path:/usr/local/courier-authlib/var/spool/authdaemon/socket
验证:
nc localhost 25 (重复上面的)
tail -f /var/log/mysqld/log.log
如果有下面:
SELECT username,password, "", '2525', '2525',concat('/var/mailbox/',homedir)..
表示重新配置的smtp验证成功了。

----------------------------------------------
调试:pop3
编辑authdaemonrc:
DEBUG_LOGIN=2 (打开日志方便调试,调试成功之后再关闭)
tail -f /var/log/maillog
nc localhost 110
user user1@extmail.org
user user
list
retr 1
quit