POSTFIX工作原理及相关概念


Postfix内部收信、发信流程图

postfix邮件服务系统原理及配置_postfix原理分析以及安装配置为一个postfix邮件服务系统原理及配置_postfix原理分析以及安装配置为一个_02

   整个处理流程分为三个阶段:接收邮件、将邮件排入队列、递送邮件。每个阶段由一组独立的Postfix组件负责。当一封邮件被收下并排入队列之后,队列管理器(Queue Manager)会启动适当的MDA,将邮件送到终点。



邮件如何进入Postfix系统

   邮件有四种渠道可以进入Postfix系统:
  1、Postfix可接受来自本机系统的邮件(本机用户或自主进程提交的邮件)。
  2、Postfix可接受网络传入的邮件(来自MUA或者其他MTA)。
  3、已经被Postfix收下并交给MDA的邮件,被MDA传回到Postfix(通常是为了转寄到另一个地址)。
  4、当Postfix无法将邮件寄到目的地时,自己会产生退信通知函。
  邮件有可能在进入Postfix之前就被拒绝了,或者因为暂时性的故障(网络断线、远程服务器响应暂时性的错误等),同样的邮件可能会每隔一段时间就重复进入Postfix系统一次,重新递送。


   1)来自服务器本机的邮件

       各个Postfix组件之间的合作全靠队列(Queue)交换邮件、Postfix系统有多个队列,这些队列全部队列管理器(Queue Manager)负责控制管理。Postfix组件可将邮件交付给Queue Manager,由其代为放入适当的队列。当需要处理特定工作时,Queue Manager将队列里的邮件交付给正确的组件。
  在Unix系统上,当用户要寄出邮件时(不管这封信是寄到哪里),通常是使用sendmail包内的sendmail命令。Postfix提供了一个与此命令兼容的同名工具,也称为sendmail。当用户以Postfix的sendmail寄出邮件后,sendmail(postfix的版本)会使用postdrop程序将邮件存入Postfix队列目录下的maildrop/子目录。专门注意maildrop子目录有无变化的是Pickup Daemon,每当有新的邮件进入maildrop时,Pickup Daemon便会读出新邮件,然后交给cleanup daemon进入“清理程序”。
  当邮件刚进入Postfix时,不一定含有构成有效邮件的所有必要字段,而且标头里的地址也可能需要被改写成标准格式(
user@domain.tld),并依据规范的或虚拟的查询表(如果有的话)将原本的地址改成其他地址。所谓“清理程序”就是补足遗漏的标头字段,这部分工作由cleanup daemon负责;地址的处理由Trivial-Rewrite Daemon负责。
  经过Cleanup Daemon处理好的邮件,会被传入收件队列(Incoming Queue)。Queue Manager会不断的注意收件队列的变化,每当有新邮件进入收件队列时,便会用适当的MDA将邮件送到下一站,或直接送到最终目的地。
   2)来自网络的邮件
       来自网络的邮件由Postfix Smtpd Daemon接收进来,然后交给Cleanup Daemon运行清理程序,随后排入收件队列,由Queue Manager选择适当的MDA将邮件送到下一站或最终目的地。Smtpd有可能收到两种邮件,第一种是外界寄给Postfix所控制的网域的邮件(Postfix系统本身是邮件的终点站或网关),另一种是要寄到其他网域的邮件。
  Smtpd一定会收下第一种邮件(如果收件人存在的话),至于第二种邮件(目的地在其他网域),就要看传邮件过来的客户端是否有资格。网络收下要寄到其他网域的邮件,并代为寄送到目的地的动作称为转发(relay)。在两种情况下,Postfix愿意提供转发服务:一是客户端符合配置文件限定的资格,二是收信网域是relay_domain参数所列出的网域之一。


   3)通知函

       当用户的邮件被延时时,或是根本无法递送到目的地时,Postfix使用Defer或Bounce Daemon产生一封新的通知函。这封通知函会被交给Cleanup Daemon,由它进行例行的清理程序之后再排入收件队列,由Queue Manager接手处理。
   4)转寄邮件
       有时候,邮件在委托给MDA之后,MDA会发现该邮件其实应该寄送到另一个系统的另一个账户。比如说,当MDA在用户个人的forward文件发现了另一个地址时,就会发现这种情况。照理说,MDA可以直接使用Smtp Client(即Smtp Daemon)送出邮件。不过,由于同一封信可能有多位收件人,为了照顾到每一位收件人,同时也为了在邮件日志上留下完整记录,MDA应该依提交新邮件的方式,让邮件重新回到Postfix系统,由Postfix按照“来自本机的邮件”的程序来处理。
   Postfix的队列管理器
