postfix-队列跟踪与队列管理_第1页
postfix-队列跟踪与队列管理_第2页
postfix-队列跟踪与队列管理_第3页
postfix-队列跟踪与队列管理_第4页
postfix-队列跟踪与队列管理_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

用strace来跟踪mail程序的系统调用过程来进行证实,如下:strace-fF-o/tmp/sendmailmail-s"test"21488275@查看打开的文件和执行的程序,如下:egrep'open|execve'/tmp/sendmail

2791

execve("/bin/mail",["mail","-s","test","21488275@"],[/*22vars*/])=0略2792

execve("/usr/sbin/sendmail",["send-mail","-i","21488275@"],[/*22vars*/])=0略2793

execve("/usr/sbin/postdrop",["/usr/sbin/postdrop","-r"],[/*2vars*/])=0略2793

open("maildrop/196313.2793",O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE,0644)=4略2793

open("public/pickup",O_WRONLY|O_NONBLOCK|O_LARGEFILE)=4上面我们知道pickup服务通过管道的方式获知有新邮件到达,此时它读取/var/spool/postfix/maildrop目录下的新邮件,并将新邮件交给cleanup服务,cleanup服务与trivial-rewrite对邮件的格式进行整理重写.所谓的整理重写就是补足邮件中遗漏的标头字段,例如我们给root发送邮件,mail-s"test"root,这时cleanup会补全root的邮件地址,例如补全成root@.pickup服务与cleanup服务的通讯方式是socket套接字,我们通过strace来跟踪pickup的工作过程,如下:strace-fF-p2688-o/tmp/pickup发送邮件mail-s"test"root

test.EOT查看系统调用,如下:tail-f/tmp/pickup3246

alarm(6000)

=59753246

time(NULL)

=13103410183246

epoll_wait(8,{{EPOLLIN,{u32=6,u64=15683691556634630}}},100,75000)=13246

time(NULL)

=13103410283246

write(5,"\256\f\0\0\1\0\0\0\0\0\0\0",12)=123246

read(6,"W",1024)

=13246

open("maildrop",O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC)=93246

getdents64(9,/*3entries*/,32768)=803246

lstat64("maildrop/7C3EA163C51",{st_mode=S_IFREG|0744,st_size=277,...})=03246

open("maildrop/7C3EA163C51",O_RDONLY|O_NONBLOCK|O_LARGEFILE)=103246

fstat64(10,{st_mode=S_IFREG|0744,st_size=277,...})=03246

lstat64("maildrop/7C3EA163C51",{st_mode=S_IFREG|0744,st_size=277,...})=03246

socket(PF_FILE,SOCK_STREAM,0)

=113246

fcntl64(11,F_GETFL)

=0x2(flagsO_RDWR)3246

fcntl64(11,F_SETFL,O_RDWR)

=0#注意这里连接/var/spool/postfix/public/cleanup(UNIX套接字)与cleanup进行通讯3246

connect(11,{sa_family=AF_FILE,path="public/cleanup"},110)=0

3246

gettimeofday({1310341028,532931},NULL)=03246

poll([{fd=11,events=POLLIN}],1,3600000)=1([{fd=11,revents=POLLIN}])3246

read(11,"queue_id\00084E5D163C55\0\0",4096)=223246

gettimeofday({1310341028,544945},NULL)=03246

time(NULL)

=13103410283246

read(10,"T\0211310341028508906A\25rewrite_con"...,4096)=2773246

time(NULL)

=13103410283246

send(7,"<22>Jul1107:37:08postfix/pick"...,74,MSG_NOSIGNAL)=743246

stat64("/etc/localtime",{st_mode=S_IFREG|0644,st_size=405,...})=03246

_llseek(10,0,[277],SEEK_END)

=03246

poll([{fd=11,events=POLLOUT}],1,3600000)=1([{fd=11,revents=POLLOUT}])3246

write(11,"flags\000115\0\0T\0211310341028508906A\25"...,398)=3983246

gettimeofday({1310341028,546876},NULL)=03246

poll([{fd=11,events=POLLIN}],1,3600000)=1([{fd=11,revents=POLLIN|POLLHUP}])3246

read(11,"status\0000\0reason\0\0\0",4096)=183246

gettimeofday({1310341028,571577},NULL)=03246

close(10)

=03246

close(11)

=03246

unlink("maildrop/7C3EA163C51")

