版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
用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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年双方保险外包服务合同
- 2024年专业技术服务外包合同样本
- 2024年婚姻过错方协议
- 2024年人力资源管理劳动合同
- 2024年区域建设项目钢材供需协议
- 2024年专用:全职个人劳动合同模板
- 2024年冷库管理服务协议
- 2024年原材料供应合同范本
- 2024年信息技术系统安装分包协议
- 化工行业聚合氯化铝购销合同
- 中信证券测评真题答案大全
- 部编版小学六年级道德与法治上册全册知识点汇编
- 数字时代的数字化政府
- 文旅推广短片策划方案相关7篇
- 2023-2024学年高中主题班会燃激情之烈火拓青春之华章 课件
- 中医药文化进校园-中医药健康伴我行课件
- 市政管道开槽施工-市政排水管道的施工
- 居住建筑户型分析
- 机电一体化职业生涯
- 中国电信新疆公司竞聘考试试题
- 妇科护理进修汇报
评论
0/150
提交评论