邮件本身的处理工作主要是由队列管理器(Queue Manager)负责,每一个能收到邮件的Postfix组件,都有一个共同的目的地--队列管理器。邮件进入队列之前的关卡是Cleanup Daemon,因为只有经过清理的邮件,才有资格进入队列。Cleanup将邮件排入队列后,会通知Queue Manager去处理新邮件。每当Queue Manager察觉收信队列有新信到达时,就会使用Trivial-Rewrite来决定邮件路由信息,这些信息包括传输方法、下一站以及收件人地址。
  Queue Manager总共维护四种队列:收件(Incoming)、活动(Active)、延迟(Deferred)、故障(Corrupt)。新邮件通过Cleanup之后的第一站是“收件队列”。假设系统资源空闲。Queue Manager会将邮件移入“活动队列”,然后调用适当的MDA来投递邮件,而投递失败的邮件则会被移入“耽搁队列”。
  如果邮件被耽搁太久,或是被判定无法送达,则Queue Manager还要负责协调Bounce与Defer Daemons来产生一份递送状态报告,并传回给系统管理员或送信者(或两者)。在Postfix的队列目录下(默认位置是/var/spool/postfix/),除了上述四种邮件队列目录之外,还有bounce/与defer/目录。这些目录含有状态信息,解释特定邮件为何被耽搁或无法递送,Bounce与Defer Daemon就是利用这些目录下的状态信息来产生通知函。


   投递操作

       Postfix依据收件地址的类型,来判断是否要收下邮件以及如何进行投递操作。主要的地址类型有本地(Local)、虚拟别名(Virtual Alias)、虚拟邮件(Virtual Mailbox)以及转发(Relay)。如果收件地址不在这四种主要类型之中,则邮件会被交给Smtp Client,通过网络寄送出去(假设原信是来自有资格使用转发服务的客户端);否则,Queue Manager便依据地址的类型,选择适当的MDA来投递邮件。

   本地邮件
  如果收件人为Postfix本地系统的用户(在运行Postfix的那台服务器上有Shell账户的用户),则他们的邮件会被交给Local MDA处理,凡是收件地址的网域名称与mydestination参数列出的任一网域名称相符,这类邮件都算是本地邮件,对于送到任何mydestination网域的任何有效账户的邮件,Local MDA会先检查收件人是否有个人的.forward文件,如果没有,则邮件会被存入用户的个人邮箱;否则,则依据.forward文件的内容来进行投递操作(或转寄到其他地方,或是交给外部程序处理)。
  对于需要转寄到他处的邮件,将会被重新提交会Postfix,以便传送到新地址。如果传送过程发生了暂时性问题,MDA会通知Queue Manager,而邮件会被保存在延迟队列等待下次的递送机会;如果发生永久性问题,则要求Queue Manager将信息退给发信者。

   虚拟别名邮件
  寄给虚拟别名地址的邮件,全部都需要转寄(Forward)到其真实地址,虚拟别名的网域名称列在virtual_alias_domains参数中,每一个虚拟网域都可以有自己的一组用户,不同的虚拟网域可以容许有同名的用户。用户与其真实地址之间对应关系,列在virtual_alias_maps参数所指定的查询表中。当Queue Manager发现邮件的收件地址的网域部分virtual_alias_domains所列出的网域之一,则会重新提交邮件,以便传到真实地址。


   虚拟邮箱邮件

  虚拟邮箱的网域名称列在virtual_mailbox_domains参数中。每一个网域都可以有自己的用户群,而且有各自独立的命名空间,换言之,即不同的虚拟邮箱网域可以有同名的用户。用户与邮箱之间的对应关系,定义在virtual_mailbox_maps参数所指定的查询表中,虚拟邮箱与系统上的Shell账户之间没有关联性,虚拟邮箱邮件的投递操作由Virtual MDA负责运行。

   转发邮件
  实际邮箱位于其他MTA控制管理的网域,但是Postfix愿意代收并转寄的邮件,称为转发邮件。这类网域的名称列在relay_domains参数中,其邮件由smtp MDA通过网络送到目标网域的MTA。当你假设邮件网关系统时,便可利用转发功能收下Internet寄到内部网域的邮件,并转寄到内部网络的邮件系统上。


   其他邮件

  如果邮件的收件地址不属于前述四类,则一律交给Smtp以递送到正确地点,因为这类邮件必定是要送到系统本身之外的其他网域。先前在“来自网络的邮件”曾说过,并非所有客户端都有资格使用转发服务。一般而言,我们会将转发服务开放给与Postfix Server位于相同局域网络的其他主机,好让这些主机可通过Postfix Server寄信到Internet上的外界网域。
  当Smtp MDA收到外地邮件时,它会依据收件地址来判断邮件应该送到哪个(或哪些)主机,然后依序连接到这些主机,直到有一部主机愿意收下邮件为止。如果投递过程发生暂时性问题,Smtp会通知Queue Manager将邮件放在延迟队列,等待下次传送的机会;如果发生永久性错误,则要求Queue Manager退信给发信者。
  当因暂时故障而不能连接的远程主机恢复连接时,Postfix会先采取试探性动作,以免过多的延迟邮件使对方瘫痪。一开始,Smtp只会搭建有限度的几条连接通道(数量可通过配置文件调整)到收件方,在发现对方能够成功收下邮件之后,才会慢慢提升连接通道的数量(到一个可设定的上限);相反的,如果Smtp发现接送方有任何麻烦,它会立刻撤销连接。

   其他传送代理程序
  Postfix还提供了其他MDA,可用来处理特殊的地址或目的地。这些MDA需要在master.cf配置文件中设定妥当之后才有作用。此外,你还必须在class_transport或transport_maps参数指定的传送表(transport table)中设定如何启动它们。最常用的两个特殊MDA是LMTP与PIPE。

   LMTP投递
  LMTP是一种很类似SMTP的协议,但只能用于同一网络上的邮件系统之间,或是同一主机上的不同邮件程序之间。举例来说,如果需要将邮件送到不同的软件包–该软件可能与Postfix在同一台机器上,也可能位于局域网络上的另一台主机,则Queue Manager可以调用LMTP MDA将邮件传送给该软件包。
  实际上,LMTP最常被用来将邮件交给特殊的POP/IMAP Server,以便使用特殊邮箱格式来存储邮件。在这种情况下,由于只要POP/IMAP SERVER知道特殊邮件格式,所以只好使用标准的LMTP来交付邮件。如果LMTP投递过程中出了任何问题,LMTP MDA会通知Queue Manager将邮件放在延迟队列,等待下次传送的机会。
   PIPE投递
  Postfix提供了Pipe Daemon将邮件传送给外部程序。实际上,Pipe经常被用来将邮件传给外部的内容过滤程序(例如:病毒扫描系统、垃圾邮件分析程序)或其他通信媒介(例如:传真机)。同样,如Pipe无法顺利传出邮件,它会通知Queue Manager将邮件放在延迟队列,等待下次传送的机会。
  实际追踪POSTFIX的邮件处理流程
  让我们追踪一封典型邮件如何通过POSTFIX系统。处理流程是一封邮件从发信方到达目的地(信封地址所指的MTA),然后又被转寄到最终的MTA(收件人实际取信处)。
  例如:HELENE的账户位于一台运行POSTFIX的服务器,她使用自己习惯的MUA编写邮件,然后调用POSTFIX的sendmail命令送出邮件。POSTFIX的sendmail程序从HELENE的MUA软件中取下邮件,然后放在队列的MAILDROP/子目录下。
