Chinaunix首页 | 论坛 | 博客
  • 博客访问: 292505
  • 博文数量: 84
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: -10
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-05 09:11
文章分类
文章存档

2015年(1)

2014年(6)

2013年(8)

2012年(1)

2011年(6)

2010年(2)

2009年(16)

2008年(44)

我的朋友

分类: LINUX

2008-06-02 01:20:40

qmail邮件投递工作基本原理
==========================================
qmail系统中有9个核心程序,这里简单的介绍一下。qmail-smtpd负责接收来自远程主机的邮件消息并将它们传送给qmail-queue处理。qmail-inject程序是用来接收本地产生的邮件消息并传送给qmail-queue程序。qmai-queue程序处理他们发来的邮件,移进邮件队列以便发送。一旦消息被成功的放在邮件队列中,就调用qmail-send程序来处理他。qmail-send检查邮件队列中每一个消息状态,前一次邮件请求失败的消息被识别,并决定它是临时失败还是永久的,临时失败会再次投递,永久失败将被送递到qmail-clean程序,被删除掉。也就是说,qmail-clean实用来清除永久失败的的邮件消息的。
qmail-send调用了qmail-lspawn 和qmail-rspawn程序。qmail-send判断邮件是发给谁的,发给本地的,就交给qmail-lspawn程序,再由qmail-local投送到本地邮件服务器。要是确定为远程主机,就调用qmail-rspawn程序,qmail-rspawn为每一个邮件消息的接受方决定目的的邮件服务器,再调用qmail-remote程序发送。

qmail是一个模块化设计的邮件系统,每一个子功能都是由一个运行程序来实现的,而每个程序的属性以及运行方式由一个或多个配置文件和环境变量来控制的。在qmail安装成功和启动以后,qmail的相关进程一直在内存中驻留,qmail会不断扫描邮件队列,并且把邮件投递到正确的目的地址。
  运行ps命令可以查看到qmail的相关进程:
  #ps –ax | grep qmail
  0:00.00 grep qmail
  23282 con- I 0:00.77 qmail-send
  23289 con- I 0:00.21 splogger qmail
  23290 con- I 0:00.13 qmail-lspawn ./Mialdir/
  23291 con- I 0:00.03 qmail-rspawn
  23292 con- I 0:00.05 qmail-clean
  qmail所有的运行程序都安装在/var/qmail/bin目录下。比较重要的运行程序如下:
1qmail-smtpd
  它的作用是接收远端主机投递的邮件,然后将邮件传递给qmail-queue进行处理。qmail-smtpd是通过SMTP协议和远端主机惊醒通讯的。qmail-smtpd并不是常驻内存的,他需要一个外部程序来激活,本文所做的系统是使用tcpserver来激活的。Tcpserver监视着系统的IP连接请求,如果检测到有SMTP的连接请求,tcpserver就会自动的激活qmail-smtpd,然后将IP连接的控制权交给qmail-smtpd,一旦qmail-smtpd和远端主机建立起SMTP连接后,远端主机就可以将邮件投递到本地的邮件服务器了。
2qmail-inject
  它的作用是接收本地生成并投递的邮件,并把邮件传递给qmail-queue来处理。在邮件传递给qmail-queue之前,qmail-inject先扫面邮件的邮件头,来查看邮件头是否符合RFC822标准,如果不符合它将会自动的更改和修正这个邮件的邮件头。
3qmail-send
  当一个邮件被放入邮件队列之后,qmail-send就开始对该邮件进行处理,。它会检查邮件队列中的每一个邮件的状态,对于没有投递过的和投递暂时失败的邮件,对于没有投递过和投递暂时失败的邮件,qmail-send会将目标地址是本地主机的传递给qmail-lspawn,目标地址是远端主机的传递给qmail-rspawn,对于投递永久失败的邮件,qmail-send将会把该邮件传递给qmail-clear,让这个程序永久删除这个邮件。qmail-send是一个常驻内存进程程序,如果qmail-send中止,qmail的其他进程将会自动中止。
