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

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

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

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

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 (в зависимости от вашей платформы) и создать фильтр. Фильтр имеет возможность выполнить регулярное выражение для самого сообщения. Все, что вам нужно сделать, это отправить его в конкретный пункт назначения, этот пункт назначения будет MySQL. Быстрый поиск расскажет вам, как настроить syslog-ng на mysql, а некоторые настройки, вероятно, дадут вам фильтр для отправки в этот пункт назначения.

Другие вопросы по тегам