接着,Pickup Daemon从该目录取出邮件,交给CLEANUP DAEMON运行必要的清理程序,如果HELENE的MUA软件没提供地址from:,或是该地址没使用完整的主机名称,则Cleanup会自动补齐不足的信息以确保邮件格式符合标准。完成清理程序之后,Cleanup将邮件存入收件队列,并通知Queue Manager,使其知道有一封新信正在等待投递。
  如果Queue Manager已经准备好处理新邮件,它会将邮件搬移到活动队列。由于HELENE的信是要送到其他网域系统的用户,所以Queue Manager使用SMTP MDA来投递该邮件。SMTP使用DNS查出哪些邮件服务器愿意收下目的地网域的邮件,然后从中挑出最优先的邮件交换主机(MX HOST)并与该主机接洽,以SMTP协议送出HELENE写的邮件。
  当目的网域的服务器上的MTA SMTPD收下HELENE的SMTP MDA送来的邮件。当smtpd确认它应该收下该邮件之后,它会将邮件交给Cleanup Daemon进行检查,然后存入收件队列。
  Queue Manager将邮件搬移到活动队列,检查收件人地址,然后使用LOCAL MDA来进行投递操作。接着,LOCAL发现收件地址其实是一个别名,其真实地址位于另一个网域,所以将邮件与新地址信息传给CLEANUP DAEMON,回到POSTFIX的队列系统。
  当CLEANUP与Queue Manager处理邮件时,依靠TRIVIAL-REWRITE将地址转换成标准格式,并判断传送方式以及递送流程到下一站。
  当Queue Manager发现新邮件应该送到另一个网络,则会调用SMTP来进行投递操作,而SMTP会先向DNS查出哪些邮件服务器可能接收该网域的邮件。该网域的MTA收下这封邮件后,最后会将邮件交给LOCAL MDA,由它将邮件存入该系统的邮箱。
  到这个时候,Postfix就完成了它的工作。这时收件人现可以用他自己的MUA来阅读邮件,至于这个MUA是直接从邮箱取信,还是使用POP或IMAP之类的协议通过网络下载邮件,都已经不是Postfix所能控制的了。
  我们的例子只假设了最理想的简单状态,实际的传送程序可能会遇到一些意外状况,诸如网络临时断线、远程主机死机、邮箱空间不足。发生意外时,MDA必须通知Queue Manager,将邮件暂时放回延迟队列,等待一段时间之后再重新投递。
  除了临时意外回影响投递过程,还有一些情况也会影响,比方说,收件人并非实际的系统账户,而是IMAP邮件系统的一个账户,在这种情况下,Queue Mananger可能要通过LMTP MDA来投递邮件,或是通过PIPE MDA将邮件送到一个事先确定的外部程序。
  Postfix还要面对各式各样的变化与潜在的复杂性,幸运的,它本身的结构设计足够稳定,几乎能够应付所有可想像到的情况,也有足够的可塑性来适应未来的可能变化。


   队列种类

  收件:Incoming 活动:Active 延迟:Deferred 故障:Corrupt 保留:Hold

   组件结构
  Master组件:主导邮件处理流程、其他组件的总管。配置文件:main.cf和master.cf。
  Qmgr组件:队列管理器。各个postfix组件之间的合作依靠队列交换邮件。
  Sendmail组件:服务器本机发送邮件。
  Postdrop组件:将邮件存入postfix队列目录下的maildrop/子目录。
  Pickup组件:监视maildrop/子目录,读出新邮件,交给cleanup组件。
  Cleanup组件:补足遗漏的标头字段。
  Trivial-Rewrite组件:地址处理,改成标准格式。决定路由信息,包括传输方法、下一站以及收件人地址。
  Smtpd组件:接收来自网络的邮件,交给cleanup组件处理。
  Defer组件:邮件被延时时产生通知函。
  Bounce组件:邮件无法送达目的地时产生通知函。
  Dns组件:查找符合条件的邮件服务器。

   Postfix命令行工具
  postalias:创建或查询别名数据库。
  postcat:显示出队列文件的内容,让管理员可观察滞留在队列里的邮件内容。
  postconf:显示或改变postfix参数,可一次显示一个参数,或是显示所有参数。
  postdrop:将邮件放回到maildrop目录,由postfix重新进行投递操作。
  postfix:启动或停止postfix系统,或重新读取配置文件。也可以用于其他维护工作,包括检查系统配置,以及清空队列。
  postkick:对特定postfix服务发出请求。此工具的作用,主要是给shell scripts提供一个能够与postfix沟通服务的管道。
  postlock:锁定特定文件,确保能够独占访问。此工具的作用,主要是让shell scripts能使用兼容于postfix的锁定方式。
  postlog:将特定的信息记录到系统日志文件中。这是支持shell scripts工具,使其能以类似于postfix的样式来记录信息到日志文件。
  postmap:创建查询表的DB数据库或查询查询表内容。postfix有许多配置信息都是记录在postmap所建的查询表数据库中。
  postqueue:让一般的用户能够有限度地访问postfix队列。可能改变队列的访问方式需要有管理员特权才能进行,而这方面的访问能力由postsuper命令提供。
  postsuper:供管理员访问postfix队列。管理员可删除邮件、扣留邮件(搬到hold队列)、取回邮件(将邮件从hold队列搬回active队列),必要时,还可以修复队列目录结构。


                                                                                                        POSTFIX   配置过程

