どうも、自称Linuxサーバ評論家の瀬古草夫です。
で、前回の続きなんですが、メール振り分けプログラムのprocmailの設定ファイルprocmailrcを見てみます。ちなみに、この設定ファイルの :0 から始まる部分は、レシピと呼ばれているそうです。たぶん、自分で自由にメールの振り分け方法を作れるので、レシピと呼ばれているのだと思いますが・・・。
目次
設定ファイルprocmailrcを確認する
# vi /etc/procmailrc
SHELL=/bin/bash PATH=/usr/bin:/bin DROPPRIVS=yes MAILDIR=$HOME/Maildir DEFAULT=$MAILDIR/ SPAM=$MAILDIR/.Spam/ LOGFILE=$HOME/.procmail.log # ログ出力先 #VERBOSE=ON # 詳細ログ出力 # Clam AntiVirusによるウィルスチェック AV_REPORT=`/usr/bin/clamdscan --no-summary - 2>&1| awk -F\n -v ORS=' ' '{print}'|awk '{print $NF}'` VIRUS=`if [ "$AV_REPORT" != "OK" ]; then echo Yes; else echo No;fi` :0fw | formail -i "X-Virus: $VIRUS" # Clam AntiVirusがウィルス判定したメールは削除 :0 * ^X-Virus: Yes /dev/null # SpamAssassinによるスパムチェック :0fw |/usr/bin/spamc # SpamAssassinにより判定されたSpam-Levelが一定値(ここでは20)以上の場合は削除 # ※必要なメールが削除されてしまう可能性があることに留意すること :0 * ^X-Spam-Level: \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* /dev/null # SpamAssassinがスパム判定したメールはスパム専用メールボックスへ配送 :0 *^X-Spam-Flag: YES $SPAM
この設定ファイルをググってみたら、結構な数、ひっかかりますわな。
瀬古も、かな~り昔に、このファイルをどこかのサイトから拾ってきてそのまま自分のサーバに適用していた訳です。
そりゃ、人の作ったものを何も考えずそのままコピペしてたら、いざトラブった時に神頼みしかできないのも当然ですわ。
という事で、上の設定ファイルを順番に確かめていきます。
1行目~8行目までは、環境変数の定義、10行目からClam AntiVirusでウイルスチェックをしている事がわかります。
11行目を見ると
AV_REPORT=/usr/bin/clamdscan --no-summary - 2>&1| awk -F\n -v ORS=' ' '{print}'|awk '{print $NF}'
とあります。
こりゃ、なんじゃらほいですな。
まあ、clamdscan のコマンドを実行して、その結果をawkコマンドで整形して変数AV_REPORTに代入している事は、なんとか理解できます。
わし、awkコマンドなんぞ使ったことないし、どんな処理をしているのかいまいちピンときませんわ。
とりあえずは、 clamdscan – 2>&1 の出力結果がどのようになるかを確かめてみました。
clamdscan – 2>&1 の出力結果 (ウイルスなしメールの場合)
stream: OK ----------- SCAN SUMMARY ----------- Infected files: 0 Time: 0.010 sec (0 m 0 s)
clamdscan – 2>&1 の出力結果 (ウイルスありメールの場合)
stream: Win.Test.EICAR_HDB-1 FOUND ----------- SCAN SUMMARY ----------- Infected files: 1 Time: 0.006 sec (0 m 0 s) clamdscan --no-summary - 2>&1 stream: OK stream: Win.Test.EICAR_HDB-1 FOUND
次に、オプション –no-summary を追加した
clamdscan –no-summary – 2>&1の出力結果を確かめます。
clamdscan –no-summary – 2>&1の出力結果 (ウイルスなしメールの場合)
stream: OK
clamdscan –no-summary – 2>&1の出力結果 (ウイルスありメールの場合)
stream: Win.Test.EICAR_HDB-1 FOUND
きれいにサマリー(要約)が消えていますね。
次に、2>&1の意味なのですが、これは、標準エラー出力(2)を標準出力(1)にリダイレクト(>)しています。
なので、clamdscan -でウイルスチェック完了後に出力されるメッセージと、エラーが発生した時に出力されるメッセージの両方が、標準出力される訳です。
そもそも、clamdscanコマンドは、clamdが起動していないと利用できません。
という事は、 clamd を停止させれば、 clamdscanを実行した際、何らかのエラーが出力される事になります。
そこで、 clamd を停止させた時に、clamdscan –no-summary – 2>&1を実行した時の出力結果と、 clamdscan –no-summary – を実行した時の出力結果を見比べる事にします。
clamd を停止させた時に、clamdscan –no-summary – 2>&1を実行した時の出力結果
ERROR: Could not connect to clamd on LocalSocket /var/run/clamav/clamd.sock: No such file or directory ERROR: Could not lookup 127.0.0.1: Servname not supported for ai_socktype
clamd を停止させた時に、clamdscan –no-summary -を実行した時の出力結果
clamdscan –no-summary -を実行した場合は、何も出力されない事がわかりました。
次に、clamdを起動中に、clamdscan –no-summary -を実行した時の出力結果 を見てみます。
clamd 起動中に、clamdscan –no-summary -を実行した時の出力結果 (ウイルスなし)
stream: OK
clamd 起動中に、clamdscan –no-summary -を実行した時の出力結果 (ウイルスあり)
stream: Win.Test.EICAR_HDB-1 FOUND
非常にくどい実験をしましたが、clamdscanの出力結果は必要な情報です。
そして、awkを、ちょこっとだけお勉強させてもらいましたよ。
-F 指定の区切り文字
-v 変数の定義
ORS(出力レコード区切り文字)組み込み変数
との事なので、
awk -F\n -v ORS= ‘ ‘ ‘{print}’
は、どうやら改行コード(\n)をスペースの文字列に変換して複数行の内容を一行にしているようです。そして、
awk ‘{print $NF}’
は、スペースで区切られた最後のフィールドのみを出力しているようです。
つまり、clamdが起動時、 ウイルスありメールの場合、”FOUND”、ウイルスなしのメールの場合、”OK”、そして clamdの停止時は、”ai_socktype”が 変数AV_REPORTに代入される訳です。
そして、設定ファイルの12行目には、
VIRUS=`if [ "$AV_REPORT" != "OK" ]; then echo Yes; else echo No;fi`
とあります。これは条件文です。変数AV_REPORTの値がOKじゃない場合は、Yes、OKの場合は、Noを変数VIRUSに代入しています。
そして、設定ファイルの14行目
:0fw | formail -i "X-Virus: $VIRUS"
このレシピはメールのヘッダに追加する情報です。
ウイルスありメールの場合、X-Virus: Yes
ウイルスなしメールの場合、 X-Virus: No
がメールのヘッダに追加されます。
そして、設定ファイルの17行目
:0 * ^X-Virus: Yes /dev/null
このレシピは、メールヘッダの行頭がX-Virus: Yesとマッチしていれば、メールは、/dev/nullによって、永遠に消し去られる悲しい運命にあるのでした。
めでたしめでたし。
・・・じゃなかった。
メールが届かなかった原因
ここまで解析したら、メールが届かなかった理由がわかっちゃいますよね?
はい、単に何らかの原因で、clamdが停止していただけなのですわ。
VIRUS=`if [ "$AV_REPORT" != "OK" ]; then echo Yes; else echo No;fi`
問題はこの条件文です。
clamdが停止していたら、”ai_socktype”が 変数AV_REPORTに代入される訳ですやん。
という事は、AV_REPORTは、当然”OK”ではないので、ウイルスメールと判定されて、そのメールは、誰も目にも触れずに永遠の眠りにつく訳ですわ。
問題の解決
とにかく、 clamdが停止 していてもメールは受信したいし、 AV_REPORT=/usr/bin/clamdscan --no-summary - 2>&1| awk -F\n -v ORS=' ' '{print}'|awk '{print $NF}'
って、結構無駄な事をやっているようなので、下記のように書き換えました。
ついでに変数名も変えちゃいました。
CLAM_CHECK=`clamdscan --no-summary -|awk '{printf $NF}'` VIRUS=`if [ "$CLAM_CHECK" != "FOUND" ]; then echo No; else echo YES;fi`
たったこの2行の為に、長々と書いちゃいましたね。
でも原因がわかって、ほっとしております。
SHELL=/bin/bash PATH=/usr/bin:/bin DROPPRIVS=yes MAILDIR=$HOME/Maildir DEFAULT=$MAILDIR/ LOGFILE=$HOME/.procmail.log # ログ出力先 #VERBOSE=ON # 詳細ログ出力 ### Clam AntiVirusでメールチェック CLAM_CHECK=`clamdscan --no-summary -|awk '{printf $NF}'` VIRUS=`if [ "$CLAM_CHECK" != "FOUND" ]; then echo No; else echo YES;fi` ###出力確認用 #:0c #|echo "$CLAM_CHECK" >> /home/XXX/check.txt ###メールヘッダの追加 :0fw | formail -i "X-Virus: $VIRUS" ### ウイルスメールを削除 :0 * ^X-Virus: Yes /dev/null
コメント