Назад | Перейти на главную страницу

Запись возвращенных сообщений в базу данных (Postfix с виртуальными доменами / пользователями)

У нас есть постфиксная установка с парой виртуальных доменов, каждый с виртуальными пользователями. Эти домены и пользователи отображаются с помощью базы данных mysql. До сих пор я отслеживал отказы, анализируя файл журнала postfix. Я подозреваю, что должны быть лучшие и более эффективные способы сделать это. Я подумал о трех, но не уверен, что лучше:

  1. Напишите фильтр содержимого Postfix, который регистрирует отказы и отбрасывает почту
  2. Используйте procmail, но я не уверен, как procmail будет работать с виртуальными пользователями, у которых не определен $ HOME
  3. Напишите сценарий, который отправляет почту из почтовых ящиков; анализирует и регистрирует их и удаляет возвращенное письмо

Я был бы признателен за совет о том, что было бы лучше всего с точки зрения обслуживания и эффективным с точки зрения экономии ресурсов сервера. Спасибо

Все это предполагает, что вы хотите собирать информацию о недоставленных сообщениях, а не о самом возвращенном письме:

У меня почти такая же настройка с postfix, mysql и виртуальными хостами. С точки зрения аппаратных ресурсов самый эффективный способ отслеживать это - анализировать файлы журналов в процессе работы. Но если вы думаете, что процесс синтаксического анализа является слишком большой нагрузкой, вы можете использовать такое приложение, как Logwatch, чтобы выполнить весь анализ за вас. Затем настройте Postfix, чтобы избавиться от возвращенных файлов.

Теперь, если вы решили, что действительно хотите где-то собирать эти электронные письма, вы можете использовать эти настройки в файле main.cf:

bounce_notice_recipient = someone@nowhere.com
error_notice_recipient = someone@nowhere.com

И если вы хотите, чтобы электронные письма были полностью уничтожены, вы можете добавить виртуального пользователя и настроить файл псевдонимов для отправки их в dev / null.

someone: /dev/null

Что касается сценария и базы данных, в наши дни я много работаю с 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";
}

?>

Затем вы можете запустить cron прямо перед тем, как ваш mail.log будет настроен на переработку, или очистить журнал после запуска cron.

Похоже, что нужно приложить немало усилий, чтобы отслеживать адреса электронной почты для отклоненных писем. Конечно, вам нужно будет написать запросы mysql, чтобы получить доступ к этой информации.

Вы также можете полностью пропустить материал mysql и просто передать результаты в тестовый файл или на адрес электронной почты (а также можете использовать cron)

php parse.php > results.txt

или

php parse_logs.php | /usr/sbin/sendmail someemailaddress@nowhere.com

Вы можете передать скрипту уведомления о недоставке. Просто в качестве обзора, как вы можете это реализовать:

/etc/postfix/main.cf

notify_classes = bounce, 2bounce, resource, software
2bounce_notice_recipient=bouncepipe@example.com
bounce_notice_recipient=bouncepipe@example.com

/ и т. д. / постфикс / транспорт

bouncepipe@example.com     bouncepipe:

/etc/postfix/master.cf

bouncepipe   unix  -       n       n       -       -       pipe
      flags=DRhu user=list argv=/etc/postfix/bouncepipe.pl

/etc/postfix/bouncepipe.pl

#!/usr/bin/perl                                                                                                                                                                                                                                                                       

my $message = '';
my $sender = '';
my $recipient = '';

foreach $line ( <STDIN> )
{
    $message .= $line;
    chomp( $line );
    if ( $line =~ /Final-Recipient: /)
    {
        my $index = index($line, ';');
        $recipient = substr($line, $index+2);
    }
    if ( $line =~ /X-Postfix-Sender: /)
    {
        my $index = index($line, ';');
        $sender = substr($line, $index+2);
    }
}
# Do whatever you need to do with $sender and $recipient

У меня нет примера, поскольку я никогда не пробовал это делать, но вы можете использовать syslog-ng (в зависимости от вашей платформы) и создать фильтр. filter имеет возможность выполнять сопоставление регулярного выражения с самим сообщением. Все, что вам нужно сделать, это отправить его в конкретное место назначения, этим местом назначения будет mysql. Быстрый поиск расскажет вам, как настроить syslog-ng на mysql, а некоторые настройки, вероятно, позволят вам получить фильтр для отправки в это место назначения.