У нас есть постфиксная установка с парой виртуальных доменов, каждый с виртуальными пользователями. Эти домены и пользователи отображаются с помощью базы данных mysql. До сих пор я отслеживал отказы, анализируя файл журнала postfix. Я подозреваю, что должны быть лучшие и более эффективные способы сделать это. Я подумал о трех, но не уверен, что лучше:
Я был бы признателен за совет о том, что было бы лучше всего с точки зрения обслуживания и эффективным с точки зрения экономии ресурсов сервера. Спасибо
Все это предполагает, что вы хотите собирать информацию о недоставленных сообщениях, а не о самом возвращенном письме:
У меня почти такая же настройка с 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, а некоторые настройки, вероятно, позволят вам получить фильтр для отправки в это место назначения.