设为首页 收藏本站
查看: 1117|回复: 0

[经验分享] 《Linux下postfix服务的深入分析》

[复制链接]

尚未签到

发表于 2015-11-24 10:45:52 | 显示全部楼层 |阅读模式
  转载自:http://www.lupaworld.com/home-space-uid-56821-do-blog-id-238537.html
  1)邮件系统基本概述:
  
1.1)邮件系统的组成:
  MTA:邮件传输代理,即邮箱服务器端,:Postfix Sendmail.
  MUA:邮件用户代理,即我们平时用的邮箱客户端.:Foxmail,Outlook Express
  MDA:邮箱投递代理,当确认收下邮件后,MDA将邮件信息存放在普通文件夹内,等待用户读取.
  1.2)邮件发送流程:
  .通过MUA创建发送邮件,此时将该邮件交给一台运行MTA的软件.
  .MTA收下邮件后,它可能将邮件递送给自己系统上的用户,也可能将邮件交给另一个MTA继续传递.
  .邮件终点站的MTA,在发现收件人是本地系统的用户之后,将邮件交给MDA.
  .MDA可能将邮件存放在普通文件夹内,也可能存放专门存储电子邮件的特殊数据库,此时邮件被存和邮箱,等待收件人将它收走.
  .收件人使用MUA来取信/读信.
  1.3)E-mail的协议
  SMTP(simple mail transport protocol)
  规范两部主机通过网络交换E-mail的对话原则.
  SMTP是用于寄信的协议,MUA要求MTA代为送出一封邮件,以及一个MTA将邮件送到另一个MTA,都使用SMTP协议.
  原始的SMTP协议并没有身份验证的设计,在后来的ESMTP中加入了这方面的功能.
  SMTP用的端口是25.
  
POP(Post office protocol)
  POP协议允许MUA访问/读取邮件服务器的邮件.目前已经发展到第三版,也就是我们常看到的pop3,它用的端口是110.
  IMAP(Internet Mail Access Protocol)
  IMAP协议运行在TCP/IP协议之上,使用的端口是143.
  它与POP3协议的主要区别是用户可以不用把所有的邮件全部下载,可以通过客户端直接对服务器上的邮件进行操作.
  