一、安装前的准备工作
    安装前说明:邮件服务依赖于DNS服务,请事先确信您的DNS服务已经为邮件应用配置完成。
    1、安装所需的rpm包,这包括以下这些:
         httpd, mysql, mysql-server, mysql-devel, openssl-devel, dovecot, perl-DBD-MySQL, tcl, tcl-devel, libart_lgpl, libart_lgpl-devel, libtool-ltdl, libtool-ltdl-devel, expect
    2、关闭sendmail,并将它的随系统自动启动功能关闭:
         # service sendmail stop
         # chkconfig sendmail off
    3、安装以下开发所用到的rpm包组:
         Development Libraries
         Development Tools
二、编译安装postfix
    # groupadd -g 2525 postfix
    # useradd -g postfix -u 2525 -s /sbin/nologin -M postfix
    # groupadd -g 2526 postdrop
    # useradd -g postdrop -u 2526 -s /sbin/nologin -M postdrop
    # tar zxvf postfix-2.10.3.tar.gz
    # cd postfix-2.10.3
    # make makefiles 'CCARGS=-DHAS_MYSQL -I/usr/include/mysql -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I/usr/include/sasl  -DUSE_TLS ' 'AUXLIBS=-L/usr/lib/mysql -lmysqlclient -lz -lm -L/usr/lib/sasl2 -lsasl2  -lssl -lcrypto'

   此处如果你是源码安装或是二进制包安装,注意你的mysql库文件和头文件位置
    # make && make install

   

   进行一些基本配置,测试启动postfix并进行发信
     # vim /etc/postfix/main.cf
    修改以下几项为您需要的配置
     myhostname = mail.neo.com
     myorigin = neo.com
     mydomain = neo.com
     mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
     mynetworks = 192.168.100.0/24, 127.0.0.0/8

    注:参数说明
     myorigin参数用来指明发件人所在的域名,即做发件地址伪装;
     mydestination参数指定postfix接收邮件时收件人的域名,即您的postfix系统要接收到哪个域名的邮件;
     myhostname 参数指定运行postfix邮件系统的主机的主机名,默认情况下,其值被设定为本地机器名;
     mydomain 参数指定您的域名,默认情况下,postfix将myhostname的第一部分删除而作为mydomain的值;
     mynetworks 参数指定你所在的网络的网络地址,postfix系统根据其值来区别用户是远程的还是本地的,如果是本地网络用户则允许其访问;
     inet_interfaces 参数指定postfix系统监听的网络接口;


   配置postfix启动服务脚本

###############################################################START#################################

#!/bin/bash
# postfix      Postfix Mail Transfer Agent    
# chkconfig: 2345 80 30
# description: Postfix is a Mail Transport Agent, which is the program \
#              that moves mail from one machine to another.
# processname: master
# pidfile: /var/spool/postfix/pid/master.pid
# config: /etc/postfix/main.cf
# config: /etc/postfix/master.cf
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ $NETWORKING = "no" ] && exit 3
[ -x /usr/sbin/postfix ] || exit 4
[ -d /etc/postfix ] || exit 5
[ -d /var/spool/postfix ] || exit 6
RETVAL=0
prog="postfix"
start() {
# Start daemons.
echo -n $"Starting postfix: "
       /usr/bin/newaliases >/dev/null 2>&1
/usr/sbin/postfix start 2>/dev/null 1>&2 && success || failure $"$prog start"
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/postfix
       echo
return $RETVAL
}
stop() {
 # Stop daemons.
echo -n $"Shutting down postfix: "
/usr/sbin/postfix stop 2>/dev/null 1>&2 && success || failure $"$prog stop"
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/postfix
echo
return $RETVAL
}
reload() {
echo -n $"Reloading postfix: "
/usr/sbin/postfix reload 2>/dev/null 1>&2 && success || failure $"$prog reload"
RETVAL=$?
echo
return $RETVAL
}
abort() {
/usr/sbin/postfix abort 2>/dev/null 1>&2 && success || failure $"$prog abort"
return $?
}
flush() {
/usr/sbin/postfix flush 2>/dev/null 1>&2 && success || failure $"$prog flush"
return $?
}
check() {
/usr/sbin/postfix check 2>/dev/null 1>&2 && success || failure $"$prog check"
return $?
}
restart() {
stop
start
}
# See how we were called.
case "$1" in
 start)
start
;;
 stop)
stop
;;
 restart)
stop
start
;;
 reload)
reload
;;
 abort)
abort
;;
 flush)
flush
;;
 check)
check
;;
 status)
  status master
;;
 condrestart)
[ -f /var/lock/subsys/postfix ] && restart || :
;;
 *)
