公司的邮件服务器出问题了。直接telnet mail.XXX.com 25和telnet mail.XXX.com 110都能正常收到postfix和dovecot的正常回显。查看服务的话,也发现状态正常。重启两个服务,发现问题依旧。刚开始怀疑是policyd策略的问题 。后来进mysql数据里看了半天,也没看到什么不对的地方。后来直接把策略进程给关掉。通过mail命令向外发送,发现也不能发出去。

折腾了大概有十多分钟还没找到原因,开始有点慌了。后来想到sendmail搭建时的邮件队列问题。由是到网上查了下关于postfix邮件队列的说明。这一查,大吃了一惊。竟然有一个有的邮件占了好几万封。原来是开发的该仁兄写的一段关于邮件通知的代码写的有问题,导致其用公司的邮件系统不停的向他的163邮箱发送邮件。而163将其地址列为了垃圾地址。导致发送拒绝后,一直在队列里排了N多封。

查到原因就好办多了,利用postfix的队列删除命令,将其删掉就行了。其中涉及到的几个命令在此总结下:

  • postqueue -p 或 mailq查看队列邮件,postfix 支持传统的mailq命令,同时也有自己的 队列维护命令postqueue。
  • 使用postsuper 来维护队列。一般是先用mailq查看队列里的邮件,找到对应的id,然后用postsuper -d来删除。例如id是0EAF3A9B 那么postsuper -d 0EAF3A9B , postsuper -d ALL 这样就删除所有邮件啦。

删除所有发件人为test@361way.com 的队列:

1mailq |awk 'BEGIN { RS = "" } / test@361way.com$/ { print $1 }' | tr -d '*!' |postsuper -d –

在使用过程中,发现上面的脚本有时并不好使,而且太复杂,容易忘,我就精简了下,可以使用下面这个!

1mailq|grep <a href="mailto:test@361way|awk">test@361way|awk</a> '{ print $1 }'|postsuper -d -
  • 修复队列以及任何权限错误 postfix check
  • 查看邮件系统日志tail -f /var/log/maillog
  • 启动postfix postfix start
  • 停止postfix postfix stop
  • 重新读取postfix配置文件 postfix reload
  • 立即投递队列中所有邮件(慎用) postfix flush
  • 发送邮件放置目录:/var/spool/postfix

Postfix 邮件队列管理的几个 Perl 小程序,pfdel.pl 是用来删除队列中指定用户的邮件的,luserdel.pl 是用来删除队列中无效用户的邮件的,moqdel.pl 是用来删除队列中邮箱配额已满的用户的邮件的,jmoqdel.pl 是删除邮箱配额已满的用户的垃圾邮件箱的。

平时主要用的为pddel.pl,具体内容如下:

 1#!/usr/bin/perl -w
 2#
 3# pfdel - deletes message containing specified address from
 4# Postfix queue. Matches either sender or recipient address.
 5#
 6# Usage: pfdel <email_address>
 7#
 8use strict;
 9# Change these paths if necessary.
10my $LISTQ = "/usr/sbin/postqueue -p";
11my $POSTSUPER = "/usr/sbin/postsuper";
12my $email_addr = "";
13my $qid = "";
14my $euid = $>;
15if ( @ARGV !=  1 ) {
16    die "Usage: pfdel <email_address>n";
17} else {
18    $email_addr = $ARGV[0];
19}
20if ( $euid != 0 ) {
21      die "You must be root to delete queue files.n";
22}
23open(QUEUE, "$LISTQ |") ||
24  die "Can't get pipe to $LISTQ: $!n";
25my $entry = <queue>;    # skip single header line
26$/ = "";        # Rest of queue entries print on
27            # multiple lines.
28while ( $entry = <queue> ) {
29    if ( $entry =~ / $email_addr$/m ) {
30        ($qid) = split(/s+/, $entry, 2);
31        $qid =~ s/[*!]//;
32        next unless ($qid);
33        #
34        # Execute postsuper -d with the queue id.
35        # postsuper provides feedback when it deletes
36        # messages. Let its output go through.
37        #
38        if ( system($POSTSUPER, "-d", $qid) != 0 ) {
39            # If postsuper has a problem, bail.
40            die "Error executing $POSTSUPER: error " .
41              "code " .  ($?/256) . "n";
42        }
43    }
44}
45close(QUEUE);
46if (! $qid ) {
47    die "No messages with the address  " .
48      "found in queue.n";
49}
50exit 0;