バウンスされたメッセージをデータベースに記録する (仮想ドメイン/ユーザーを持つ Postfix)

バウンスされたメッセージをデータベースに記録する (仮想ドメイン/ユーザーを持つ Postfix)

私たちは、それぞれ仮想ユーザーを持つ仮想ドメインが 2 つある postfix をインストールしています。これらのドメインとユーザーは、mysql データベースを使用してマップされます。私はこれまで、postfix ログ ファイルを解析してバウンスを追跡してきました。これを行うには、もっと良い、効率的な方法があるはずです。私は 3 つの方法を思いつきましたが、どれが最適かはわかりません。

  1. バウンスを記録してメールを破棄するPostfixコンテンツフィルタを作成する
  2. procmail を使用します - ただし、$HOME が定義されていない仮想ユーザーに対して procmail がどのように動作するかはわかりません
  3. メールボックスからメールをPOPし、解析してログに記録し、返送されたメールを削除するスクリプトを作成します。

メンテナンスの観点からはどれが最適か、またサーバーリソースの節約の観点からはどれが効率的かアドバイスをいただければ幸いです。よろしくお願いします

答え1

ここでは、バウンスしたメール自体ではなく、バウンスに関する情報を収集することを前提としています。

私は、postfix、mysql、仮想ホストをほぼ同じように設定しています。ハードウェア リソースの観点から、これを追跡する最も効率的な方法は、実行しているときにログ ファイルを解析することです。ただし、解析方法が大きすぎると思われる場合は、Logwatch などのアプリケーションを使用して、すべての解析を実行できます。次に、Postfix を設定して、バウンスされたファイルを破棄します。

実際にこれらの電子メールをどこかに収集することに決めた場合は、main.cf ファイルで次の設定を使用できます。

bounce_notice_recipient = [email protected]
error_notice_recipient = [email protected]

メールを完全に破棄したい場合は、仮想ユーザーを追加し、エイリアスファイルを調整して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";
}

?>

その後、mail.log がリサイクルされる直前に cron を起動したり、cron が起動したらログをクリアしたりすることができます。

バウンスされたメールのメールアドレスを追跡するのは大変な作業のように思えます。もちろん、この情報にアクセスするには、MySQL クエリを作成する必要があります。

また、mysql の処理を​​完全に省略して、結果をテスト ファイルまたは電子メール アドレスにパイプすることもできます (cron を使用することもできます)。

php parse.php > results.txt

または

php parse_logs.php | /usr/sbin/sendmail [email protected]

答え2

試したことがないので例はありませんが、syslog-ng (プラットフォームによって異なります) を使用してフィルターを作成できます。フィルターには、メッセージ自体に正規表現の一致を実行するオプションがあります。必要なのは、特定の宛先に送信することだけです。その宛先は mysql です。簡単に検索すると、syslog-ng を mysql に設定する方法がわかり、少し調整すれば、その宛先に送信するフィルターが手に入るでしょう。

答え3

バウンス通知をスクリプトにパイプすることができます。実装方法の概要は次のとおりです。

/etc/postfix/main.cf

notify_classes = bounce, 2bounce, resource, software
[email protected]
[email protected]

/etc/postfix/トランスポート

[email protected]     bouncepipe:

マスター

bouncepipe   unix  -       n       n       -       -       pipe
      flags=DRhu user=list argv=/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

関連情報