2)Postfix的运作流程
  2.1)Postfix的组件
  

  Postfix的处理流程分为三个阶段:
  .接收邮件
  .将邮件排入队列
  .递送邮件
  

  接收邮件分为从本地接收,从网络接收,本地转发,转寄邮件,退信通知函.
  将邮件排入队列主要由队列管理员负责.
  递送邮件的目的地主要是本地,虚拟别名,虚拟邮箱以及转发.
  

  

  2.2)来自服务器本地的邮件
  

  在Unix/Linux系统上发送邮件,比如通过mail程序发送邮件,mail程序在做为相关处理后会调用sendmail程序投递邮件.
  注:
  sendmail会让我们想起sendmail邮件服务,但这里的sendmail是与postfix兼容的同名工具.
  当用户以sendmail(postfix)程序寄出邮件后,sendmail会使用postdrop程序将邮件存入postfix队列目录下的maildrop子目录.默认目录为: /var/spool/postfix/maildrop/
  最后postdrop程序会打开/var/spool/postfix/public/pickup,这个文件是个管道文件,用这种IPC通讯文件告之pickup服务.
  

  下面我们用strace来跟踪mail程序的系统调用过程来进行证实,如下:
  strace -fF -o /tmp/sendmail mail -s "test" 21488275@qq.com
  

  查看打开的文件和执行的程序,如下:
  egrep 'open|execve' /tmp/sendmail
  2791  execve("/bin/mail", ["mail", "-s", "test", "21488275@qq.com"], [/* 22 vars */]) = 0
  略
  2792  execve("/usr/sbin/sendmail", ["send-mail", "-i", "21488275@qq.com"], [/* 22 vars */]) = 0
  略
  2793  execve("/usr/sbin/postdrop", ["/usr/sbin/postdrop", "-r"], [/* 2 vars */]) = 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@example.com.
  pickup服务与cleanup服务的通讯方式是socket套接字,我们通过strace来跟踪pickup的工作过程,如下:
  strace -fF -p 2688 -o /tmp/pickup
  

  发送邮件
  mail -s "test" root
  test
  .
  EOT
  

  查看系统调用,如下:
  tail -f /tmp/pickup
  3246  alarm(6000)                       = 5975
  3246  time(NULL)                        = 1310341018
  3246  epoll_wait(8, {{EPOLLIN, {u32=6, u64=15683691556634630}}}, 100, 75000) = 1
  3246  time(NULL)                        = 1310341028
  3246  write(5, "\256\f\0\0\1\0\0\0\0\0\0\0", 12) = 12
  3246  read(6, "W", 1024)                = 1
  3246  open("maildrop", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 9
  3246  getdents64(9, /* 3 entries */, 32768) = 80
  3246  lstat64("maildrop/7C3EA163C51", {st_mode=S_IFREG|0744, st_size=277, ...}) = 0
  3246  open("maildrop/7C3EA163C51", O_RDONLY|O_NONBLOCK|O_LARGEFILE) = 10
  3246  fstat64(10, {st_mode=S_IFREG|0744, st_size=277, ...}) = 0
  3246  lstat64("maildrop/7C3EA163C51", {st_mode=S_IFREG|0744, st_size=277, ...}) = 0
  3246  socket(PF_FILE, SOCK_STREAM, 0)   = 11
  3246  fcntl64(11, F_GETFL)              = 0x2 (flags O_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) = 0
  3246  poll([{fd=11, events=POLLIN}], 1, 3600000) = 1 ([{fd=11, revents=POLLIN}])
  3246  read(11, "queue_id\00084E5D163C55\0\0", 4096) = 22
  3246  gettimeofday({1310341028, 544945}, NULL) = 0
  3246  time(NULL)                        = 1310341028
  3246  read(10, "T\0211310341028 508906A\25rewrite_con"..., 4096) = 277
  3246  time(NULL)                        = 1310341028
  3246  send(7, &quot;<22>Jul 11 07:37:08 postfix/pick&quot;..., 74, MSG_NOSIGNAL) = 74
  3246  stat64(&quot;/etc/localtime&quot;, {st_mode=S_IFREG|0644, st_size=405, ...}) = 0
  3246  _llseek(10, 0, [277], SEEK_END)   = 0
  3246  poll([{fd=11, events=POLLOUT}], 1, 3600000) = 1 ([{fd=11, revents=POLLOUT}])
  3246  write(11, &quot;flags\000115\0\0T\0211310341028 508906A\25&quot;..., 398) = 398
  3246  gettimeofday({1310341028, 546876}, NULL) = 0
  3246  poll([{fd=11, events=POLLIN}], 1, 3600000) = 1 ([{fd=11, revents=POLLIN|POLLHUP}])
  3246  read(11, &quot;status\0000\0reason\0\0\0&quot;, 4096) = 18
  3246  gettimeofday({1310341028, 571577}, NULL) = 0
  3246  close(10)                         = 0
  3246  close(11)                         = 0
  3246  unlink(&quot;maildrop/7C3EA163C51&quot;)    = 0
  

  当postfix发现pickup连接cleanup套接字后,通过execve调用cleanup程序,并且通过socket的通讯方式进行接收处理该邮件.
  下面的系统调用说明了这一点:
  3321  execve(&quot;/usr/libexec/postfix/cleanup&quot;, [&quot;cleanup&quot;, &quot;-z&quot;, &quot;-t&quot;, &quot;unix&quot;, &quot;-u&quot;], [/* 4 vars */]) = 0
  略
  3321  socket(PF_NETLINK, SOCK_RAW, 0)   = 8
  3321  bind(8, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
  3321  getsockname(8, {sa_family=AF_NETLINK, pid=3321, groups=00000000}, [12]) = 0
  3321  time(NULL)                        = 1310341496
  3321  sendto(8, &quot;\24\0\0\0\22\0\1\3x9\32N\0\0\0\0\0\0\0\0&quot;, 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
  3321  recvmsg(8, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{&quot;\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&quot;..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 1292
  3321  recvmsg(8, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{&quot;\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&quot;..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 20
  3321  sendto(8, &quot;\24\0\0\0\26\0\1\3y9\32N\0\0\0\0\0\0\0\0&quot;, 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
  3321  recvmsg(8, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{&quot;0\0\0\0\24\0\2\0y9\32N\371\f\0\0\2\10\2
  00\376\1\0\0\0\10\0\1\0\177\0\0\1&quot;..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 168
  3321  recvmsg(8, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{&quot;@\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&quot;..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 128
  3321  recvmsg(8, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{&quot;\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&quot;..., 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(&quot;incoming/711959.3321&quot;, &quot;incoming/AE07E163C55&quot;) = 0
  

  最后队列管理器看到有新邮件已经入队,它确定是进行转发还是发送给本地用户,是转发还是本地的区别在用它连接使用的套接字文件,如下:
  本地发送:
  3247  connect(10, {sa_family=AF_FILE, path=&quot;private/local&quot;}, 110) = 0
  远程转发:
  3247  connect(13, {sa_family=AF_FILE, path=&quot;private/smtp&quot;}, 110) = 0
  &#20540;得注意的是队列管理器是独立的服务进程,如下:
  ps -ef|grep qmgr|grep -v grep
  postfix   3247  3244  0 07:36 ?        00:00:00 qmgr -l -t fifo -u
  

  最后确认我们这里是本地发送,所以postfix会用exec调用local程序完成本地邮件发送的工序,首先它会通过/etc/passwd/etc/aliases.db来判断是否是当前系统用户或其别名,如是当前系统用户则接收存放邮件,并将文件写入到/var/mail/root下面,完成了最后的发送过程.
  

  

  

  2.3)来自网络的邮件
  

  这里分为两种,一种是外界寄给postfix所控制网域的邮件,这种情况smtpd一定会收下第一种邮件,如果收件人存在的话.
  第二种情况是目的地在其它网域,这种情况我们称为转发,这里先讨论第一种情况.
  

  外界寄给postfix,postfixsmtpd daemon来处理接收外来邮件,然后通过socket文件将邮件传输给cleanup/trivial-rewrite对邮件进行规范处理,最后根据是本地用户邮件还是其它网域用户邮件选择执行对映的程序(本地是local,转发是smtp)
  

  首先我们在服务端用strace跟踪postfix进程,如下:
  ps -ef|grep postfix
  root      2505     1  0 05:38 ?        00:00:00 /usr/libexec/postfix/master
  postfix   2508  2505  0 05:38 ?        00:00:00 qmgr -l -t fifo -u
  postfix   3066  2505  0 07:18 ?        00:00:00 pickup -l -t fifo -u
  root      3085  2569  0 07:26 pts/1    00:00:00 grep postfix
  

  strace -fF -p 2505  -o /tmp/postfix
  

  

  然后,我们在客户端用telnet命令连接服务端的postfix(MTA),发送邮件.
  

  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 ckhitler.org ESMTP Postfix
  helo ckhitler.org
  250 ckhitler.org
  mail from:<troy@taomee.com>
  250 2.1.0 Ok
  rcpt to:<root@ckhitler.org>
  250 2.1.5 Ok
  data
  354 End data with <CR><LF>.<CR><LF>
  test
  .
  250 2.0.0 Ok: queued as DA43C163C53
  quit
  221 2.0.0 Bye
  Connection closed by foreign host.
  

  

  在服务端查看postfixexec系统调用,如下:
  egrep 'exec' /tmp/postfix |grep -v set_thread_area
  #注意:这里调用smtpd daemon进行邮件接收处理
  2718  execve(&quot;/usr/libexec/postfix/smtpd&quot;, [&quot;smtpd&quot;, &quot;-n&quot;, &quot;smtp&quot;, &quot;-t&quot;, &quot;inet&quot;, &quot;-u&quot;, &quot;-o&quot;, &quot;stress=&quot;], [/* 4 vars */]) = 0
  2719  execve(&quot;/usr/libexec/postfix/proxymap&quot;, [&quot;proxymap&quot;, &quot;-t&quot;, &quot;unix&quot;, &quot;-u&quot;], [/* 4 vars */]) = 0
  2721  execve(&quot;/usr/libexec/postfix/trivial-rewrite&quot;, [&quot;trivial-rewrite&quot;, &quot;-n&quot;, &quot;rewrite&quot;, &quot;-t&quot;, &quot;unix&quot;, &quot;-u&quot;], [/* 4 vars */]) = 0
  2722  execve(&quot;/usr/libexec/postfix/cleanup&quot;, [&quot;cleanup&quot;, &quot;-z&quot;, &quot;-t&quot;, &quot;unix&quot;, &quot;-u&quot;], [/* 4 vars */]) = 0
  #注意:这里调用local程序将邮件接收至本地
  2723  execve(&quot;/usr/libexec/postfix/local&quot;, [&quot;local&quot;, &quot;-t&quot;, &quot;unix&quot;], [/* 4 vars */]) = 0
  

  下面是转发的测试:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 ckhitler.org ESMTP Postfix
  helo ckhitler.org
  250 ckhitler.org
  mail from:<troy@taomee.com>
  250 2.1.0 Ok
  rcpt to:<21488275@qq.com>
  250 2.1.5 Ok
  data
  354 End data with <CR><LF>.<CR><LF>
  test
  .
  250 2.0.0 Ok: queued as 2A525163C53
  quit
  221 2.0.0 Bye
  Connection closed by foreign host.
  

  如果是转发邮件,postfix进程的exec系统调用如下:
  egrep 'exec' /tmp/postfix |grep -v set_thread_area
  3165  execve(&quot;/usr/libexec/postfix/cleanup&quot;, [&quot;cleanup&quot;, &quot;-z&quot;, &quot;-t&quot;, &quot;unix&quot;, &quot;-u&quot;], [/* 4 vars */]) = 0
  3166  execve(&quot;/usr/libexec/postfix/trivial-rewrite&quot;, [&quot;trivial-rewrite&quot;, &quot;-n&quot;, &quot;rewrite&quot;, &quot;-t&quot;, &quot;unix&quot;, &quot;-u&quot;], [/* 4 vars */]) = 0
  #注意:这里调用smtp程序将邮件转发至其它网域的邮件服务器.
  3167  execve(&quot;/usr/libexec/postfix/smtp&quot;, [&quot;smtp&quot;, &quot;-t&quot;, &quot;unix&quot;, &quot;-u&quot;], [/* 4 vars */]) = 0
  

  注意:来自于网络的邮件也同样要入队列,由邮件队列服务qmgr来处理.最后再由postfix服务调用smtp/local程序进行邮件的发送操作.
  

  

  3)postfix的队列管理
  

  在postfix中负责队列管理的服务叫qmgr,它是整个postfix系统的中心枢纽,所有邮件,包括等待送出与从外界收进来的,都必须通过队列.
  队列管理器总共设置了五个做不同用途的队列,包括:输入(incoming),活动(active),等待(deferred),故障(corrupt),保留(hold).
  

  默认队列目录:/var/spool/postfix
  

  目录结构如下所示:
  ls -l
  total 56
  drwx------. 2 postfix root     4096 Jul 14 07:46 active
  drwx------. 2 postfix root     4096 Jul  5 06:17 bounce
  drwx------. 2 postfix root     4096 May 26  2010 corrupt
  drwx------. 6 postfix root     4096 Jul 11 06:51 defer
  drwx------. 6 postfix root     4096 Jul 11 06:51 deferred
  drwx------. 2 postfix root     4096 May 26  2010 flush
  drwx------. 2 postfix root     4096 May 26  2010 hold
  drwx------. 2 postfix root     4096 Jul 14 07:46 incoming
  drwx-wx---. 2 postfix postdrop 4096 Jul 11 08:11 maildrop
  drwxr-xr-x. 2 root    root     4096 Jul 14 05:38 pid
  drwx------. 2 postfix root     4096 Jul 15 17:21 private
  drwx--x---. 2 postfix postdrop 4096 Jul 15 17:21 public
  drwx------. 2 postfix root     4096 May 26  2010 saved
  drwx------. 2 postfix root     4096 May 26  2010 trace
  

  首先有新邮件进入队列的第一站是incoming,qmgr收到邮件到达的通知后,将邮件从incoming队列移到active队列.
  

  我们来看一下,这里我们采用本地收发,如下:
  首先用strace监控qmgr进程,如下:
  strace -fF -p 1439 -o /tmp/qmgr
  

  打开另一个窗口,发送邮件,如下:
  mail root@ckhitler.org
  Subject: test
  test
  .
  EOT
  

  查看监控日志,如下:
  grep open /tmp/qmgr
  1439  open(&quot;incoming&quot;, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 9
  1439  open(&quot;active/AE320163C55&quot;, O_RDWR|O_LARGEFILE) = 10
  

  邮件从active目录队列送出到private目录队列中的local文件,local是一个socket文件
  connect(10, {sa_family=AF_FILE, path=&quot;private/local&quot;}, 110) = 0
  

  最后postfix调用local(本地邮件)smtp(远程转发)程序对邮件进行发送处理.
  注意:这里的localsmtp也可以称为MDR
  

  

  我们这里假定DNS发生故障,resolv.conf里面的DNS去掉,如下:
  cat /etc/resolv.conf
  # Generated by NetworkManager
  #domain localdomain
  #search localdomain org
  #nameserver 192.168.75.2
  

  再次监控qmgr进程,如下:
  strace -fF -p 1439 -o /tmp/qmgr
  

  

  再发送如下:
  mail root@chitler.org
  Subject: test
  test
  .
  EOT
  注意:这里我们发送的域名不是ckhitler.org而是chitler.org.
  

  我们再来看监控的结果:
  1439  connect(10, {sa_family=AF_FILE, path=&quot;private/smtp&quot;}, 110) = 0
  注:因为是外网转发,qmgr队列程序将邮件从active队列取出,通过socket协议发送给private/smtp套接字文件.
  

  1439  rename(&quot;active/34E40163C55&quot;, &quot;deferred/3/34E40163C55&quot;) = 0
  注:由于没有DNS解析,邮件不能发送,所以被放到了等待队列deferred.
  

  我们可以查看deferred队列的文件,如下:
  cat deferred/3/34E40163C55
  CO            420             212               1               0             420T1310724985
  187059Acreate_time=1310724985Arewrite_context=localFhitlerStest@ckhitler.orgOroot@chitler.orgRroot@chitler.orgMN4Received: by ckhitler.org
  (Postfix, from userid 500)N6   iSubject: testN'User-Agent: Heirloom mailx 12.4 7/29/08NMIME-Version: 1.0N*Content-Type: text/plain;
  charset=us-asciiNContent-Transfer-Encoding: 7bitN5Message-Id: <20110715101625.34E40163C55@ckhitler.org>N From: test@ckhitler.org
  (hitler)NNtestXE
  

  

  最后我们模拟发送不成功的情况,如下:
  cat /etc/resolv.conf
  # Generated by NetworkManager
  domain localdomain
  search localdomain org
  nameserver 192.168.75.2
  

  再次监控qmgr进程,如下:
  strace -fF -p 1439 -o /tmp/qmgr
  

  发送邮件,如下:
  mail root@chitler.org
  Subject: test
  test.
  .
  EOT
  注意:chitler.org域名不存在.
  

  我们查看/tmp/qmgr文件,如下:
  grep open /tmp/qmgr
  1439  open(&quot;incoming&quot;, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 9
  1439  open(&quot;active/9A428163C56&quot;, O_RDWR|O_LARGEFILE) = 10
  1439  open(&quot;incoming&quot;, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 10
  1439  open(&quot;active/9B1C7163C54&quot;, O_RDWR|O_LARGEFILE) = 12
  

  注:两次进入incoming/active队列是因为chilter.org域名不存在,我们调用MDR发送了邮件,但又被退回来了.
  

  最后我们看一下有关于邮件队列的一些工具:
  

  显示邮件列表:
  postqueue -p
  -Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
  34E40163C55      420 Fri Jul 15 18:16:25  test@ckhitler.org
  (Host or domain name not found. Name service error for name=chitler.org type=MX: Host not found, try again)
  root@chitler.org
  

  -- 0 Kbytes in 1 Request.
  

  显示邮件内容:
  postcat -q 34E40163C55
  *** ENVELOPE RECORDS deferred/3/34E40163C55 ***
  message_size:             420             212               1               0             420
  message_arrival_time: Fri Jul 15 18:16:25 2011
  create_time: Fri Jul 15 18:16:25 2011
  named_attribute: rewrite_context=local
  sender_fullname: hitler
  sender: test@ckhitler.org
  original_recipient: root@chitler.org
  recipient: root@chitler.org
  *** MESSAGE CONTENTS deferred/3/34E40163C55 ***
  Received: by ckhitler.org (Postfix, from userid 500)
  id 34E40163C55; Fri, 15 Jul 2011 18:16:25 &#43;0800 (CST)
  Date: Fri, 15 Jul 2011 18:16:25 &#43;0800
  To: root@chitler.org
  Subject: test
  User-Agent: Heirloom mailx 12.4 7/29/08
  MIME-Version: 1.0
  Content-Type: text/plain; charset=us-ascii
  Content-Transfer-Encoding: 7bit
  Message-Id: <20110715101625.34E40163C55@ckhitler.org>
  From: test@ckhitler.org (hitler)
  

  test
  *** HEADER EXTRACTED deferred/3/34E40163C55 ***
  *** MESSAGE FILE END deferred/3/34E40163C55 ***
  

  将邮件转存到保存队列:
  postsuper -h 34E40163C55
  

  ls -l hold/34E40163C55
  -rwx------ 1 postfix postfix 636 Jul 15  2011 hold/34E40163C55
  

  删除队列中的邮件:
  postsuper -d 34E40163C55
  postsuper: 34E40163C55: removed
  postsuper: Deleted: 1 message
  

  postqueue -p
  Mail queue is empty
  

  重新排队:
  postsuper -r ALL
  

  

  4)postfix邮件服务器的配置项
  

  4.1)设定邮件主机的识别身份
  

  myhostname:设定主机名称
  如果没有指定该选项,系统会以gethostname()取得当前主机的主机名.
  myhostname需要使用FQDN,我们查看61.com域名的mx记录,如下:
  host -t mx 61.com
  61.com mail is handled by 10 mail.61.com.
  在这里我们就要将myhostname设定为mail.61.com
  

  mydomain:网域名称
  预设会以myhostname第一个点之后的作为domain名称.
  依据上例,我们将mydomain设为61.com,这时我们就可以往troy@61.com发邮件.
  

  

  myorigin:发信时所显示的发信源主机
  如果在配置文件中没有指定myorigin选项,myorigin等同于myhostname.
  如果我们将myorigin设置为mail.ckhitler.org,则在接收方会看到mail frommail.ckhitler.org
  如下:
  From root@mail.ckhitler.org  Sat Jul 16 08:12:14 2011
  Return-Path: <root@mail.ckhitler.org>
  

  

  mydestination:能够收信的主机名称
  这个项目指定的主机名称就是对方填写的mail to中的主机名字,例如:
  mail to:<test@ckhitler.org>
  所以这里的mydestination就是ckhitler.org,另外我们也要把mx记录指定的域名也要填写在这里.例如:mail.ckhitler.org
  

  这里建议的配置方案是:
  myhostname = mail.ckhitler.org
  mydomain = ckhitler.org
  myorigin = ckhitler.org
  mydestination = $myhostname,$mydomain
  

  

  4.2)设定postfix使用的网络介面
  

  inet_interfaces选项用于选择网络介面,如果设定为localhost,则绑定监听本地回环地址.
  设定为all,则绑定监听到0.0.0.0
  

  这里建议的配置方案是:
  inet_interfaces = all
  

  

  4.3)设定postfix的转发信任网络
  

  mynetworks:明确设定可使用relay的主机范围
  

  注意:如果设置mynetworks选项的话,就不需要再设置mynetworks_style选项.
  

  

  我们设置只转发当前主机如下:
  mynetworks = 127.0.0.0/8
  

  这时我们在其它机器连接postfix,无法完成转发,如下:
  [iyunv@ssh-client ~]# telnet 192.168.75.128  25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo mail.ckhitler.org
  250 mail.ckhitler.org
  mail from:<root@ckhitler.org>
  250 2.1.0 Ok
  rcpt to:<21488275@qq.com>
  554 5.7.1 <21488275@qq.com>: Relay access denied
  

  我们设置本机及同网段的信任转发,如下:
  mynetworks = 127.0.0.0/8, 192.168.75.0/24
  

  这时我们在其它机器连接postfix,可以完成转发,如下:
  telnet 192.168.75.128  25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo mail.ckhitler.org
  250 mail.ckhitler.org
  mail from:<root@ckhitler.org>
  250 2.1.0 Ok
  rcpt to:<21488275@qq.com>
  250 2.1.5 Ok
  data
  354 End data with <CR><LF>.<CR><LF>
  test
  .
  250 2.0.0 Ok: queued as 603BF163C55
  quit
  221 2.0.0 Bye
  Connection closed by foreign host.
  

  

  relay_domains:规范可以relay的域名
  

  我们在其它服务器连接192.168.75.128,root@abc.com进行发送,relay被拒绝,如下:
  telnet 192.168.75.128  25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo mail.ckhitler.org
  250 mail.ckhitler.org
  mail from:<root@abc.com>
  250 2.1.0 Ok
  rcpt to:<21488275@qq.com>
  554 5.7.1 <21488275@qq.com>: Relay access denied
  

  做relay_domains的设定如下:
  relay_domains = $mydomain,abc.com
  

  再次转发则顺利的发出.如下:
  telnet 192.168.75.128  25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo mail.ckhitler.org
  250 mail.ckhitler.org
  mail from:<root@abc.com>
  250 2.1.0 Ok
  rcpt to:<21488275@qq.com>
  250 2.1.5 Ok
  data
  354 End data with <CR><LF>.<CR><LF>
  test
  .
  250 2.0.0 Ok: queued as 4EA2E163C55
  quit
  221 2.0.0 Bye
  Connection closed by foreign host.
  

  

  4.4)smtpd_client_restrictions
  允许/拒绝客户端使用邮件服务器
  

  4.4.1)check_client_access:根据客户端的主机名,父域,IP地址或部分IP来匹配.
  如下:
  smtpd_client_restrictions = check_client_access hash:/etc/postfix/access
  

  

  编辑:
  vi /etc/postfix/access
  

  添加下面的选项,即拒绝192.168.75.129的远程连接:
  192.168.75.129  REJECT
  

  重建hash文件:
  postmap /etc/postfix/access
  

  

  在客户端192.168.75.129上进行测试,如下:
  [iyunv@ssh-client ~]# telnet 192.168.75.128  25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  h220 mail.ckhitler.org ESMTP Postfix
  helo mail.ckhitler.org
  250 mail.ckhitler.org
  mail from:<root@ckhitler.org>
  250 2.1.0 Ok
  rcpt to:<named@ckhitler.org>
  554 5.7.1 <unknown[192.168.75.129]>: Client host rejected: Access denied /*注意:客户端被拒绝.*/
  

  

  这回我们拒绝192.168.75.0/24网段使用本邮件服务器,只允许192.168.75.129这台机器使用邮件服务器,设置如下:
  

  vi /etc/postfix/access
  postmap /etc/postfix/access
  

  192.168.75.129 OK
  192.168.75 REJECT
  

  

  4.4.2)reject_unknown_client
  拒绝客户的地址没有对应的DNSA记录或PTR记录的连接
  

  修改smtpd_client_restrictions规则如下:
  smtpd_client_restrictions = reject_unknown_client
  

  再次发送测试,提示如下的错误:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  mail from:<test@abchitler.com>
  250 2.1.0 Ok
  rcpt to:<root@ckhitler.org>
  450 4.7.1 Client host rejected: cannot find your hostname, [192.168.75.129]
  quit
  221 2.0.0 Bye
  Connection closed by foreign host.
  

  我们在服务端增加客户端的对映主机名,如下:
  echo &quot;192.168.75.129  client&quot; >> /etc/hosts
  

  再次进行发送测试,如下:
  

  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  mail from:<test@abchitler.com>
  250 2.1.0 Ok
  rcpt to:<root@ckhitler.org>
  250 2.1.5 Ok
  data
  354 End data with <CR><LF>.<CR><LF>
  test
  .
  250 2.0.0 Ok: queued as B4655163C49
  quit
  221 2.0.0 Bye
  Connection closed by foreign host.
  

  4.4.3)permit_mynetworks
  允许来自其IP地址属于$mynetworks所定义的网络的客户端的连接.
  

  我们修改配置如下:
  smtpd_client_restrictions = permit_mynetworks,check_client_access hash:/etc/postfix/access,
  reject_unknown_client
  
  注意我们要删除之前加入/etc/hosts中的主机名,这样在不加入permit_mynetworks的情况下,postfix将拒绝客户端的连接,我们将permit_mynetworks加入到reject_unknown_client选项的前面.
  保证以permit_mynetworks优先的顺序处理邮件.
  

  发送测试邮件成功,如下:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  mail from:<test@abchitler.com>
  250 2.1.0 Ok
  rcpt to:<root@ckhitler.org>
  250 2.1.5 Ok
  data
  354 End data with <CR><LF>.<CR><LF>
  .
  250 2.0.0 Ok: queued as DF74F163C49
  quit
  221 2.0.0 Bye
  Connection closed by foreign host.
  

  

  4.4.4)reject_rbl_client/reject_rhsbl_client
  拒绝来自属于RBLRHSBL列表中的地址进行连接,通过检查一个IP地址或域名是否存在于domain.tldRBLRHSBL,可以判断该客户端是否被列入了domain.tld的实时黑名单,从而决定是否接受连接.
  

  我们加入以下的反垃圾邮件联盟,如下:
  smtpd_client_restrictions = permit_mynetworks,check_client_access hash:/etc/postfix/access,
  reject_unknown_client,
  reject_rbl_client cblless.anti-spam.org.cn,
  reject_rbl_client sbl-xbl.spamhaus.org,
  reject_rbl_client relays.ordb.org,
  reject_rhsbl_client dsn.rfc-ignorant.org
  
  

  4.5)smtpd_helo_required
  通过smtpd_helo_required参数指定客户端在SMTP会话的开始必须发送一个HELO命令,你可以指定该参数的&#20540;为yesno,缺省&#20540;为:
  smtpd_helo_required = no
  

  我们将smtpd_helo_required改成yes,如下:
  vi /etc/postfix/main.cf
  添加如下配置:
  smtpd_helo_required = yes
  

  再次发送测试邮件,如下:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  mail from:<troy@abcckhitler.org>
  503 5.5.1 Error: send HELO/EHLO first
  

  我们看到该参数已经起了作用,该项对反垃圾邮件有一定作用.
  

  

  

  4.6)smtpd_helo_restrictions
  通过smtpd_helo_restrictions参数在客户端在执行HELO命令时,对客户端的合法性进行检查.
  

  4.6.1)
  reject_invalid_hostname:如果HELO命令所带的主机名参数不符合语法规范则拒绝客户机的连接请求.
  

  修改相关配置,如下:
  vi /etc/postfix/main.cf
  smtpd_helo_restrictions = reject_invalid_hostname
  

  测试:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo 8888
  250 mail.ckhitler.org
  mail from:<troy@abcckhitler.org>
  250 2.1.0 Ok
  rcpt to:<troy@ckhitler.org>  
  501 5.5.2 <8888>: Helo command rejected: Invalid name
  quit
  221 2.0.0 Bye
  Connection closed by foreign host.
  

  

  4.6.2)
  reject_unknown_hostname
  拒绝未知的主机名的连接.所谓未知的主机名是指该主机没有DNSA记录或MX记录.
  

  修改相关配置,如下:
  vi /etc/postfix/main.cf
  smtpd_helo_restrictions = reject_invalid_hostname,reject_unknown_hostname
  

  测试:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo die
  250 mail.ckhitler.org
  mail from:<troy@abcckhitler.org>
  250 2.1.0 Ok
  rcpt to:<troy@ckhitler.org>  
  450 4.7.1 <die>: Helo command rejected: Host not found
  quit
  221 2.0.0 Bye
  Connection closed by foreign host.
  注:由于无法解析die,所以发送失败.
  

  

  测试:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo test.com
  250 mail.ckhitler.org
  mail from:<troy@abcckhitler.org>
  250 2.1.0 Ok
  rcpt to:<troy@ckhitler.org>  
  250 2.1.5 Ok
  data
  354 End data with <CR><LF>.<CR><LF>
  注:由于这回用helo test.com,所以发送邮件成功.
  

  

  4.6.3)
  reject_non_fqdn_hostname
  如果客户端执行HELO命令时的主机名不是RFC规定的完整的域名则拒绝客户端的连接请求.
  

  修改相关配置,如下:
  vi /etc/postfix/main.cf
  smtpd_helo_restrictions = reject_invalid_hostname,reject_non_fqdn_hostname
  

  测试:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo die
  250 mail.ckhitler.org
  mail from:<troy@abcckhitler.org>
  250 2.1.0 Ok
  rcpt to:<troy@ckhitler.org>  
  504 5.5.2 <die>: Helo command rejected: need fully-qualified hostname
  quit
  221 2.0.0 Bye
  Connection closed by foreign host.
  注:我们用helo die,由于die不符合FQDN的规范,所以发送失败.
  

  

  4.7)
  strict_rfc821_envelopes
  RFC 821对邮件的信头做了严&#26684;的规定,但是广泛使用的sendmail并不支持该规定.
  strict_rfc821_envelopes选项默认是no.
  

  修改相关配置,如下:
  vi /etc/postfix/main.cf
  strict_rfc821_envelopes = yes
  

  测试:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  mail from:<troy@abcckhitler.org>
  503 5.5.1 Error: send HELO/EHLO first
  

  

  4.8)
  smtpd_sender_restrictions
  通过发件人在执行MAIL FROM命令时提供的地址进行限制.
  

  4.8.1)
  reject_unknown_sender_domain
  如果MAIL FROM命令提供的主机名在DNS中没有相应的AMX记录则拒绝该客户端的连接请求.
  

  修改相关配置如下:
  vi /etc/postfix/main.cf
  smtpd_sender_restrictions = reject_unknown_sender_domain
  

  测试如下:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo test.com
  250 mail.ckhitler.org
  mail from:<troy@abcckhitler.org>
  250 2.1.0 Ok
  rcpt to:<troy@ckhitler.org>  
  450 4.1.8 <troy@abcckhitler.org>: Sender address rejected: Domain not found
  因为不存在abcckhitler.org这个域名,所以失败邮件失败.
  

  

  4.8.2)
  reject_non_fqdn_sender
  如果MAIL FROM命令提供的主机名不是RFC规定的完整的域名则拒绝客户端的连接请求.
  

  修改相关配置如下:
  vi /etc/postfix/main.cf
  smtpd_sender_restrictions = reject_non_fqdn_sender
  

  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo test.com
  250 mail.ckhitler.org
  mail from:<troy@abc>
  250 2.1.0 Ok
  rcpt to:<troy@ckhitler.org>  
  504 5.5.2 <troy@abc>: Sender address rejected: need fully-qualified address
  

  

  4.9)
  smtpd_recipient_restrictions
  可以用smtpd_recipient_restrictions参数通过发件人在执行RCPT TO命令时提供的地址进行限制.
  

  4.9.1)
  reject_unknown_recipient_domain
  如果收件人的邮件地址在DNS中没有相应的A MX 记录则拒绝该客户端的连接请求.
  

  修改相关配置如下:
  vi /etc/postfix/main.cf
  smtpd_recipient_restrictions = reject_unknown_recipient_domain,reject_unauth_destination,permit_mynetworks
  

  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo test.com
  250 mail.ckhitler.org
  mail from:<troy@abcckhitler.org>
  250 2.1.0 Ok
  rcpt to:<troy@abcckhitler.org>
  450 4.1.2 <troy@abcckhitler.org>: Recipient address rejected: Domain not found
  注:我们看到转发被拒绝了,是因为abcckhitler.org这个域名DNS无法解析.
  

  

  4.9.2)
  reject_unauth_destination
  不管客户端的主机名,只要符合以下的条件,就不拒绝该客户端SMTP连接请求:
  * 解析后的目标地址符合$relay_domains及其子域
  * 解析后的目标地址符合$inet_interfaces$mydestination$virtual_maps
  

  修改相关配置如下:
  vi /etc/postfix/main.cf
  smtpd_recipient_restrictions =  reject_unauth_destination
  

  测试如下:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo test.com
  250 mail.ckhitler.org
  mail from:<troy@abcckhitler.org>
  250 2.1.0 Ok
  rcpt to:<troy@abcckhitler.org>
  554 5.7.1 <troy@abcckhitler.org>: Relay access denied
  我们看到转发被拒绝了.这是因为abcckhitler.org不在relay_domains的列表中.
  

  

  4.9.3)
  reject_non_fqdn_recipient
  如果发件人在执行RCPT TO命令时提供的地址不是完整的域名则拒绝其SMTP连接请求
  修改相关配置如下:
  vi /etc/postfix/main.cf
  smtpd_recipient_restrictions = reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,reject_unauth_destination
  

  测试如下:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  helo test.com
  250 mail.ckhitler.org
  mail from:<troy@abcckhitler.org>
  250 2.1.0 Ok
  rcpt to:<troy@abc>               
  504 5.5.2 <troy@abc>: Recipient address rejected: need fully-qualified address
  

  

  4.9.4)
  check_relay_domains
  如果符合以下的条件,则接受SMTP连接请求,否则拒绝该连接
  * 客户端主机名符合$relay_domains及其子域
  * 目的地为$inet_interfaces$mydestination$virtual_maps
  

  修改相关配置如下:
  smtpd_recipient_restrictions = check_relay_domains
  

  测试如下:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  helo test.com220 mail.ckhitler.org ESMTP Postfix
  

  250 mail.ckhitler.org
  mail from:<troy@ckhitler.org>      
  250 2.1.0 Ok
  rcpt to:<troy@abcckhitler.org>
  554 5.7.1 <troy@abcckhitler.org>: Recipient address rejected: Relay access denied
  我们看到smtp服务对目的地进行检测,因为abcckhitler.org不在mydestination选项所指定的域名,所以转发失败.
  

  

  

  

  5)行为控制
  

  5.1)发件和收件的限制
  

  smtpd_recipient_limit
  设置一封邮件允许有多少个收件人,该参数默认为1000.
  

  我们为了测试将该&#20540;改为2,如下:
  smtpd_recipient_limit = 2
  

  进行测试:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  helo 220 mail.ckhitler.org ESMTP Postfix
  

  501 Syntax: HELO hostname
  mail from:<root@ckhitler.org>
  250 2.1.0 Ok
  rcpt to:<test@ckhitler.org>
  250 2.1.5 Ok
  rcpt to:<root@ckhitler.org>
  250 2.1.5 Ok
  rcpt to:<bin@ckhitler.org>
  452 4.5.3 Error: too many recipients
  

  注:我们看到这里只能有2个收件人.
  

  建议修改为50个收件人,:
  smtpd_recipient_limit = 50
  

  

  message_size_limit
  设置一封邮件大小(包括正文,附件等所有内容),该参数默认&#20540;为10MB
  

  我们为测试将message_size_limit设为100,即只接收100个字节的邮件.
  message_size_limit = 100
  

  进行测试:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  mail from:<root@ckhitler.org>220 mail.ckhitler.org ESMTP Postfix
  

  250 2.1.0 Ok
  rcpt to:<test@ckhitler.org>
  250 2.1.5 Ok
  data
  354 End data with <CR><LF>.<CR><LF>
  ssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssss
  eeeeeeeeeeeeeeeeeeeeeeeeeess
  fffffffffffffffffffffffffffs
  wwwwwwwwwwwwwwwwwwwwwwwwwwww
  xxxxxxxxxxxxxxxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxxxxxxxxxxxxxxx
  .
  552 5.3.4 Error: message file too big
  

  我们这里可以更改为20MB,即每封邮件最大为20MB,如下:
  message_size_limit = 20480000
  

  

  

  mailbox_size_limit
  设置用户的邮箱大小,注意,邮箱的限额不能小于设置的邮件限额.
  

  例如,我们这里设置用户的邮箱的限额1024
  mailbox_size_limit = 1024
  设置邮件的限额为1000,如下:
  message_size_limit = 1000
  

  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  mail from:<root@ckhitler.org>
  250 2.1.0 Ok
  rcpt to:<test@ckhitler.org>
  250 2.1.5 Ok
  data
  354 End data with <CR><LF>.<CR><LF>
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  .
  250 2.0.0 Ok: queued as DD385163C49
  quit
  

  查看邮箱大小:
  ls -l
  total 4
  -rw-------  1 root  mail   0 Jul 19 06:21 root
  -rw-rw----. 1 rpc   mail   0 May 10 07:39 rpc
  -rw-rw----. 1 test  mail 551 Jul 19 06:41 test
  -rw-rw----. 1 test1 mail   0 Jul 16 20:27 test1
  

  我们再次发送给test相同大小的邮件,如下:
  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  mail from:<root@ckhitler.org>
  250 2.1.0 Ok
  rcpt to:<test@ckhitler.org>
  250 2.1.5 Ok
  data
  354 End data with <CR><LF>.<CR><LF>
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  ssssssssssssssssssssssssssssssss
  .
  250 2.0.0 Ok: queued as DD385163C49
  quit
  

  再次查看邮箱大小,发现邮箱还没改变,说明邮箱限额起了作用,如下:
  ls -l
  total 4
  -rw-------  1 root  mail   0 Jul 19 06:21 root
  -rw-rw----. 1 rpc   mail   0 May 10 07:39 rpc
  -rw-rw----. 1 test  mail 551 Jul 19 06:41 test
  -rw-rw----. 1 test1 mail   0 Jul 16 20:27 test1
  

  

  

  5.2)客户端连接控制
  

  smtpd_error_sleep_time
  当SMTP服务端口接收到非法的命令时,系统将缓冲处理的时间间隔,我们调整smtpd_error_sleep_time10.
  如下:
  smtpd_error_sleep_time = 10s
  

  smtpd_soft_error_limit
  当超过smtpd_soft_error_limit参数所指定的错误次数时,系统应用smtpd_error_sleep_time参数所指定的缓冲时间.
  如下:
  smtpd_soft_error_limit = 2
  

  smtpd_hard_error_limit
  当超过smtpd_hard_error_limit参数所指定的错误次数时,系统强制断开客户端的连接.
  如下:
  smtpd_hard_error_limit = 5
  

  注:上面的配置说明如果用户连接SMTP输入的错误指令超过2,系统将缓冲处理10秒钟,以后每输错一种指令都延时10秒钟,直到累加超过5,断开连接,我们做测试如下:
  

  telnet 192.168.75.128 25
  Trying 192.168.75.128...
  Connected to 192.168.75.128.
  Escape character is '^]'.
  220 mail.ckhitler.org ESMTP Postfix
  test
  502 5.5.2 Error: command not recognized
  test
  502 5.5.2 Error: command not recognized
  test          /*注意:在输入第三次错误指令后,在这里延时10秒钟*/
  502 5.5.2 Error: command not recognized
  test          /*注意:在输入第四次错误指令后,在这里延时10秒钟*/
  502 5.5.2 Error: command not recognized
  test          /*注意:在输入第五次错误指令后,在这里延时10秒钟*/
  502 5.5.2 Error: command not recognized
  test          /*注意:在输入第六次错误指令后,postfix断开客户端连接*/
  421 4.7.0 mail.ckhitler.org Error: too many errors
  Connection closed by foreign host.
  

  

  

  6)性能控制
  

  6.1)
  default_process_limit
  通过default_process_limit 参数来控制postfix系统同时可以运行的最大进程数目.缺省&#20540;是50.
  

  为了能提高并行处理能力,可以提高进程最大数目,如下:
  default_process_limit = 300
  

  

  

  6.2)
  initial_destination_concurrency
  控制对同一目标主机的初始化并发连接数目,缺省&#20540;为2.
  

  default_destination_concurrency_limit
  控制初始化连接后对同一目标主机的最大并发连接数目,缺省&#20540;为10.
  

  local_destination_concurrency_limit
  控制对同一本地收件人的最大同时投递的邮件数目,缺省&#20540;为2.
  

  

  6.3)
  queue_run_delay
  设置队列管理进行扫描deferred邮件队列的频率,缺省&#20540;为1000.
  这里我们建议将扫描频率改为3600.
  

  maximal_queue_lifetime
  设置postfix在放弃投递而返回不可投递信息前,被延迟邮件再deferred邮件队列中的生存时间.
  这里我们建议将生存时间改为3
  

  minimal_backoff_time
  当一封邮件投递失败后,邮件队列将在一段时间内忽视该邮件的存在,也就是我们前面讲的时间戳,该参数就是用来设置最小的时间戳,缺省&#20540;为1000.
  这里我们建议将最小忽视时间改为300
  

  maximal_backoff_time
  设置最大的时间戳,缺省&#20540;是4000
  最大忽视时间保持默认即可.
  

  6.4)
  line_length_limit
  控制读入数据时每一行的大小,如果太长则强行将其分割成更短的行,太长的行在投递时再重组.缺省&#20540;为2048 bytes.
  这里保持默认即可.
  

  header_size_limit
  限制信头长度,缺省&#20540;为102400bytes.
  

  queue_minfree
  设置整个队列目录最大使用的磁盘功能,缺省为无限制,建议该&#20540;最好时message_size_limit的数倍以便于处理大邮件.
  
  bounce_size_limit
  限制某一邮件不可投递时,返回给发件人不可投递报告的大小,缺省&#20540;为50000 bytes.
  

  6.5)
  qmgr_message_recipient_limit
  设置内存中收件人地址的最大数目,缺省&#20540;为10000
  
  qmgr_message_active_limit
  设置active邮件队列中邮件数目的最大&#20540;,缺省&#20540;为1000,这里可以调整为10000.
  
  duplicate_filter_limit
  设置需要localcleanup后台程序记住的收件人地址的最大数目,缺省&#20540;为1000.
  

  

  6.6)
  command_time_limit
  设置local程序等待一个外部命令完成的时间,缺省&#20540;为1000.
  

  

  6.7)
  deliver_lock_attempts
  设置锁定一个文件的最大尝试次数,缺省&#20540;为5.
  
  deliver_lock_delay
  设置如果锁定一个文件失败后再次尝试的等待时间,缺省&#20540;为1.
  

  

  6.8)
  fork_attempts
  试图重启动一个进程的最大尝试次数,缺省&#20540;为5.
  

  fork_delay
  每两次尝试之间的等待时间,缺省&#20540;为1.
  
  transport_retry_time
  队列管理进程每两次尝试连接一个不正常的投递代理进程之间的等待时间,缺省为60.
  

  

  

  7)postfix的配置模板
  

  ##########################################
  #设定主机名称 myhostname
  #设定发信时所显示的发信源主机 myorigin
  #设定网域名称 mydomain
  #设定能够收信的主机名称 mydestination
  ##########################################
  myhostname = mail.ckhitler.org
  mydomain = ckhitler.org
  myorigin = ckhitler.org
  mydestination = $myhostname,$mydomain
  

  

  ##########################################
  #监听的网络地址,这里监听所有网络介质
  ##########################################
  inet_interfaces = all
  

  

  ##########################################
  #设定转发信任网络 mynetworks
  #规范可以转发的域名 relay_domains
  ##########################################
  mynetworks = 127.0.0.0/8, 192.168.75.0/24
  relay_domains = $mydomain
  

  

  ###########################################
  #客户端在执行HELO命令时,对客户端的合法性进行检查
  #1)如果HELO命令所带的主机名参数不符合语法规范则拒绝客户机的连接请求
  #2)拒绝未知的主机名的连接.所谓未知的主机名是指该主机没有DNSA记录或MX记录
  #3)如果客户端执行HELO命令时的主机名不是RFC规定的完整的域名则拒绝客户端的连接请求
  ###########################################
  smtpd_helo_restrictions = reject_invalid_hostname,reject_unknown_hostname,reject_non_fqdn_hostname
  

  

  ##########################################
  #允许/拒绝客户端使用邮件服务器 smtpd_client_restrictions
  #1)拒绝来自属于RBLRHSBL列表中的地址进行连接
  ##########################################
  smtpd_client_restrictions = permit_mynetworks,check_client_access hash:/etc/postfix/access,
  reject_rbl_client cblless.anti-spam.org.cn,
  reject_rbl_client sbl-xbl.spamhaus.org,
  reject_rbl_client relays.ordb.org,
  reject_rhsbl_client dsn.rfc-ignorant.org
  

  

  ##########################################
  #通过发件人在执行MAIL FROM命令时提供的地址进行限制
  #1)如果MAIL FROM命令提供的主机名在DNS中没有相应的AMX记录则拒绝该客户端的连接请求
  #2)如果MAIL FROM命令提供的主机名不是RFC规定的完整的域名则拒绝客户端的连接请求.
  ##########################################
  smtpd_sender_restrictions = reject_unknown_sender_domain,
  reject_non_fqdn_sender
  

  

  ##########################################
  #通过发件人在执行RCPT TO命令时提供的地址进行限制
  #1)如果收件人的邮件地址在DNS中没有相应的A MX 记录则拒绝该客户端的连接请求
  #2)不管客户端的主机名,只要符合以下的条件,就不拒绝该客户端SMTP连接请求:
  #  2.1)解析后的目标地址符合$relay_domains及其子域
  #  2.2)解析后的目标地址符合$inet_interfaces,$mydestination$virtual_maps
  #3)如果发件人在执行RCPT TO命令时提供的地址不是完整的域名则拒绝其SMTP连接请求
  #4)如果符合以下的条件,则接受SMTP连接请求,否则拒绝该连接
  #  4.1)客户端主机名符合$relay_domains及其子域
  #  4.2)目的地为$inet_interfaces$mydestination$virtual_maps
  ##########################################
  smtpd_recipient_restrictions = reject_non_fqdn_recipient,
  reject_unknown_recipient_domain,
  reject_unauth_destination,
  permit_mynetworks
  check_relay_domains
  

  

  ###########################################
  #客户端在SMTP会话的开始必须发送一个HELO命令
  ###########################################
  smtpd_helo_required = yes
  

  

  ###########################################
  #RFC 821对邮件的信头做了严&#26684;的规定
  ###########################################
  strict_rfc821_envelopes = yes
  

  

  ###########################################
  #设置一封邮件允许有多少个收件人,这里指定一封邮件可以同时发给50个人
  ###########################################
  smtpd_recipient_limit = 50
  

  

  ###########################################
  #设置一封邮件大小(包括正文,附件等所有内容),这里指定为20MB
  ###########################################
  message_size_limit = 20480000
  

  

  ###########################################
  #设置用户邮箱在大小,这里为2GB
  ###########################################
  mailbox_size_limit = 2048000000
  

  

  ###########################################
  #SMTP服务端口接收到非法的命令时,系统将缓冲处理的时间间隔,这里指定为10
  ###########################################
  smtpd_error_sleep_time = 10s
  

  

  ###########################################
  #当超过该参数所指定的错误次数时,系统应用缓冲时间,10,这里指定错误次数为2
  ###########################################
  smtpd_soft_error_limit = 2
  

  

  ###########################################
  #当超过该参数所指定的错误次数时,系统强制断开客户端,这里指定为5
  ###########################################
  smtpd_hard_error_limit = 5
  

  

  ###########################################
  #提高并行处理能力,提高进程最大数目,这里指定为300
  ###########################################
  default_process_limit = 300
  

  

  ###########################################
  #控制对同一目标主机的初始化并发连接数目,这里调整为10
  ###########################################
  initial_destination_concurrency = 10
  

  

  ###########################################
  #控制初始化连接后对同一目标主机的最大并发连接数目,这里调整为10
  ###########################################
  default_destination_concurrency_limit = 10
  

  

  ###########################################
  #控制对同一本地收件人的最大同时投递的邮件数目
  ###########################################
  local_destination_concurrency_limit = 2
  

  

  ###########################################
  #设置postfix在放弃投递而返回不可投递信息前,被延迟邮件再deferred邮件队列中的生存时间
  ###########################################
  maximal_queue_lifetime = 3d
  

  

  ###########################################
  #设置队列管理进行扫描deferred邮件队列的频率,这里调整为1小时
  ###########################################
  queue_run_delay = 3600s
  

  

  ###########################################
  #当一封邮件投递失败后,邮件队列将在一段时间内忽视该邮件的存在,最小的忽略时间为300
  ###########################################
  minimal_backoff_time = 300s
  

  

  ###########################################
  #当一封邮件投递失败后,邮件队列将在一段时间内忽视该邮件的存在,最大的忽略时间为3600
  ###########################################
  maximal_backoff_time = 3600s
  

  

  ###########################################
  #控制读入数据时每一行的大小,这里为2048个字节
  ###########################################
  line_length_limit = 2048
  

  

  ###########################################
  #限制信头长度
  ###########################################
  header_size_limit = 102400
  

  

  ###########################################
  #设置整个队列目录最大使用的磁盘功能,这里调整为2GB
  ###########################################
  queue_minfree = 2048000000
  

  

  ###########################################
  #限制某一邮件不可投递时,返回给发件人不可投递报告的大小
  ###########################################
  bounce_size_limit = 50000
  

  

  ###########################################
  #内存中收件人地址的最大数目,这里为20000
  ###########################################
  qmgr_message_recipient_limit = 20000
  

  

  ###########################################
  #设置active邮件队列中邮件数目的最大&#20540;
  ###########################################
  qmgr_message_active_limit = 20000
  

  

  ###########################################
  #设置需要localcleanup后台程序记住的收件人地址的最大数目
  ###########################################
  duplicate_filter_limit = 1000
  

  

  ###########################################
  #设置local程序等待一个外部命令完成的时间
  ###########################################
  command_time_limit = 1000s
  

  

  ###########################################
  #设置锁定一个文件的最大尝试次数
  ###########################################
  deliver_lock_attempts = 5
  

  

  ###########################################
  #设置如果锁定一个文件失败后再次尝试的等待时间
  ###########################################
  deliver_lock_delay = 1s
  

  

  ###########################################
  #试图重启动一个进程的最大尝试次数
  ###########################################
  fork_attempts = 5
  

  

  ###########################################
  #每两次尝试之间的等待时间
  ###########################################
  fork_delay = 1s
  

  

  ###########################################
  #队列管理进程每两次尝试连接一个不正常的投递代理进程之间的等待时间
  ###########################################
  transport_retry_time = 60s

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-142998-1-1.html 上篇帖子: 解決Postfix被gmail退信問題 下篇帖子: Postfix email foward 配置指南
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表