echo $"Usage: $0 {start|stop|restart|reload|abort|flush|check|status|condrestart}"
exit 1
esac
exit $?
#####################################################################END####################

   为此脚本赋予执行权限:
       # chmod +x /etc/rc.d/init.d/postfix
   将postfix服务添加至服务列表:
       # chkconfig --add postfix
   设置其开机自动启动:
       # chkconfig postfix on
   使用此脚本重新启动服务,以测试其能否正常执行:
       # service postfix restart
   此时可使用本地用户测试邮件收发了。

#####################################################测试开始####################################
[root@mail ~]# telnet mail.neo.com 25
Trying 192.168.100.5...
Connected to mail.neo.com (192.168.100.5).
Escape character is '^]'.
220 mail.neo.com ESMTP Postfix
ehlo mail.neo.com
250-mail.neo.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
mail from:test@qq.com
250 2.1.0 Ok
rcpt to:tom
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
hello,I am test@qq.com
are you OK?
.
250 2.0.0 Ok: queued as 9041F29802C
quit
221 2.0.0 Bye
Connection closed by foreign host.
[root@mail ~]# tail /var/log/maillog
Mar  1 10:11:47 mail postfix/qmgr[10162]: 9041F29802C: from=<test@qq.com>, size=323, nrcpt=1 (queue active)
Mar  1 10:11:47 mail postfix/local[10195]: warning: dict_nis_init: NIS domain name not set - NIS lookups disabled
Mar  1 10:11:47 mail postfix/local[10195]: 9041F29802C: to=<tom@neo.com>, orig_to=<tom>, relay=local, delay=92, delays=92/0.01/0/0.05, dsn=2.0.0, status=sent (delivered to mailbox)
[root@mail ~]# su - tom
[tom@mail ~]$ mail
Mail version 8.1 6/6/93.  Type ? for help.
"/var/spool/mail/tom": 1 message 1 new
>N  1 test@qq.com           Sat Mar  1 10:11  14/430  
Message 1:
From test@qq.com  Sat Mar  1 10:11:47 2014
X-Original-To: tom
Delivered-To: tom@neo.com
Date: Sat,  1 Mar 2014 10:10:15 +0800 (CST)
From: test@qq.com

hello,I am test@qq.com
are you OK?


