Postfix

Postfix Logo

Postfix是一个著名的邮件服务器,由任职于IBM华生研究中心(T.J. Watson Research Center)的荷兰籍研究员Wietse Venema为改良sendmail而开发。Postfix看起来很像sendmail,但本质上却有很大不同。Postfix的主页:www.postfix.org

Postfix基础概念

Postfix默认配置文件:/etc/postfix/main.cf

虚拟域名(Postfix Virtual Domain Hosting)

Postfix把域名分为以下几类:

canonical domains(权威域、正式域)
包括运行Postfix的主机名(hostnames)、IP地址,或者主机的父域名,称作权威域(canonical domains)。权威域在Postfix中以 local_domain 实现。
hosted domains(托管域)
如果作为目标投递地址(final destination),又不是权威域的话,就称为托管域(hosted domains)。托管域在Postfix中以 virtual_alias_domainvirtual_mailbox_domain 实现。
relay domains(中转域、中继域)
如果不是目标投递地址(not the finaly destination),需要转发(forwards),则成为中继域(relay domains)。中继域在Postfix中以 relay_domain 实现。

Postfix与SASL

查看Postfix支持何种SASL实现:

# postconf -a
cyrus
dovecot

可见当前的Postfix版本支持Cyrus SASL和Dovecot SASL 2中SASL的实现。

saslauthd是Cyrus SASL的后台程序。查看当前运行的saslauthd运行模式:

# ps awx|grep sasl
3244 ?        Ss     0:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a shadow sasldb
...

这里涉及到2个参数:

-m <path>
设置saslauthd的工作路径。
-a <authmech>
设置saslauthd的认证模式。

以上,saslauthd的工作路径是/var/run/saslauthd,认证模式是shadow。可以通过修改/etc/sysconfig/saslauthd来配置saslauthd的运行时参数:

# cat /etc/sysconfig/saslauthd 
# Directory in which to place saslauthd's listening socket, pid file, and so
# on.  This directory must already exist.
SOCKETDIR=/var/run/saslauthd

# Mechanism to use when checking passwords.  Run "saslauthd -v" to get a list
# of which mechanism your installation was compiled with the ablity to use.
#MECH=shadow

# Options sent to the saslauthd. If the MECH is other than "pam" uncomment the next line.
# DAEMONOPTS=--user saslauth

# Additional flags to pass to saslauthd on the command line.  See saslauthd(8)
# for the list of accepted flags.
FLAGS=sasldb

这个配置文件包括几个常见参数:SOCKETDIR设置了工作路径(saslauthd用于监听的socket路径),也就是-m设置的路径。

saslauthd通常用UNIX域协议与其他进程通信,因此必须确保Postfix SMTP Server在saslauthd的工作路径有可读和可执行的权限:

# ls -ld /var/run/saslauthd/
drwxr-xr-x 2 root root 4096 7月  28 18:02 /var/run/saslauthd/

以下是Cyrus SASL的一个配置示例:

# cat /etc/sasl2/smtpd.conf 
pwcheck_method: saslauthd
mech_list: plain login

pwcheck_method的值可以设置为:saslauthd或auxprop。saslauthd是最基本的验证方式,如果设置为saslauthd,则mech_list就只能是plain, login,而这两种认证机制(plain和login)都是以不加密方式发送认证信息(credentials),应该用TLS来加密认证信息。

使用testsaslauthd来测试saslauthd认证模式:

$ testsaslauthd -ubailing -p123456
0: NO "authentication failed"
$ testsaslauthd -ubailing -pMYCORRECTPWD
0: OK "Success."

而如果设置为auxprop(Auxiliary Property Plugins),则需要添加另一个选项:auxprop_plugin。Cyrus SASL支持插件的方式来扩展libsasl,目前支持的插件包括:

sasldb账户信息存储于BerkeleyDB中。
sql账户信息存储于SQL数据库中。
ldapdb帐号信息存储于LDAP数据库中。
密码验证服务/插件认证后台
saslauthd/etc/shadow
saslauthdPAM
saslauthdIMAP Server
saslauthdsasldb
sqlMySQL、PostgreSQL、SQLite
ldapdbLDAP

疑难杂症

no SASL authentication mechanisms

起初测试Postfix是否工作时遇到的一个问题:

# telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Connection closed by foreign host.

连接直接被断开。检查服务器日志(/var/log/maillog)发现有以下输出:

Jul 29 10:51:49 vps950 postfix/smtpd[5168]: connect from localhost[127.0.0.1]
Jul 29 10:51:49 vps950 postfix/smtpd[5168]: warning: xsasl_cyrus_server_get_mechanism_list: no applicable SASL mechanisms
Jul 29 10:51:49 vps950 postfix/smtpd[5168]: fatal: no SASL authentication mechanisms

检查Cyrus SASL的安装包情况:

# rpm -qa|grep sasl
cyrus-sasl-2.1.23-13.el6_3.1.x86_64
cyrus-sasl-lib-2.1.23-13.el6_3.1.x86_64
cyrus-sasl-devel-2.1.23-13.el6_3.1.x86_64
cyrus-sasl-plain-2.1.23-13.el6_3.1.i686

没有发现问题。后来过了N个小时,发现以上输出绝对是错的!被它瞒天过海。缘故在于:

# uname -a
Linux vps950 2.6.32-220.el6.x86_64 #1 SMP Tue Dec 6 19:48:22 GMT 2011 x86_64 x86_64 x86_64 GNU/Linux

看清了,是x86_64,再对比cyrus-sasl-plain的安装信息:

cyrus-sasl-plain-2.1.23-13.el6_3.1.i686

.i686!绝对的不靠谱。这个问题想来必然是copy导致,检查history,居然有这样一条混账安装记录:

# history |grep "yum install.*sasl"
yum install cyrus-sasl-plain.i686

果然copy害死人。卸载.i686,安装.x86_64版本:

# yum remove cyrus-sasl-plain.i686
# yum install cyrus-sasl-plain

重新启动Postfix:

# service postfix restart
Shutting down postfix:                                     [  OK  ]
Starting postfix:                                          [  OK  ]

再次连接Postfix(输出220 berlinix.com ESMTP unknow;输入EHLO berlinix.com):

# telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 berlinix.com ESMTP unknow
EHLO berlinix.com
250-berlinix.com
250-PIPELINING
250-SIZE 10485760
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

可以看到验证方式设置为:PLAIN LOGIN。

关于这个问题,可以参考Postfix SMTP Auth Error "no SASL authentication mechanisms"这篇文章。

无法接收外部邮件

Postfix配置完毕后,发现可以发送邮件出去,但无法接收外部发来的邮件。怀疑是MX配置问题:

$ dig MX berlinix.com +short
50 mail-fwd.mx.g19.rapidsite.net.

看起来没有正确的设置邮件服务器地址。修改DNS配置(在DNS服务商的Zone file中编辑):

www.berlinix.com.      86400 IN MX    50 mail.berlinix.com.
berlinix.com.          86400 IN MX    50 mail.berlinix.com.
mail.berlinix.com.     86400 IN A     119.254.35.103
www.berlinix.com.      86400 IN TXT   "v=spf1 a mx ptr ~all"
berlinix.com.          86400 IN TXT   "v=spf1 a mx ptr ~all"

接下来就是等待MX配置生效。

参考

Postfix SASL Howto。Postfix官方文档,详细介绍了Postfix如何与SASL协同工作。

分享

0