4qmail-clean
  它的作用是从邮件队列中删除投递永久失败的邮件。qmail使用多种状态标示来标记邮件,每个邮件在每一次被处理后它的状态表示都会被改变。如果系统当机,系统重新启动以后,qmail-send仍然可以找到邮件队列中上次最后一次成功处理过的邮件的位置,并且从这里重新开始处理邮件队列。如果由于其他原因造成qmail-send不能处理的邮件队列,qmail-send会调用qmail-clean从邮件队列中删除邮件。qmail-clean也是常驻内存的进程。
5qmail-rspawn
  当qmail-send判明邮件目标地址是远端邮件服务器时,qmail-send就会将邮件交给qmail-rspawn,qmail-rspawn的作用是调度邮件的投递时间和顺序,然后激活qmail-remote来进行投递。qmail-rspawn还有一个作用是决定每一个邮件的目标邮件服务器,每次和远端邮件服务器的连接都会调用qmail-remote一次。qmail-rspawn也是常驻内存的进程。
6qmail-lspawn
  功能和qmail-rspawn类似,qmail-lspawn也是被qmail-send调度来投递邮件的,不过qmail-lspawn是负责目标地址是为本地邮件服务器的邮件。
7qmail-remote
  它的作用是通过SMTP协议将邮件投递到远端的用户。邮件是通过qmail-rspawn传递过来的,qmail-remote每次只可以同一个远端主机连接,不过在连接时qmail-remote可以投递这个远端主机上的多个接收者的邮件。投递当中的调度是由qmail-rspamwn来负责的。
8qmail-local
  它的作用是投递本地邮件服务器的邮件。这个程序通常是用来检测因为转发命令使用不当造成的邮件循环故障。
9qmail-queue
  他处理从qmail-inject和qmail-smtpd传递过来的邮件,并把这些邮件传递到邮件队列中,它会扫描每个邮件的发送者和接收者的地址,一般传递给qmail-queue的邮件的标示都是为0,如果为1时,它会认为这个邮件的发送者和接收者的地址要经过特殊格式的处理。



 
模块 功能
qmail-smtpd 接收/拒收通过SMTP传递的邮件
qmail-inject 本地邮件注入
qmail-rspawn/qmail-remote 控制远程传输
qmail-lspawn/qmail-local 控制本地传输
qmail-send 处理队列
qmail-clean 清除队列
=============================================================
 
添加qmail所需要的用户和组
groupadd nofiles
groupadd qmail
groupadd vchkpw
groupadd logadmin
useradd qmaild -g nofiles -d /var/qmail -s /nonexistent
useradd alias -g nofiles -d /var/qmail/alias -s /nonexistent
useradd qmaill -g nofiles -d /var/qmail -s /nonexistent
useradd qmailp -g nofiles -d /var/qmail -s /nonexistent
useradd qmailq -g qmail -d /var/qmail -s /nonexistent
useradd qmailr -g qmail -d /var/qmail -s /nonexistent
useradd qmails -g qmail -d /var/qmail -s /nonexistent
useradd vpopmail -g vchkpw -d /home/vpopmail -s /nonexistent
useradd logamdin -g logadmin -d /home/logadmin -s /nonexistent



或者

    pw groupadd nofiles  -g 7001 
    pw groupadd qmail    -g 7002 
    pw groupadd vchkpw   -g 7003 
    pw groupadd logadmin -g 9001 
 
    pw useradd alias    -u 7001 -g nofiles  -d /var/qmail/alias    -s /bin/true  
    pw useradd qmaild   -u 7002 -g nofiles  -d /var/qmail          -s /bin/true 
    pw useradd qmaill   -u 7003 -g nofiles  -d /var/qmail          -s /bin/true 
    pw useradd qmailp   -u 7004 -g nofiles  -d /var/qmail          -s /bin/true 
    pw useradd qmailq   -u 7005 -g qmail    -d /var/qmail          -s /bin/true 
    pw useradd qmailr   -u 7006 -g qmail    -d /var/qmail          -s /bin/true  
    pw useradd qmails   -u 7007 -g qmail    -d /var/qmail          -s /bin/true 
    pw useradd vpopmail -u 7008 -g vchkpw   -d /home/vpopmail   -m -s /bin/true 
    pw useradd logadmin -u 9001 -g logadmin -d /home/logadmin      -s /bin/true 