##########################################测试完成###############################################



   为postfix服务开启用户别名支持:
   1、在配置文件开启基于hash的别名文件支持
       在main.cf中,找到如下指令,而后启用它(即移除前面的#号):
       #alias_maps = hash:/etc/aliases
   2、在/etc/aliases文件中定义新的别名项,其格式通常为以冒号隔开的两个字段,前一字段为别名用户,后一字段为实际用户
       redhat: neo
   3、将/etc/aliases转换为hash格式:
       # postalias  /etc/aliases
   4、让postfix重新载入配置文件,即可进行测试;

   实现postfix基于客户端的访问控制
    1、基于客户端的访问控制概览
         postfix内置了多种反垃圾邮件的机制,其中就包括“客户端”发送邮件限制。客户端判别机制可以设定一系列客户信息的判别条件:
         smtpd_client_restrictions
         smtpd_data_restrictions
         smtpd_helo_restrictions
         smtpd_recipient_restrictions
         smtpd_sender_restrictions
        上面的每一项参数分别用于检查SMTP会话过程中的特定阶段,即客户端提供相应信息的阶段,如当客户端发起连接请求时,postfix就可以根据配置文件中定义的smtpd_client_restrictions参数来判别此客户端IP的访问权限。相应地,smtpd_helo_restrictions则用于根据用户的helo信息判别客户端的访问能力等等。
        如果DATA命令之前的所有内容都被接受,客户端接着就可以开始传送邮件内容了。邮件内容通常由两部分组成,前半部分是标题(header),其可以由header_check过滤,后半部分是邮件正文(body),其可以由check_body过滤。这两项实现的是邮件“内容检查”。
        postfix的默认配置如下:
         smtpd_client_restrictions =
         smtpd_data_restrictions =
         smtpd_end_of_data_restrictions =
         smtpd_etrn_restrictions =
         smtpd_helo_restrictions =
         smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
         smtpd_sender_restrictions =
        这限制了只有mynetworks参数中定义的本地网络中的客户端才能通过postfix转发邮件,其它客户端则不被允许,从而关闭了开放式中继(open relay)的功能。
        Postfix有多个内置的限制条件,如上面的permit_mynetworks和reject_unauth_destination,但管理员也可以使用访问表(access map)来自定义限制条件。自定义访问表的条件通常使用check_client_access, check_helo_access, check_sender_access, check_recipient_access进行,它们后面通常跟上type:mapname格式的访问表类型和名称。其中,check_sender_access和check_recipient_access用来检查客户端提供的邮件地址,因此,其访问表中可以使用完整的邮件地址,如admin@neo.com;也可以只使用域名,如neo.com;还可以只有用户名的部分,如jun@。


实验1
   禁止192.168.100.3这台主机通过工作在192.168.100.5上的postfix服务发送邮件为例演示说明其实现过程。访问表使用hash的格式。
       (1)首先,编辑/etc/postfix/access文件,以之做为客户端检查的控制文件,在里面定义如下一行:
           192.168.100.3  REJECT
       (2)将此文件转换为hash格式
           # postmap /etc/postfix/access
       (3)配置postfix使用此文件对客户端进行检查
           编辑/etc/postfix/main.cf文件,添加如下参数:
           smtpd_client_restrictions = check_client_access hash:/etc/postfix/access
       (4)让postfix重新载入配置文件即可进行发信控制的效果测试了。


实验2
   禁止通过本服务器向baidu.com域发送邮件为例演示其实现过程。访问表使用hash的格式。
       (1)首先,建立/etc/postfix/deny文件(文件名任取),在里面定义如下一行:
           baidu.com  REJECT
       (2)将此文件转换为hash格式
           # postmap /etc/postfix/deny
       (3)配置postfix使用此文件对客户端进行检查
           编辑/etc/postfix/main.cf文件,添加如下参数:
           smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/deny, permit_mynetworks, reject_unauth_destination
       (4)让postfix重新载入配置文件即可进行发信控制的效果测试了。

   为postfix开启基于cyrus-sasl的认证功能
    查看postfix是否支持cyrus的sasl认证
    #postconf -a
     cyrus
     dovecot
   #vim /etc/postfix/main.cf
   添加以下内容:
############################cyrus-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
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
smtpd_sasl_path = smtpd
smtpd_banner = Welcome to our $myhostname ESMTP,Warning: Version not Available!

########################################################################################


   # vim /usr/lib/sasl2/smtpd.conf
       添加如下内容:
       pwcheck_method: saslauthd
       mech_list: PLAIN LOGIN
   让postfix重新加载配置文件
       #/usr/sbin/postfix reload
   [root@mail ~]# telnet mail.neo.com 25
Trying 192.168.100.5...
Connected to mail.neo.com (192.168.100.5).
Escape character is '^]'.
220 Welcome to our mail.neo.com ESMTP,Warning: Version not Available!
ehlo mail.neo.com
250-mail.neo.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH LOGIN
250-AUTH=LOGIN

250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

确保与我们刚开始测试postfix是否能工作,多出了两行,这样证名己成功了


   安装Courier authentication library
       1、courier简介
       courier-authlib是Courier组件中的认证库,它是courier组件中一个独立的子项目,用于为Courier的其它组件提供认证服务。其认证功能通常包括验正登录时的帐号和密码、获取一个帐号相关的家目录或邮件目录等信息、改变帐号的密码等。而其认证的实现方式也包括基于PAM通过/etc/passwd和/etc/shadow进行认证,基于GDBM或DB进行认证,基于LDAP/MySQL/PostgreSQL进行认证等。因此,courier-authlib也常用来与courier之外的其它邮件组件(如postfix)整合为其提供认证服务。
       # tar jxvf courier-authlib-0.64.0.tar.bz2
       # cd courier-authlib-0.64.0
       #./configure \
   --prefix=/usr/local/courier-authlib \
   --sysconfdir=/etc \
   --without-authpam \
   --without-authshadow \
   --without-authvchkpw \
   --without-authpgsql \
   --with-authmysql \
   --with-mysql-libs=/usr/lib/mysql \
   --with-mysql-includes=/usr/include/mysql \
   --with-redhat \
   --with-authmysqlrc=/etc/authmysqlrc \
   --with-authdaemonrc=/etc/authdaemonrc \
   --with-mailuser=postfix \
   --with-mailgroup=postfix \
   --with-ltdl-lib=/usr/lib \
   --with-ltdl-include=/usr/include
   # make &&make install
   # chmod 755 /usr/local/courier-authlib/var/spool/authdaemon/  
   # cp /etc/authmysqlrc.dist /etc/authmysqlrc
   # cp /etc/authdaemonrc.dist /etc/authdaemonrc
   修改/etc/authdaemonrc 文件
       authmodulelist="authmysql"
       authmodulelistorig="authmysql"
       daemons=10
   配置其通过mysql进行邮件帐号认证
    编辑/etc/authmysqlrc 为以下内容,其中2525,2525 为postfix 用户的UID和GID。
 MYSQL_SERVER localhost
 MYSQL_PORT 3306                   (指定你的mysql监听的端口,这里使用默认的3306)
 MYSQL_USERNAME  extmail      (这时为后文要用的数据库的所有者的用户名)
 MYSQL_PASSWORD extmail        (密码)
 MYSQL_SOCKET  /var/lib/mysql/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)

   提供SysV服务脚本

    # cp courier-authlib.sysvinit /etc/rc.d/init.d/courier-authlib
    # chmod 755 /etc/init.d/courier-authlib
    # chkconfig --add courier-authlib
    # chkconfig --level 2345 courier-authlib on

    # echo "/usr/local/courier-authlib/lib/courier-authlib" >> /etc/ld.so.conf.d/courier-authlib.conf
    # ldconfig -v
    # service courier-authlib start   (启动服务)

   配置postfix和courier-authlib

        新建虚拟用户邮箱所在的目录,并将其权限赋予postfix用户:
        #mkdir –pv /var/mailbox
        #chown –R postfix /var/mailbox

   接下来重新配置SMTP 认证,
    编辑 /usr/lib/sasl2/smtpd.conf ,确保其为以下内容:
    pwcheck_method: authdaemond
    log_level: 3
    mech_list:PLAIN LOGIN
    authdaemond_path:/usr/local/courier-authlib/var/spool/authdaemon/socket


   让postfix支持虚拟域和虚拟用户

    1、编辑/etc/postfix/main.cf,添加如下内容:
########################Virtual Mailbox Settings#####################################################
virtual_mailbox_base = /var/mailbox
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_alias_domains =
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_uid_maps = static:2525
virtual_gid_maps = static:2525
virtual_transport = virtual
maildrop_destination_recipient_limit = 1
maildrop_destination_concurrency_limit = 1
##########################QUOTA Settings##########################################################
message_size_limit = 14336000
virtual_mailbox_limit = 20971520
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
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

