如何永久删除 sendmail 队列中的电子邮件并防止它们再次出现?

如何永久删除 sendmail 队列中的电子邮件并防止它们再次出现?

我这里有一个相当烦人的问题。我一直在测试一个应用程序,并创建了一些测试电子邮件到虚假的电子邮件地址(更不用说我的服务器实际上并没有设置为发送电子邮件)。当然,无法sendmail发送这些消息,它们一直卡在队列中。我想手动删除队列中累积的消息,而不是等待通常需要sendmail5 天才能停止重试。sendmail

我正在使用 Ubuntu 10.04,/var/spool/mqueue/这是我读过的所有指南中都提到的用于保存排队的电子邮件的目录。当我删除此目录中的文件时,系统sendmail会停止处理电子邮件,直到运行一个看似 cron 脚本的程序,并用我不想发送的消息重新填充此目录。以下是我的几行代码syslog

Jun  2 17:35:19 sajo-laptop sm-mta[9367]: o530SlbK009365: to=, ctladdr= (33/33), delay=00:06:27, xdelay=00:06:22, mailer=esmtp, pri=120418, relay=e.mx.mail.yahoo.com. [67.195.168.230], dsn=4.0.0, stat=Deferred: Connection timed out with e.mx.mail.yahoo.com.
Jun  2 17:35:48 sajo-laptop sm-mta[9149]: o4VHn3cw003597: to=, ctladdr= (33/33), delay=2+06:46:45, xdelay=00:34:12, mailer=esmtp, pri=3540649, relay=mx2.hotmail.com. [65.54.188.94], dsn=4.0.0, stat=Deferred: Connection timed out with mx2.hotmail.com.
Jun  2 17:39:02 sajo-laptop CRON[9510]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -n 200 -r -0 rm)
Jun  2 17:39:43 sajo-laptop sm-mta[9372]: o52LHK4s007585: to=, ctladdr= (33/33), delay=03:22:18, xdelay=00:06:28, mailer=esmtp, pri=1470404, relay=c.mx.mail.yahoo.com. [206.190.54.127], dsn=4.0.0, stat=Deferred: Connection timed out with c.mx.mail.yahoo.com.
Jun  2 17:39:50 sajo-laptop sm-mta[9149]: o51I8ieV004377: to=, ctladdr= (33/33), delay=1+06:31:06, xdelay=00:03:57, mailer=esmtp, pri=6601668, relay=alt4.gmail-smtp-in.l.google.com. [74.125.79.114], dsn=4.0.0, stat=Deferred: Connection timed out with alt4.gmail-smtp-in.l.google.com.
Jun  2 17:40:01 sajo-laptop CRON[9523]: (smmsp) CMD (test -x /etc/init.d/sendmail && /usr/share/sendmail/sendmail cron-msp)

有人知道我该如何永久删除这些邮件吗?顺便说一句,我还想知道是否有办法设置sendmail“假”发送电子邮件。有吗?

答案1

已发送或正在尝试发送的消息存储在 中/var/spool/mqueue。Sendmail 还未尝试排队的消息可以在 中找到/var/spool/mqueue-client

所以尝试一下(我假设你想摆脱全部队列中的消息):

  • 停止 sendmail
  • rm /var/spool/mqueue/*
  • 如果您想删除等待中的消息,rm /var/spool/mqueue-client/*
  • 启动 sendmail

这将清除您的队列文件夹,直到系统收到另一条消息。您可以通过运行mailq(两个队列文件夹)或sendmail -bp(仅队列文件夹)进行仔细检查。

笔记: 在大多数 Linux 发行版中,您可以使用 或 来启动/停止服务service sendmail <start|stop|restart>/etc/init.d/sendmail <start|stop|restart>这两个选项都有许多其他状态标志,可以通过输入不带状态标志的命令和服务来观察。

答案2

您经常会发现有人建议从 Sendmail 的 mqueue 目录中删除文件,例如rm /var/spool/mqueue/*或更糟糕的是(rm -rf等等)。恕我直言,这很危险。在许多情况下,这种方法有效,但我建议您系好安全带。简单地从 mqueue 中删除所有文件可能会删除合法邮件。

在删除排队消息之前停止 Sendmail 是个好建议,尤其是在需要删除大量消息的情况下。但是,如果只删除少量消息,或者定期清理队列(例如通过 cron 作业),则实际上无需停止 Sendmail。在最坏的情况下,其中一条消息将重新排队,当您重试时,它几乎肯定会被删除。

相反,停止 Sendmail(例如在 Ubuntu 中使用service sendmail stop)可能还不够。即使停止,某些(子)进程可能仍在运行。必须等到它们完成(推荐)或终止它们。

为了安全地从 mqueue 中删除消息,您需要消息的队列 ID。ID 显示在日志中的“sm-mta[...]:”后面。日志摘录中的 ID 为o530SlbK009365o4VHn3cw003597、... 对于每个 ID,mqueue 中都存储了 2 个文件,一个以“qf”开头,另一个以“df”开头。

mailq通常用于列出队列的内容。它在第一列显示 ID。此外,您应该查阅mailq的输出,因为它还显示消息是否处于活动状态/当前正在处理中。例如

-----Q-ID----- --Size-- -----Q-Time----- ------------Sender/Recipient----------
oBDDuKAB023946*    1058 Mon Dec 13 14:56 <[email protected]
                 (Deferred: 450-4.2.1 The user you are trying to contact is re)
                                         <[email protected]>
oBAEMuV8000429     1058 Fri Dec 10 15:22 <[email protected]
                 (Deferred: 450-4.2.1 The user you are trying to contact is re)
                                         <[email protected]>

在此示例中,ID 为 的消息oBDDuKAB023946当前正在处理中,以附加的星号表示。其他消息可以安全删除。例如,为了删除 ID 为 的消息,oBAEMuV8000429请使用

rm /var/spool/mqueue/{d,q}foBAEMuV8000429

Brandon Hutchinson 在从邮件队列中删除邮件。Brandon 还包括根据域部分、电子邮件地址等删除消息的脚本。Brandon 的脚本对于定期清理或批量删除非常有帮助。

尽管如此,即使是 Brandon 的脚本也没有处理消息的状态。不过,添加起来很容易。在脚本开头添加

# Get current mailq status
my $mailq = `mailq`;

然后,在子程序“wanted”的开头添加一个检查以跳过活动消息,例如

# skip if file is currently processed by MTA
if ($mailq =~ /\n$queue_id\*/) {
   $debug && print "$queue_id is locked.\n";
   last;
}

HTH。还有,记得备份 :-)

答案3

我遇到了同样的问题,发现有两个文件夹包含排队消息。文件夹 /var/spool/clientmqueue/ 中包含的消息如果无法传递,则最终会进入 /var/spool/mqueue/。必须从这两个文件夹中删除文件才能解决问题。

rm -f /var/spool/clientmqueue/* rm -f /var/spool/mqueue/*

答案4

我使用这个 bash 脚本成功做到了这一点

for i in `sudo ls /var/spool/mqueue`
do
    sudo rm -rv `echo /var/spool/mqueue/$i`
done

相关内容