=0当postfix发现pickup连接cleanup套接字后,通过execve调用cleanup程序,并且通过socket的通讯方式进行接收处理该邮件.下面的系统调用说明了这一点:3321

execve("/usr/libexec/postfix/cleanup",["cleanup","-z","-t","unix","-u"],[/*4vars*/])=0略3321

socket(PF_NETLINK,SOCK_RAW,0)

=83321

bind(8,{sa_family=AF_NETLINK,pid=0,groups=00000000},12)=03321

getsockname(8,{sa_family=AF_NETLINK,pid=3321,groups=00000000},[12])=03321

time(NULL)

=13103414963321

sendto(8,"\24\0\0\0\22\0\1\3x9\32N\0\0\0\0\0\0\0\0",20,0,{sa_family=AF_NETLINK,pid=0,groups=00000000},12)=203321

recvmsg(8,{msg_name(12)={sa_family=AF_NETLINK,pid=0,groups=00000000},msg_iov(1)=[{"\250\1\0\0\20\0\2\0x9\32N\371\f\0\0\0\0\4\3\1\0\0\0I\0\1\0\0\0\0\0"...,4096}],msg_controllen=0,msg_flags=0},0)=12923321

recvmsg(8,{msg_name(12)={sa_family=AF_NETLINK,pid=0,groups=00000000},msg_iov(1)=[{"\24\0\0\0\3\0\2\0x9\32N\371\f\0\0\0\0\0\0\1\0\0\0I\0\1\0\0\0\0\0"...,4096}],msg_controllen=0,msg_flags=0},0)=203321

sendto(8,"\24\0\0\0\26\0\1\3y9\32N\0\0\0\0\0\0\0\0",20,0,{sa_family=AF_NETLINK,pid=0,groups=00000000},12)=203321

recvmsg(8,{msg_name(12)={sa_family=AF_NETLINK,pid=0,groups=00000000},msg_iov(1)=[{"0\0\0\0\24\0\2\0y9\32N\371\f\0\0\2\10\200\376\1\0\0\0\10\0\1\0\177\0\0\1"...,4096}],msg_controllen=0,msg_flags=0},0)=1683321

recvmsg(8,{msg_name(12)={sa_family=AF_NETLINK,pid=0,groups=00000000},msg_iov(1)=[{"@\0\0\0\24\0\2\0y9\32N\371\f\0\0\n\200\200\376\1\0\0\0\24\0\1\0\0\0\0\0"...,4096}],msg_controllen=0,msg_flags=0},0)=1283321

recvmsg(8,{msg_name(12)={sa_family=AF_NETLINK,pid=0,groups=00000000},msg_iov(1)=[{"\24\0\0\0\3\0\2\0y9\32N\371\f\0\0\0\0\0\0\1\0\0\0\24\0\1\0\0\0\0\0"...,4096}],msg_controllen=0,msg_flags=0},0)=20然后cleanup程序通过socket(unix套接字)与trivial-rewrite服务进行通讯,即postfix检查到cleanup连接到/var/spool/postfix/private/rewrite套接字文件后,再通过execve调用trivial-rewrite程序,完成最后的清理工作.经过cleanup处理好邮件后,邮件最后被传入收件队列,也就是/var/spool/postfix/incoming目录.例如这样一个邮件队列:/var/spool/postfix/incoming/711959.3321它还要将队列名字改名,如下:rename("incoming/711959.3321","incoming/AE07E163C55")=0最后队列管理器看到有新邮件已经入队,它确定是进行转发还是发送给本地用户,是转发还是本地的区别在用它连接使用的套接字文件,如下:本地发送:3247

connect(10,{sa_family=AF_FILE,path="private/local"},110)=0远程转发:3247

connect(13,{sa_family=AF_FILE,path="private/smtp"},110)=0值得注意的是队列管理器是独立的服务进程,如下:ps-ef|grepqmgr|grep-vgreppostfix

3247

3244

007:36?