##############################################################################################

   此处配置完后最好执行一次postconf -n检查是否有选项无效,如果有,注释或删除都行

    2、使用extman源码目录下docs目录中的extmail.sql和init.sql建立数据库:

        # tar zxvf  extman-1.1.tar.gz
        # cd extman-1.1/docs
        # mysql -u root -p < extmail.sql
        # mysql -u root -p <init.sql
        # cp mysql*  /etc/postfix/

    3、授予用户extmail访问extmail数据库的权限
        mysql> GRANT all privileges on extmail.* TO extmail@localhost IDENTIFIED BY 'extmail';
        mysql> GRANT all privileges on extmail.* TO extmail@127.0.0.1 IDENTIFIED BY 'extmail';

    说明:
         1、启用虚拟域以后,需要取消中心域,即注释掉myhostname, mydestination, mydomain, myorigin几个指令;当然,你也可以把mydestionation的值改为你自己需要的。
         2、对于MySQL-5.1以后版本,其中的服务脚本extmail.sql执行会有语法错误;可先使用如下命令修改extmail.sql配置文件,而后再执行。修改方法如下:
             # sed -i 's@TYPE=MyISAM@ENGINE=InnoDB@g' extmail.sql


     1   配置dovecot

    # vi /etc/dovecot.conf

