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目录下。比较重要的运行程序如下:
1.qmail-smtpd
它的作用是接收远端主机投递的邮件,然后将邮件传递给qmail-queue进行处理。qmail-smtpd是通过SMTP协议和远端主机惊醒通讯的。qmail-smtpd并不是常驻内存的,他需要一个外部程序来激活,本文所做的系统是使用tcpserver来激活的。Tcpserver监视着系统的IP连接请求,如果检测到有SMTP的连接请求,tcpserver就会自动的激活qmail-smtpd,然后将IP连接的控制权交给qmail-smtpd,一旦qmail-smtpd和远端主机建立起SMTP连接后,远端主机就可以将邮件投递到本地的邮件服务器了。
2.qmail-inject
它的作用是接收本地生成并投递的邮件,并把邮件传递给qmail-queue来处理。在邮件传递给qmail-queue之前,qmail-inject先扫面邮件的邮件头,来查看邮件头是否符合RFC822标准,如果不符合它将会自动的更改和修正这个邮件的邮件头。
3.qmail-send
当一个邮件被放入邮件队列之后,qmail-send就开始对该邮件进行处理,。它会检查邮件队列中的每一个邮件的状态,对于没有投递过的和投递暂时失败的邮件,对于没有投递过和投递暂时失败的邮件,qmail-send会将目标地址是本地主机的传递给qmail-lspawn,目标地址是远端主机的传递给qmail-rspawn,对于投递永久失败的邮件,qmail-send将会把该邮件传递给qmail-clear,让这个程序永久删除这个邮件。qmail-send是一个常驻内存进程程序,如果qmail-send中止,qmail的其他进程将会自动中止。
4.qmail-clean
它的作用是从邮件队列中删除投递永久失败的邮件。qmail使用多种状态标示来标记邮件,每个邮件在每一次被处理后它的状态表示都会被改变。如果系统当机,系统重新启动以后,qmail-send仍然可以找到邮件队列中上次最后一次成功处理过的邮件的位置,并且从这里重新开始处理邮件队列。如果由于其他原因造成qmail-send不能处理的邮件队列,qmail-send会调用qmail-clean从邮件队列中删除邮件。qmail-clean也是常驻内存的进程。
5.qmail-rspawn
当qmail-send判明邮件目标地址是远端邮件服务器时,qmail-send就会将邮件交给qmail-rspawn,qmail-rspawn的作用是调度邮件的投递时间和顺序,然后激活qmail-remote来进行投递。qmail-rspawn还有一个作用是决定每一个邮件的目标邮件服务器,每次和远端邮件服务器的连接都会调用qmail-remote一次。qmail-rspawn也是常驻内存的进程。
6.qmail-lspawn
功能和qmail-rspawn类似,qmail-lspawn也是被qmail-send调度来投递邮件的,不过qmail-lspawn是负责目标地址是为本地邮件服务器的邮件。
7.qmail-remote
它的作用是通过SMTP协议将邮件投递到远端的用户。邮件是通过qmail-rspawn传递过来的,qmail-remote每次只可以同一个远端主机连接,不过在连接时qmail-remote可以投递这个远端主机上的多个接收者的邮件。投递当中的调度是由qmail-rspamwn来负责的。
8.qmail-local
它的作用是投递本地邮件服务器的邮件。这个程序通常是用来检测因为转发命令使用不当造成的邮件循环故障。
9.qmail-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) |