00:00:00qmgr-l-tfifo-u最后确认我们这里是本地发送,所以postfix会用exec调用local程序完成本地邮件发送的工序,首先它会通过/etc/passwd和/etc/aliases.db来判断是否是当前系统用户或其别名,如是当前系统用户则接收存放邮件,并将文件写入到/var/mail/root下面,完成了最后的发送过程.2.3)来自网络的邮件这里分为两种,一种是外界寄给postfix所控制网域的邮件,这种情况smtpd一定会收下第一种邮件,如果收件人存在的话.第二种情况是目的地在其它网域,这种情况我们称为转发,这里先讨论第一种情况.外界寄给postfix时,postfix用smtpddaemon来处理接收外来邮件,然后通过socket文件将邮件传输给cleanup/trivial-rewrite对邮件进行规范处理,最后根据是本地用户邮件还是其它网域用户邮件选择执行对映的程序(本地是local,转发是smtp)首先我们在服务端用strace跟踪postfix进程,如下:ps-ef|greppostfixroot

2505

1

005:38?

00:00:00/usr/libexec/postfix/masterpostfix

2508

2505

005:38?

00:00:00qmgr-l-tfifo-upostfix

3066

2505

007:18?

00:00:00pickup-l-tfifo-uroot

3085

2569

007:26pts/1

00:00:00greppostfixstrace-fF-p2505

-o/tmp/postfix然后,我们在客户端用telnet命令连接服务端的postfix(MTA),发送邮件.telnet2825Trying28...Connectedto28.Escapecharacteris'^]'.220ESMTPPostfixhelo250mailfrom:<troy@>2502.1.0Okrcptto:<root@>2502.1.5Okdata354Enddatawith<CR><LF>.<CR><LF>test.2502.0.0Ok:queuedasDA43C163C53quit2212.0.0ByeConnectionclosedbyforeignhost.在服务端查看postfix的exec系统调用,如下:egrep'exec'/tmp/postfix|grep-vset_thread_area#注意:这里调用smtpddaemon进行邮件接收处理2718

execve("/usr/libexec/postfix/smtpd",["smtpd","-n","smtp","-t","inet","-u","-o","stress="],[/*4vars*/])=02719

execve("/usr/libexec/postfix/proxymap",["proxymap","-t","unix","-u"],[/*4vars*/])=02721

execve("/usr/libexec/postfix/trivial-rewrite",["trivial-rewrite","-n","rewrite","-t","unix","-u"],[/*4vars*/])=02722

execve("/usr/libexec/postfix/cleanup",["cleanup","-z","-t","unix","-u"],[/*4vars*/])=0#注意:这里调用local程序将邮件接收至本地2723

execve("/usr/libexec/postfix/local",["local","-t","unix"],[/*4vars*/])=0下面是转发的测试:telnet2825Trying28...Connectedto28.Escapecharacteris'^]'.220ESMTPPostfixhelo250mailfrom:<troy@>2502.1.0Okrcptto:<21488275@>2502.1.5Okdata354Enddatawith<CR><LF>.<CR><LF>test.2502.0.0Ok:queuedas2A525163C53quit2212.0.0ByeConnectionclosedbyforeignhost.如果是转发邮件,postfix进程的exec系统调用如下:egrep'exec'/tmp/postfix|grep-vset_thread_area3165

execve("/usr/libexec/postfix/cleanup",["cleanup","-z","-t","unix","-u"],[/*4vars*/])=03166

execve("/usr/libexec/postfix/trivial-rewrite",["trivial-rewrite","-n","rewrite","-t","unix","-u"],[/*4vars*/])=0#注意:这里调用smtp程序将邮件转发至其它网域的邮件服务器.3167

execve("/usr/libexec/postfix/smtp",["smtp","-t","unix","-u"],[/*4vars*/])=0注意:来自于网络的邮件也同样要入队列,由邮件队列服务qmgr来处理.最后再由postfix服务调用smtp/local程序进行邮件的发送操作.3)postfix的队列管理在postfix中负责队列管理的服务叫qmgr,它是整个postfix系统的中心枢纽,所有邮件,包括等待送出与从外界收进来的,都必须通过队列.队列管理器总共设置了五个做不同用途的队列,包括:输入(incoming),活动(active),等待(deferred),故障(corrupt),保留(hold).默认队列目录:/var/spool/postfix目录结构如下所示:ls-ltotal56drwx------.2postfixroot

4096Jul1407:46activedrwx------.2postfixroot

4096Jul

506:17bouncedrwx------.2postfixroot

4096May26

2010corruptdrwx------.6postfixroot

4096Jul1106:51deferdrwx------.6postfixroot

4096Jul1106:51deferreddrwx------.2postfixroot

4096May26

2010flushdrwx------.2postfixroot

4096May26

2010holddrwx------.2postfixroot