##############################################################################################
     mail_location = maildir:/var/mailbox/%d/%n/Maildir
  ……
 auth default {
    mechanisms = plain
    passdb sql {
         args = /etc/dovecot-mysql.conf
    }
    userdb sql {
         args = /etc/dovecot-mysql.conf
    }
    ……

############################################################################################

# vim /etc/dovecot-mysql.conf    

############################################################################################      
driver = mysql
connect = host=localhost dbname=extmail user=extmail password=extmail
default_pass_scheme = CRYPT
password_query = SELECT username AS user,password AS password FROM mailbox WHERE username = '%u'
user_query = SELECT maildir, uidnumber AS uid, gidnumber AS gid FROM mailbox WHERE username = '%u'

###########################################################################################

    说明:如果mysql服务器是本地主机,即host=localhost时,如果mysql.sock文件不是默认的/var/lib/mysql/mysql.sock,可以使用host=“sock文件的路径”来指定新位置;例如,使用通用二进制格式安装的MySQL,其soc文件位置为/tmp/mysql.sock,相应地,connect应按如下方式定义。
    connect = host=/tmp/mysql.sock dbname=extmail user=extmail password=extmail

   接下来启动dovecot服务:

        # service dovecot start
        # chkconfig dovecot on


    2  安装Extmail-1.2

        说明:如果extmail的放置路径做了修改,那么配置文件webmail.cf中的/var/www路径必须修改为你所需要的位置。本文使用了默认的/var/www,所以,以下示例中并没有包含路径修改的相关内容。

    1、安装
         # tar zxvf extmail-1.2.tar.gz
         # mkdir -pv /var/www/extsuite
         # mv extmail-1.2 /var/www/extsuite/extmail
         # cp /var/www/extsuite/extmail/webmail.cf.default  /var/www/extsuite/extmail/webmail.cf

    2、修改主配置文件
         #vi /var/www/extsuite/extmail/webmail.cf

    部分修改选项的说明:

############################################################################################

SYS_MESSAGE_SIZE_LIMIT = 5242880
用户可以发送的最大邮件
SYS_USER_LANG = en_US
语言选项,可改作:
SYS_USER_LANG = zh_CN

SYS_MAILDIR_BASE = /home/domains
此处即为您在前文所设置的用户邮件的存放目录,可改作:
SYS_MAILDIR_BASE = /var/mailbox

SYS_MYSQL_USER = db_user
SYS_MYSQL_PASS = db_pass
以上两句句用来设置连接数据库服务器所使用用户名、密码和邮件服务器用到的数据库,这里修改为:
SYS_MYSQL_USER = extmail
SYS_MYSQL_PASS = extmail

SYS_MYSQL_HOST = localhost
指明数据库服务器主机名,这里默认即可

SYS_MYSQL_TABLE = mailbox
SYS_MYSQL_ATTR_USERNAME = username
SYS_MYSQL_ATTR_DOMAIN = domain
SYS_MYSQL_ATTR_PASSWD = password

以上用来指定验正用户登录里所用到的表,以及用户名、域名和用户密码分别对应的表中列的名称;这里默认即可

SYS_AUTHLIB_SOCKET = /var/spool/authdaemon/socket
此句用来指明authdaemo socket文件的位置,这里修改为:
SYS_AUTHLIB_SOCKET = /usr/local/courier-authlib/var/spool/authdaemon/socket

########################################################################################
    3   apache相关配置

     由于extmail要进行本地邮件的投递操作,故必须将运行apache服务器用户的身份修改为您的邮件投递代理的用户;本例中打开了apache服务器的suexec功能,故使用以下方法来实现虚拟主机运行身份的指定。此例中的MDA为postfix自带,因此将指定为postfix用户:
<VirtualHost *:80>
ServerName mail.neo.com
DocumentRoot /var/www/extsuite/extmail/html/
ScriptAlias /extmail/cgi /var/www/extsuite/extmail/cgi
Alias /extmail /var/www/extsuite/extmail/html
SuexecUserGroup postfix postfix
</VirtualHost>

 修改 cgi执行文件属主为apache运行身份用户:
 # chown -R postfix.postfix /var/www/extsuite/extmail/cgi/

 如果您没有打开apache服务器的suexec功能,也可以使用以下方法解决:
 # vim /etc/httpd/httpd.conf
 User postfix
 Group postfix

<VirtualHost *:80>
ServerName mail.neo.com
DocumentRoot /var/www/extsuite/extmail/html/
ScriptAlias /extmail/cgi /var/www/extsuite/extmail/cgi
Alias /extmail /var/www/extsuite/extmail/html
</VirtualHost>


    4   依赖关系的解决

 extmail将会用到perl的Unix::syslogd功能,您可以去http://search.cpan.org搜索下载原码包进行安装。
 # tar zxvf Unix-Syslog-0.100.tar.gz
 # cd Unix-Syslog-0.100
 # perl Makefile.PL
 # make && make install

5、启动apache服务
 # service httpd start
 # chkconfig httpd on


   5  安装Extman-1.1

1、安装及基本配置

 # tar zxvf  extman-1.1.tar.gz
 # mv extman-1.1 /var/www/extsuite/extman

 修改配置文件以符合本例的需要:
 # cp /var/www/extsuite/extman/webman.cf.default  /var/www/extsuite/extman/webman.cf
 # vi /var/www/extsuite/extman/webman.cf

############################################################################################

 SYS_MAILDIR_BASE = /home/domains
 此处即为您在前文所设置的用户邮件的存放目录,可改作:
 SYS_MAILDIR_BASE = /var/mailbox

 SYS_DEFAULT_UID = 1000
 SYS_DEFAULT_GID = 1000
 此两处后面设定的ID号需更改为前而创建的postfix用户和postfix组的id号,本文使用的是2525,因此,上述两项需要修改为:
 SYS_DEFAULT_UID = 2525
 SYS_DEFAULT_GID = 2525

 SYS_MYSQL_USER = webman
 SYS_MYSQL_PASS = webman
 修改为:
 SYS_MYSQL_USER = extmail
 SYS_MYSQL_PASS = extmail

##############################################################################################

 而后修改cgi目录的属主:
 # chown -R postfix.postfix /var/www/extsuite/extman/cgi/

 在apache的主配置文件中Extmail的虚拟主机部分,添加如下两行:
 ScriptAlias /extman/cgi /var/www/extsuite/extman/cgi
 Alias /extman /var/www/extsuite/extman/html

 创建其运行时所需的临时目录,并修改其相应的权限:
 #mkdir  -pv  /tmp/extman
 #chown postfix.postfix  /tmp/extman

 修改
  SYS_CAPTCHA_ON = 1
 为
  SYS_CAPTCHA_ON = 0

 好了,到此为止,重新启动apache服务器后,您的Webmail和Extman已经可以使用了,可以在浏览器中输入指定的虚拟主机的名称进行访问,如下:
   http://mail.neo.com

 选择管理即可登入extman进行后台管理了。默认管理帐号为:root@extmail.org  密码为:extmail*123*

 说明:
  (1) 如果您安装后无法正常显示校验码,安装perl-GD模块会解决这个问题。如果想简单,您可以到以下地址下载适合您的平台的rpm包,安装即可:  http://dries.ulyssis.org/rpm/packages/perl-GD/info.html
  (2) extman-1.1自带了图形化显示日志的功能;此功能需要rrdtool的支持,您需要安装此些模块才可能正常显示图形日志。


    6   配置Mailgraph_ext,使用Extman的图形日志:(下面所需的软件包面要自己下载)

 接下来安装图形日志的运行所需要的软件包Time::HiRes、File::Tail和rrdtool,其中前两个包您可以去http://search.cpan.org搜索并下载获得,后一个包您可以到 http://oss.oetiker.ch/rrdtool/pub/?M=D下载获得; 注意安装顺序不能改换。

 安装Time::HiRes
  #tar zxvf Time-HiRes-1.9707.tar.gz
  #cd Time-HiRes-1.9707
  #perl Makefile.PL
  #make
  #make test &&make install

 7  安装File::Tail
  #tar zxvf File-Tail-0.99.3.tar.gz
  #cd File-Tail-0.99.3
  #perl Makefile
  #make &&make install

8   安装rrdtool-1.2.23
  #tar zxvf rrdtool-1.2.23.tar.gz
  #cd rrdtool-1.2.23
  #./configure --prefix=/usr/local/rrdtool
  #make &&make install

 创建必要的符号链接(Extman会到这些路径下找相关的库文件)
  #ln -sv /usr/local/rrdtool/lib/perl/5.8.5/i386-linux-thread-multi/auto/RRDs/RRDs.so   /usr/lib/perl5/5.8.5/i386-linux-thread-multi/
  #ln -sv /usr/local/rrdtool/lib/perl/5.8.5/RRDp.pm   /usr/lib/perl5/5.8.5
  #ln -sv /usr/local/rrdtool/lib/perl/5.8.5/i386-linux-thread-multi/RRDs.pm   /usr/lib/perl5/5.8.5

 复制mailgraph_ext到/usr/local,并启动之
  # cp -r /var/www/extsuite/extman/addon/mailgraph_ext  /usr/local  
  # /usr/local/mailgraph_ext/mailgraph-init start

 启动cmdserver(在后台显示系统信息)
  # /var/www/extsuite/extman/daemon/cmdserver --daemon

 添加到自动启动队列
  # echo “/usr/local/mailgraph_ext/mailgraph-init start” >> /etc/rc.d/rc.local
  # echo “/var/www/extsuite/extman/daemon/cmdserver -v -d” >> /etc/rc.d/rc.local



-------------------------------本文为学习笔记,经本人亲试,完美成功-------------------------------------------