将退回的消息记录到数据库(带有虚拟域/用户的 Postfix)

Ya.*_*man 3 email postfix filtering

我们有一个带有几个虚拟域的 postfix 安装,每个域都有虚拟用户。这些域和用户使用 mysql 数据库进行映射。到目前为止,我一直通过解析 postfix 日志文件来跟踪反弹。我怀疑必须有更好、更有效的方法来做到这一点。我想到了三个,但我不确定哪个最好:

  1. 编写一个 Postfix 内容过滤器来记录退回邮件并丢弃邮件
  2. 使用 procmail - 但我不确定 procmail 如何与没有定义 $HOME 的虚拟用户一起使用
  3. 编写一个脚本,从邮箱中 POP 邮件;解析并记录它们并删除退回的电子邮件

我很感激从维护的角度来看哪个最好,从节省服务器资源的角度来看哪个更有效。谢谢

Pat*_*k R 5

这一切都假设您想收集有关退回邮件的信息,而不是退回的电子邮件本身:

我对 postfix、mysql 和虚拟主机的设置几乎相同。从硬件资源的角度来看,跟踪此情况的最有效方法是在您执行操作时解析日志文件。但是,如果您认为自己的解析方式负载很大,则可以使用 Logwatch 之类的应用程序为您完成所有解析工作。然后设置 Postfix 为您丢弃退回的文件。

现在,如果您决定确实要在某处收集这些电子邮件,则可以在 main.cf 文件中使用这些设置:

bounce_notice_recipient = someone@nowhere.com
error_notice_recipient = someone@nowhere.com
Run Code Online (Sandbox Code Playgroud)

如果您希望完全销毁电子邮件,您可以添加一个虚拟用户并调整您的别名文件以将它们发送到 dev/null

someone: /dev/null
Run Code Online (Sandbox Code Playgroud)

至于脚本和数据库,这些天我经常使用 PHP 和 MySQL,所以如果我要使用这些工具,我可以创建一些 php 代码来读取日志文件,查找反弹,然后将它们放入数据库. 然后我会在 mail.log 被截断之前运行代码。事实上,我会在写完代码之后把代码贴在这里。

如果你想用 php/mysql 运行它,这里有一些代码(我相信它会更漂亮):

<?php
#parse_logs.php
# load local file into array
$val = file("mail.log");

$pattern = '/status=bounced/';

foreach ($val as &$value) {
if (preg_match($pattern,$value)) {
        $a = split('[<>]', $value);

       //if you prefer you can also use: preg_match_all('/<(.*)>/', '$value', $matches);
       #can be helpful to print the following to the screen during tests
       # echo $a[1];

        // Make a MySQL Connection
        mysql_connect("localhost", "username", "password") or die(mysql_error());
        mysql_select_db("postfix_db") or die(mysql_error());

        // Insert a row of information into the table "example"
        mysql_query("INSERT INTO emails (emailaddress) VALUES('$a[1]') ") 
        or die(mysql_error());  

        #again, if you want to see while running manually from cli
        #echo "Data Inserted!";

}
#again, if you want to see while running manually from cli
#echo "\n";
}

?>
Run Code Online (Sandbox Code Playgroud)

然后,您可以在将 mail.log 设置为回收之前启动 cron,或者在 cron 启动后清除日志。

似乎需要付出很多努力来跟踪退回电子邮件的电子邮件地址。当然,您需要编写 mysql 查询才能访问此信息。

您也可以完全跳过 mysql 的内容,只需将结果通过管道传输到测试文件或电子邮件地址(也可以使用 cron)

php parse.php > results.txt
Run Code Online (Sandbox Code Playgroud)

或者

php parse_logs.php | /usr/sbin/sendmail someemailaddress@nowhere.com
Run Code Online (Sandbox Code Playgroud)

  • 投了反对票。在邮件日志上使用 file() 通常是一个坏主意。发送任何数量邮件的服务器都会有日志,这些日志会相当快地积累数十甚至数百兆字节。file() 一次将整个文件加载到数组 [memory] ​​中。此外,此功能还有一些记录在案的问题,这些问题与访问其他进程正在访问的文件有关,邮件日志就是这种情况。 (2认同)