======================================================================
解压安装
tar -zxvf netqmail-1.05.tar.gz
cd /usr/local/netqmail-1.05
./collate.sh
cd /usr/local/netqmail-1.05/netqmail-1.05
make setup check
./config-fast 主机名    (如果后面加test.com,则发信的时候发件人是root@test.com,跟主机名,发件人就是root@hostname.hostname)
echo "&postmaster@test.com" > .qmail-postmaster 
echo "&postmaster" > .qmail-root 
echo "&postmaster" > .qmail-mailer-daemon 
到此安装完成
echo "lili@aaa.com" > .qmail-postmaster (这样如果系统发送邮件失败会给lili发送封退信的邮件)
=======================================================================
启动qmail
adduser logadmin
mkidr -p /var/qmail/supervise/qmail-send
cd /var/qmail/supervise/qmail-send
 
===================================================
cat run
#!/bin/sh
PATH=/var/qmail/bin:/home/vpopmail/bin:/usr/local/bin:/usr/bin:/bin
export PATH
sleep 10
exec env - PATH=$PATH \
qmail-start ./Maildir/ 2>&1
====================================================
mkdir -p /var/qmail/supervise/qmail-send/log
mkdir -p /var/qmail/supervise/qmail-send/log/main
touch /var/qmail/supervise/qmail-send/log/status
chown logadmin:logadmin /var/qmail/supervise/qmail-send/log/status
chown logadmin:logadmin /var/qmail/supervise/qmail-send/log/main
cd /var/qmail/supervise/qmail-send/log
cat run
#!/bin/sh
exec setuidgid logadmin multilog t s10000000 n1000 ./main
===================================================
nohup ./run &
[root@localhost qmail-send]# ps aux|grep qmail
qmails    3616  0.0  0.3   1592   396 pts/0    S    20:46   0:00 qmail-send
root      3621  0.0  0.2   1560   340 pts/0    S    20:46   0:00 qmail-lspawn ./Maildir/
qmailr    3622  0.0  0.2   1556   352 pts/0    S    20:46   0:00 qmail-rspawn
qmailq    3623  0.0  0.2   1548   360 pts/0    S    20:46   0:00 qmail-clean
root      3652  0.0  0.3   1684   500 pts/0    R+   20:48   0:00 grep qmail
===========================================
发信
[root@localhost qmail]# ll /usr/sbin/sendmail
lrwxrwxrwx  1 root root 21 Dec 14 13:19 /usr/sbin/sendmail -> /etc/alternatives/mta
rm -rf /usr/sbin/sendmail 删除原来的连接
 
 
安装Qmail的Sendmail外壳
ln -s /var/qmail/bin/sendmail  /usr/sbin/sendmail 建立新连接
 
只有建立上面的连接才可以这样发信
mail -s "test" < aa 发信成功
======================================================
以上是简单安装只能投递本地用户的邮件
======================================================
 
qmail-smtpd投递远端用户邮件,具有储转功能
 
cd /var/qmail/supervise/qmail-smtpd
[root@localhost qmail-smtpd]# cat run
#!/bin/sh
PATH=/var/qmail/bin:/home/vpopmail/bin:/usr/local/bin:/usr/bin:/bin
export PATH
sleep 10
_rule=/home/vpopmail/etc/tcp.smtp.cdb
exec env - PATH=$PATH \
envuidgid qmaild tcpserver -HRDl0 -U -x $_rule 0 smtp \
qmail-smtpd 2>&1
======================================================
启动前提条件
因为run文件用到envuidgid所以要首先安装daemontools,以tcpserver启动
所以要安装tcpserver
 
 
echo '127.:allow,RELAYCLIENT=""' > /home/vpopmail/etc/tcp.smtp
cd /home/vpopmail/etc/
tcprules tcp.smtp.cdb tcp.smtp.tmp < tcp.smtp
nohup ./run &
 
[root@localhost qmail-smtpd]# ps aux|grep qmail
qmaild    8108  0.0  0.4   1620   508 pts/0    S    22:18   0:00 tcpserver -HRDl0 -U -x /home/vpopmail/etc/tcp.smtp.cdb 0 smtp qmail-smtpd
[root@localhost qmail-smtpd]# netstat -ant|grep 25
tcp        0      0 0.0.0.0:25                  0.0.0.0:*                   LISTEN
 
=======================================================
qmail-pop3d收信服务器
 
