プロジェクト

全般

プロフィール

pflogsummとbody_checkの競合対策(base64エンコード)

Postfixのbody_checksフィルタとpflogsumを併用すると、毎日送られるサマリに
「(当該メール)には(body_checksのこの定義に)に引っかかった行があります」
といった旨のメール本文が含まれるため、サマリメール自体がbody_checksに検知
され届かなくなる。

最悪、下記のようなループが発生する。
  1. スパムメールがbodychecksに引っかかる
  2. 翌日のサマリメールの(スパムメールの)bodychecks検知報告がbodychecksに引っかかる
  3. 翌日のサマリメールの(サマリが引っかかった報告の)bodychecks検知報告がbodychecksに引っかかる
  4. 翌日のサマリメールの(サマリが引っかかった報告の)bodychecks検知報告がbodychecksに引っかかる
  5. ……以下ループ

実質、一度bodycheckが機能するとpflogsumメールが受信できなくなる。

対策案

Postfixのサイトに以下のワークアラウンド記載がある。

上記ではpflogsumのメール本文をBase64エンコードすることにより、見た目は
そのままだがソース上はエンコード文字列が記載されるためbody_checksのフィルタ
に引っかからなくするという対策となる。

通常、pflogsumは付属の「/etc/cron.daily/pflogsumm_report」がpflogsumコマンド
を実行してメールを送信するまで行うが、ワークアラウンドでは次のように実行フロー
を変更する。

  1. pflogsumを実行し、出力内容を一時ファイルに保存する
  2. 一時ファイルをBase64エンコードして添付し送信する

前段のプログラムは「/etc/cron.daily/pflogsumm_report」、後段のプログラムが
上記アドレスのワークアラウンドプログラムとなる。

以下では「/etc/cron.daily/pflogsumm_report」を改修し、新たに「pflogsum_send」
プログラムを作成して問題に対応する。

導入

  • perlのBase64エンコードモジュールの導入
    # # yum install perl-MIME-Lite
    
  • 「pflogsum_send」コマンドを作成する
    「Path」には一時ファイルパスを指定する。後述の「pflogsumm_report」でも明示指定する。
    # vi /usr/sbin/pflogsumm_send
    -----------------------------
    #!/usr/bin/perl
    
    use MIME::Lite;
    
    ## Create a new message:
    
    $msg = MIME::Lite->new(
        From     => '送信元@example.com',
        To       => '宛先@example.com',
        Subject  => 'Postfix log summaries',
        Date     => `date`,
        Type     => 'text/plain',
        Encoding => 'base64',
        Path     => '/var/tmp/pflogsum.txt',
    );
    
    $msg->send;
    
  • 実行権限を付与する。
    # chmod 755 /usr/sbin/pflogsumm_send
    
  • pflogsumm_reportの次の内容を修正する。
    • メールの送信を行わない
    • 一時ファイルを明示的に指定して保持する
  • 「/etc/cron.daily/pflogsumm_report」ファイルを修正する
    1. REPORT変数の内容をmktemp(一時ファイル作成)からパスを指定
    2. REPORT一時ファイルをcatしてメール出力しないように修正
    3. 実行後にREPORT一時ファイルを削除しないように修正
    4. 最後に、作成した「pflogsum_send」コマンドを実行してメールを投げさせる
    # vi /etc/cron.daily/pflogsumm_report
    -----------------------------
    #!/bin/bash
    MAILLOG=`mktemp`
    for log in `ls /var/log/maillog-*|sort`
    do
        cat $log >> $MAILLOG
    done
    # /var/log/maillog-*を昇順にソートして$MAILLOG変数に代入
    cat /var/log/maillog >> $MAILLOG
    
    #1. REPORT変数の内容をmktemp(一時ファイル作成)からパスを指定
    #REPORT=`mktemp`
    REPORT="/var/tmp/pflogsum.txt" 
    
    # pflogsumm コマンドで解析した結果を$REPORTに格納する
    pflogsumm --problems_first --verbose_msg_detail --mailq -d yesterday $MAILLOG > $REPORT
    
    # $REPORTを本文に、最初の1行を件名に宛先はpostmasterを指定してメールを送信する。
    #2. REPORT一時ファイルをcatしてメール出力しないように修正
    #cat $REPORT | mail -s "`head -1 $REPORT` in `uname -n`" -r 送信元@example.com 送信先@example.com
    
    # 不要となった$REPORTファイルを削除する
    #3. 実行後にREPORT一時ファイルを削除しないように修正
    #rm -f $MAILLOG $REPORT
    rm -f $MAILLOG
    
    #4. 最後に、作成した「pflogsum_send」コマンドを実行してメールを投げさせる
    /usr/sbin/pflogsumm_send
    

テスト実行

  • 「/etc/cron.daily/pflogsumm_report」を実行する
    # /etc/cron.daily/pflogsumm_report
    
  • 「pflogsum_send」に設定したアドレス宛にメールが送信されること

自動実行設定

  • 改修前通り「/etc/cron.daily」以下にスクリプトを配置しているので日次実行される。