解析未送达的邮件标头(退回邮件)

Ric*_*ard 9 email email-server email-bounces

解析发送回我的服务器的退回(无法投递)电子邮件的标头并确定它是软退回还是硬退回的最佳方法是什么?

我只向我的用户发送选择加入的电子邮件,但有时一些电子邮件地址会过时。当电子邮件退回到我的服务器时,我想找出它退回的原因(软/硬)。然后我可以在我的数据库中适当地处理它和/或标记用户在下次登录时更新他们的电子邮件。

我正在使用 Ubuntu 和 Postfix。我已经成功地使用别名和虚拟别名实现了 VERP。因此,退回的电子邮件的返回路径为bolt+OrigEmailAddress@example.com,我可以将它们通过管道传输到脚本。

现在我已经设置了 VERP,我知道原始电子邮件发送给谁,但我需要解析返回的邮件标头以确定它是软退回还是硬退回。

处理这个问题的最佳方法是什么?据我了解,并非所有邮件服务器都遵循相同的规则,并且标头可以具有多种格式。是否有一些开源项目可以跟踪这些类型的事情?我可以实现一些简单的方法来正确地对大多数反弹进行分类?

我正在努力保护我的邮件服务器的声誉,因此非常感谢您的帮助!

Esa*_*nen 10

正如RFC3463解释的那样,以 5 开头的状态代码用于永久性故障,以 4 开头的状态代码用于持久性瞬时故障。您可以依赖服务器日志并尝试以下操作,而不是尝试解析具有不同格式的多条消息:

grep " dsn=5." /var/log/mail.log | grep -o -P " to=<(.+?)>" | sort | uniq -c
Run Code Online (Sandbox Code Playgroud)

这将从 mail.log(Postfix 格式)中找到永久性错误,并给出每个地址的地址和退回数量。您也可以使用“dsn=4”。获取具有临时错误的地址。


mas*_*oeh 8

通常有两种类型的反弹

  1. postfix投递邮件时直接拒绝远程邮件服务器导致的退回邮件。
  2. 由远程服务器(postfix 之后的下一跳服务器)引起的退回邮件无法将邮件传递给最终收件人。

上面的 Esa Jokinen的出色回答已经涵盖了第一个案例。最好的办法是解析邮件日志。

第二种情况是反弹的特殊情况。示例场景:

  • 您发送与接受电子邮件fakemail@example.commail.example.com服务器。
  • 在 mail.example.com 中,fakemail@example.com 的别名是realmail@example.net并且必须转发到mail.example.net
  • 有一天mail.example.net拒绝您的消息,因此mail.example.com必须将退回邮件发送到您的服务器。
  • 不幸的是,您服务器中的 maillog 将具有“dsn=2”,因为mail.example.com已经接受了该消息,但未能将其转发到mail.example.net

这里是第二种退回邮件的例子。有转发规则 Yahoo 邮件服务器myuser@yahoo.com -> myuser@example.net。不幸的是,example.net 的邮件服务器拒绝了该消息:(

From MAILER-DAEMON  Thu Mar  5 05:07:26 2015
Return-Path: <>
X-Original-To: noreply-myuser=yahoo.com@example.org
Delivered-To: noreply-263462085117-1425506829-myuser=yahoo.com@example.org
Received: from nm21-vm7.bullet.mail.gq1.yahoo.com (nm21-vm7.bullet.mail.gq1.yahoo.com [98.136.217.54])
        (using TLSv1 with cipher ECDHE-RSA-AES128-SHA (128/128 bits))
        (No client certificate requested)
        by mx.example.org (Postfix) with ESMTPS id D6365565FC
        for <noreply-263462085117-1425506829-myuser=yahoo.com@example.org>; Thu,  5 Mar 2015 05:07:25 +0700 (WIT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=bounce; t=1425506842; bh=zk/tWZNl6c36dmlPDmakM9ekK8cHVJANXMmSdsbkcWc=; h=From:To:Date:Subject:From:Subject; b=Im95h1qTg6qN3yUI7vF1fXtJ0SbUnzv8rUPwLbpNwxGPN2p8wfosXJzQgJ3nzr4L4ZQ50P2d9E9U4jEUNtnyi7nlFd5kKbtiVuda4H56h1PFnt+7wSpgHcd5Irs/lLODumb6ZZSEpCOWttcB9+JLaDfEUUPjGcbR+xww4XeH5Eo=
From: MAILER-DAEMON@yahoo.com
To: noreply-263462085117-1425506829-myuser=yahoo.com@example.org
Date: Wed, 04 Mar 2015 22:07:22 -0000
Subject: Failure Notice
X-Yahoo-Newman-Property: bmbounce

Sorry, we were unable to deliver your message to the following address.

<myuser@example.net>:
Remote host said:
550 5.1.1 User unknown
 [RCPT_TO]
Run Code Online (Sandbox Code Playgroud)

对于这种情况,您唯一的方法是解析退回邮件。不幸的是,没有标准的反弹格式,因此您必须解析正文并确定导致的拒绝。

您的 postfix 反弹解析的功能清单:

  1. 检查 VERP 地址是否有效。您不想解析无效消息。
  2. 解析身体,确定它们是软拒绝还是硬拒绝。

对于第二个功能,您可以谷歌一些常见的拒绝消息。这个例子是Jakub Liska的这个bounce-regex-list.xml


Esa Jokinen在下面关于这两种反弹类型的评论中提出了一个很好的观点。如果您的目标是保持服务器声誉,那么处理第一种反弹类型就足够了。第二次反弹是关于清理你的清单。因此,应该删除死电子邮件,从而释放服务器中的一些资源。

一些邮件列表管理器(例如 PHPlist 和 Mailman)也通过解析电子邮件正文来处理这种退回问题,因为他们没有资源来解析邮件日志。

  • 如果还需要处理自动转发到另一个地址的邮件,则此解决方案非常有用且更彻底。但是,如果目标是保护邮件服务器的声誉,处理直接拒绝就足够了。转发 MTA 的管理员应删除过时的转发和邮件列表(以保护其声誉并避免不必要的流量)。之后我们回到案例一。如果二次跳出量很大,OP 应使用此解决方案。哪个需要更少的努力。 (2认同)