4096Jul1407:46incomingdrwx-wx---.2postfixpostdrop4096Jul1108:11maildropdrwxr-xr-x.2root

root

4096Jul1405:38piddrwx------.2postfixroot

4096Jul1517:21privatedrwx--x---.2postfixpostdrop4096Jul1517:21publicdrwx------.2postfixroot

4096May26

2010saveddrwx------.2postfixroot

4096May26

2010trace首先有新邮件进入队列的第一站是incoming,qmgr收到邮件到达的通知后,将邮件从incoming队列移到active队列.我们来看一下,这里我们采用本地收发,如下:首先用strace监控qmgr进程,如下:strace-fF-p1439-o/tmp/qmgr打开另一个窗口,发送邮件,如下:mailroot@

Subject:testtest.EOT查看监控日志,如下:grepopen/tmp/qmgr

1439

open("incoming",O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC)=91439

open("active/AE320163C55",O_RDWR|O_LARGEFILE)=10邮件从active目录队列送出到private目录队列中的local文件,local是一个socket文件connect(10,{sa_family=AF_FILE,path="private/local"},110)=0最后postfix调用local(本地邮件)或smtp(远程转发)程序对邮件进行发送处理.注意:这里的local和smtp也可以称为MDR我们这里假定DNS发生故障,把resolv.conf里面的DNS去掉,如下:cat/etc/resolv.conf

#GeneratedbyNetworkManager#domainlocaldomain#searchlocaldomainorg#nameserver再次监控qmgr进程,如下:strace-fF-p1439-o/tmp/qmgr再发送如下:mailroot@

Subject:testtest.EOT注意:这里我们发送的域名不是而是.我们再来看监控的结果:1439

connect(10,{sa_family=AF_FILE,path="private/smtp"},110)=0注:因为是外网转发,qmgr队列程序将邮件从active队列取出,通过socket协议发送给private/smtp套接字文件.1439

rename("active/34E40163C55","deferred/3/34E40163C55")=0注:由于没有DNS解析,邮件不能发送,所以被放到了等待队列deferred.我们可以查看deferred队列的文件,如下:catdeferred/3/34E40163C55

CO

420

212

1

0

420T1310724985

187059Acreate_time=1310724985Arewrite_context=localFhitlerStest@Oroot@Rroot@MN4Received:by

(Postfix,fromuserid500)N6

iSubject:testN'User-Agent:Heirloommailx12.47/29/08NMIME-Version:1.0N*Content-Type:text/plain;charset=us-asciiNContent-Transfer-Encoding:7bitN5Message-Id:<20110715101625.34E40163C55@>NFrom:test@(hitler)NNtestXE

最后我们模拟发送不成功的情况,如下:cat/etc/resolv.conf

#GeneratedbyNetworkManagerdomainlocaldomainsearchlocaldomainorgnameserver再次监控qmgr进程,如下:strace-fF-p1439-o/tmp/qmgr发送邮件,如下:mailroot@

Subject:testtest..EOT注意:域名不存在.我们查看/tmp/qmgr文件,如下:grepopen/tmp/qmgr

1439

open("incoming",O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC)=91439

open("active/9A428163C56",O_RDWR|O_LARGEFILE)=101439

open("incoming",O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC)=101439

open("active/9B1C7163C54",O_RDWR|O_LARGEFILE)=12注:两次进入incoming/active队列是因为域名不存在,我们调用MDR发送了邮件,但又被退回来了.最后我们看一下有关于邮件队列的一些工具:显示邮件列表:postqueue-p-QueueID---Size------ArrivalTime-----Sender/Recipient-------34E40163C55

420FriJul1518:16:25

test@(Hostordomainnamenotfound.Nameserviceerrorforname=type=MX:Hostnotfound,tryagain)

root@--0Kbytesin1Request.显示邮件内容:postcat-q34E40163C55***ENVELOPERECORDSdeferred/3/34E40163C55***message_size:

420

212

1

0

420message_arrival_time:FriJul1518:16:252011create_time:FriJul1518:16:252011named_attribute:rewrite_context=localsender_fullname:hitlersender:test@original_recipient:root@recipient:root@***MESSAGECONTENTSdeferred/3/34E40163C55***Received:by(Postfix,fromuserid500)

id34E40163C55;Fri,15Jul201118:16:25+0800(CST)Date:Fri,15Jul201118:16:25+0800To:root@Subject

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论