首先安装tcpserver,qmail-pop3d用tcpserver启动
添加用户和组
groupadd vchkpw
useradd vpopmail -g vchkpw -d /home/vpopmail -s /nonexistent
 
cd /var/qmail/supervise/qmail-pop3d
[root@localhost qmail-pop3d]# cat run
#!/bin/sh
PATH=/var/qmail/bin:/home/vpopmail/bin:/usr/local/bin:/usr/bin:/bin
export PATH
sleep 10
_host=`hostname`
echo $_host
_fqdn=`dnsfq $_host`
echo $_fqdn
exec env - PATH=$PATH \
tcpserver -HRDl0 -u vpopmail -g vchkpw 0 pop3 \
qmail-popup $_fqdn vchkpw qmail-pop3d Maildir 2>&1
==================================================
正式环境配置文件
[root@prmail01 qmail-pop3d]# cat run
#!/bin/sh
PATH=/var/qmail/bin:/home/vpopmail/bin:/usr/local/bin:/usr/bin:/bin
export PATH
sleep 10
_host=`hostname`
echo $_host
_fqdn=`dnsfq $_host`
echo $_fqdn
exec env - PATH=$PATH \
tcpserver -HRDl0 -u vpopmail -g vchkpw 0 pop3 \
qmail-popup mail.min-fx.tv vchkpw qmail-pop3d Maildir 2>&1
===================================================
  • qmail-popup: 取得用户名/密码
  • checkpassword: 鉴别用户名/密码
  • qmail-pop3d: POP后台服务程序
  • qmail-popup由inetd 或者 tcpserver运行, 在110端口监听, 一旦有连接, 它将提示输入用户名和密码, 然后它调用checkpassword来校验用户名/密码, 通过校验后调用qmail-pop3d.

    nohup ./run &

    [root@localhost qmail-pop3d]# ps aux|grep tcpserver

    root      3704  0.0  0.3   1616   496 pts/0    S    20:52   0:00 tcpserver -HRDl0 -u vpopmail -g vchkpw 0 pop3 qmail-popup vchkpw qmail-pop3d Maildir
     
    [root@localhost qmail-pop3d]# netstat -ant|grep 110
    tcp        0      0 0.0.0.0:110                 0.0.0.0:*                   LISTEN    
    =============================================================
    vpopmail安装
    tar -xzf tar/vpopmail-5.4.10.tar.gz
    cd vpopmail-5.4.10
    ./configure --enable-logging=v
    make
    make install-strip
    编译之前要添加用户否则会编译失败
    添加用户和组
    groupadd vchkpw
    useradd vpopmail -g vchkpw -d /home/vpopmail -s /nonexistent
    添加虚拟域
    /home/vpopmail/bin/vadddomain aaa.com
     添加用户
    ./vadduser cc设置客户端,可以接受发送给cc@aaa.com的邮件
    ============================================================
     qmailadmin——WEB方式管理qmail
    涉及到的软件:ezmlm autorespond qmailAdmin
    tar zxvf ezmlm-0.53-idx-0.41.tar.gz
    cd ezmlm-0.53-idx-0.41
    echo "/var/qmail/bin/ezmlm" > conf-bin
    make && make setup


     ezmlm   另一种安装方法 (下载的安装包ezmlm-0.53.tar.gz有可能安装不上
     tar zxf ezmlm-0.53.tar.gz       
     tar zxf ezmlm-idx-0.40.tar.gz 
     mv ezmlm-idx-0.40/* ezmlm-0.53/. 
     rmdir ezmlm-idx-0.40 
     cd ezmlm-0.53 
     patch < idx.patch 
     make clean 
     echo "/var/qmail/bin/ezmlm" > conf-bin 
     make
     make man 
     make jp
     make setup


    tar zxvf autorespond-2.0.5.tar.gz
    cd autorespond-2.0.5
    make && make install
     
    tar zxvf qmailadmin-1.2.9.tar.gz
    cd qmailadmin-1.2.9
    ./configure --enable-cgibindir=/usr/local/apache/cgi-bin/ --enable-htmldir=/usr/local/apache/htdocs/
    make && make install-strip
     
    :postmaster
    域名称:aaa.com
    密码:   域密码
     进入页面创建列表的时候选择 (人和人可以发布)否则会失败。


    :zhang
    域名称:aaa.com
    密码   :邮箱密码
    用postmaster登陆可以创建 删除邮箱等。。。。
    用zhang登陆只能修改密码


    在命令行下创建邮件列表
    /usr/local/bin/ezmlm/ezmlm-make /home/vpopmail/domains/aaa.com/maillist /home/vpopmail/domains/aaa.com/.qmail-maillist maillist aaa.com 
    /usr/local/bin/ezmlm/ezmlm-sub /home/vpopmail/domains/aaa.com/maillist lili@aaa.com
    chown -R vpopmail:vchkpw /home/vpopmail/domains/aaa.com/maillist
    在列表maillist@aaa.com中添加成员: 
    lili@aaa.com
    当然如果你使用了qmailadmin,那就更方便了.^_^

    =========================================================
     
    checkpassword 和 vpopmail 两种验证方式
    checkpassword 对/etc/passwd中的用户开放mail,安装完成后生成在/bin/checkpassword
    vpopmail      不对/etc/passwd中的用户开放mail,安装完成后生成在/home/vpopmail/bin/vchkpw
    以上两种pop3启动的时候可以任意选择一种
     
     
    checkpassword安装(pop3验证用户程序)
    tar xzvf checkpassword-0.90.tar.gz
    cd checkpassword-0.90
    patch -p1
    make
    make setup check

     
     
     
     
    =========================================================
    邮件转发设置:
    10.18.20.45上设置
    cd /var/qmail/control/
    touch smtproutes
    :[10.18.20.42]

    说明:在42上已经启动了qmail-send qmail-smtpd,qmail-pop3d (必须启动qmail-smtpd)(在45上只启动了qmail-send,并在/var/qmail/control/smtproutes文件里设置了:[10.18.20.42]),含义是,在.45上发一封邮件
    是通过42进行转发的,此时还需要在10.18.20.42上,在/var/qmail/control/rcpthosts文件里加入发送邮件的域名例如:aaa.com
    (意思是如许通过服务器42转发任何发往aaa.com的邮件)

    ==========================================================
     
    给虚拟域上的用户发邮件,如果客户端没有接受则里面就多一个邮件
    直到客户端接受后,邮件在里面删除
    mail -s "test" < /home/wangzm/logs
    /home/vpopmail/domains/aaa.com/wangzm/Maildir/new
    [root@localhost new]# ls
    1179927466.29413.localhost.localdomain,S=238
    [root@localhost new]# cat 1179927466.29413.localhost.localdomain,S=238
    Return-Path: <>
    Delivered-To:
    Received: (qmail 29411 invoked by uid 0); 23 May 2007 13:37:46 -0000
    Date: 23 May 2007 13:37:46 -0000
    Message-ID: <>
    From:
    To:
    Subject: test
    hello
    =============================================================
    daemontools启动qmail
    ln -s /var/qmail/supervise/qmail-send   /service/qmail-send
    ln -s /var/qmail/supervise/qmail-smtpd /service/qmail-smtpd
    ln -s /var/qmail/supervise/qmail-pop3d /service/qmail-pop3d
     
    说明:刚开始的时候在log目录里可能不会自动生成supervise,它的作用,supervise的一个重要的功能就是可以检测出run脚本中执行的程序是否正常工作,若发现其已经死掉,supervise将会重新执行run脚本,重新启动指定程序
    这时候
    [root@localhost log]# ps aux|grep svs
    root     19736  0.0  0.8   2304  1068 ?        Ss   16:23   0:00 /bin/sh /command/svscanboot
    root     19738  0.0  0.2   1580   360 ?        S    16:23   0:00 svscan /service
    root     19896  0.0  0.3   1684   500 pts/0    R+   16:24   0:00 grep svs
     kill -9 19736  把该进程挺掉让其自动重起/bin/sh /command/svscanboot 这时候就会在log目录生成supervise,才会往其目录里写日志
    停止qmail-send
    [root@localhost main]# svc -d /service/qmail-send/
    [root@localhost main]# ps aux|grep qmail
    root      3276  0.1  0.2   1420   300 ?        S    13:28   0:04 supervise qmail-smtpd
    启动qmail-send
    [root@localhost main]# svc -u /service/qmail-send/
    [root@localhost main]# ps aux|grep qmail
    root      3252  0.0  0.2   1416   300 ?        S    13:28   0:01 supervise qmail-send
    qmails    3558  0.5  0.3   1596   384 ?        S    14:17   0:00 qmail-send
    root      3589  0.0  0.2   1560   348 ?        S    14:17   0:00 qmail-lspawn ./Maildir/
    qmailr    3590  0.0  0.2   1556   336 ?        S    14:17   0:00 qmail-rspawn
    qmailq    3591  0.0  0.2   1548   348 ?        S    14:17   0:00 qmail-clean
    root      3594  0.0  0.4   1684   504 pts/1    S+   14:17   0:00 grep qmail
    重起qmail-send
    [root@localhost main]# svc -t /service/qmail-send/
    =========================================================
    qmail-smtp qmail-pop3d 和qmail-send一样
    有时候 svc -u /service/*   程序启动不起来,可以试着把svscanboot,svscan kill 掉
    在启动 nohup /usr/local/bin/svscanboot &
     
    下面是一段从本地系统发送一个邮件到远程系统的日志片断:
    1 @4000000038c3eeb027f41c7c new msg 93869
    2 @4000000038c3eeb027f6b0a4 info msg 93869: bytes 2343 from qp 18695 uid 49491
    3 @4000000038c3eeb02877ee94 starting delivery 2392: msg 93869 to remote lwq@w3.to
    4 @4000000038c3eeb0287b55ac status: local 0/10 remote 1/20
    5 @4000000038c3eeb104a13804 delivery 2392: success: 209.85.127.177_accepted_message.
       /Remote_host_said:_250_CAA01516_Message_accepted_for_delivery/
    6 @4000000038c3eeb104a4492c status: local 0/10 remote 0/20
    7 @4000000038c3eeb104a6ecf4 end msg 93869
    第 1 行指出qmail接收到一条新邮件, 邮件的队列ID是93869. 队列ID是 /var/qmail/queue/mess/NN/ 包含这个邮件的队列文件的 i-node 节点值. 队列ID将在这个消息存在于队列的过程中保持全局唯一.
    第 2 行表明邮件来自 dave@sill.org, 并且大小为2343字节.
    第 3 行表明qmail-remote开始传送这个邮件到lwq@w3.to, 并且为这个传送指定了ID 2392.
    第 4 行指出 0 个本地传送和 1 个远程传送处于等待状态.
    第 5 行显示出 ID 2392 这个传送已经成功完成, 并且返回远程主机的回应, 这个回应里面常常包含了远程邮件管理员对于跟踪这个传送的有用信息. 在我们这个例子里面, "CAA01516"是远程系统的传送ID.
    第 6 行指出 0 个本地传送和 0个远程传送处于等待状态. 也就是传送已经完成了.
    第 7 行指出这个消息已经被传送完毕并且被移出队列. 这个时候, 队列ID 93869, 已经可以重用于其他传送ID了.
    ========================================================================
    给一个地址不存在发信笺,日志有如下内容
     
    mail -s test < run         该地址不存在
     
    [root@localhost bin]# ./qmail-qstat
    messages in queue: 1
    messages in queue but not yet preprocessed: 0
     
    [root@localhost bin]#cat /service/qmail-send/log/main/current
    @400000004660c15b1e0d94a4 new msg 7030045
    @400000004660c15b1e0db7cc info msg 7030045: bytes 293 from <> qp 8962 uid 0
    @400000004660c15b1eac8bf4 starting delivery 20: msg 7030045 to remote
    @400000004660c15b1eb50fa4 status: local 0/10 remote 1/20
     
     
     
    [root@localhost bin]# ./qmail-qread
    2 Jun 2007 01:01:05 GMT  #7030045  293  <>
            remote 
     
     
    =======================================================
     
    查看qmail列的成员列表
    /var/qmail/bin/ezmlm/ezmlm-list  /home/vpopmail/domains/min-fx.tv/information
    ========================================================
     

     
    参考文档
     
    ==========================================================

    阅读(2581) | 评论(1) | 转发(0) |
    给主人留下些什么吧!~~

    chinaunix网友2010-11-04 16:14:29

    wq vb