2010年4月アーカイブ

毎日決まった時刻に送られてくる自動メルマガがなぜか今日は送られてこない。

おかしいなと思いつつもこういうときに限って日曜日で出かけたりしてる。


帰ってからサーバをチェックしてみるとなんと配送されてないキュー(deferedにたまりっぱなし)が約7000件・・・。


maillogをチェックしようにもどうやらログが膨大になりすぎてなかなか問題の部分が表示されない・・・

ようやく確認できたのが、

LibClamAV Warning: ***********************************************************
LibClamAV Warning: *** This version of the ClamAV engine is outdated. ***
LibClamAV Warning: *** DON'T PANIC! Read http://www.clamav.net/support/faq ***
LibClamAV Warning: ***********************************************************
LibClamAV Error: cli_hex2str(): Malformed hexstring: This ClamAV version has reached End of Life! Please upgrade to version 0.95 or later. For more information see www.clamav.net/eol-clamav-094 and www.clamav.net/download (length: 169)
LibClamAV Error: Problem parsing database at line 742
LibClamAV Error: Can't load daily.ndb: Malformed database
LibClamAV Error: cli_tgzload: Can't load daily.ndb
LibClamAV Error: Can't load /usr/XXXXXX/clamav/daily.cld: Malformed database
ERROR: Malformed database

とゆー部分。


最初の4行はいつものことなのでいいんだが、その後になんか見慣れないエラーが。

ここに気づくまでにかなりハマってしまい、amavisの設定ファイルやclamavの設定ファイルをいろいろいじくってみたり、パッケージをインストールしなおしてみたりしてもさっぱり変わらず、ようやくこちらのサイト
http://homepage.mac.com/yuji_okamura/iSawIt/archives/2010/04/entry_2452.html
のおかげで原因ぽいのがわかりました。

つまり簡単に言うと、clamavのバージョンを0.95以上にしないと、ついにファイルのスキャンができなくなりましたってゆーことらしい。

たしかにmaillogの他の部分を見てみると、「clamavのソケットに接続できなくてウイルススキャンに失敗しました」→「配送に失敗しました」みたいな流れがずらっと続いている。
(でもRPMで定期的に更新してんのはamavisの方なんだから、フツーは最初にamavisの方を疑うよなぁ・・・)


ほんでもって例のごとく、clamavの最新パッケージはyumから引っ張れないので以下を参考に、最新版のソースをダウンロードしてアップデートをしたわけです。

http://d.hatena.ne.jp/ooolong/20080102/1199294335
http://yokensaka.com/fedora/index.php?itemid=158

一個目のリンクはどうやら2個目のリンクの対処法を元に書いてあるみたいなんだけど、「yumのclamavパッケージ(依存も含む)を削除しておく」ってゆーのがウチの環境ではいけなかったみたいですね。
yumで削除したらinit.dのリストまでいじくられるわけで、デーモン(サービス)一覧からamavisデーモンまで無くなってしまったわけで・・・

ほんなわけで、再度yumからamavis-new、clamav、clamav-serverなどなど依存関係も含めてまるごとインストールしなおしてinit.dを元に戻した状態で、clamavの最新ソースを入れ直し(configure→make→make install)たらうまく行ったのです。


以上の作業が終わった時点から、溜まってたキューがどんどん送信され始めました。


ただ、GUIでサービス一覧を確認すると、amavisdは復活したけど今まであったclam.amavisdは復活しない。

でもコマンドで、
-----------------------------------

chkconfig --list

-----------------------------------
で確認すると、デーモン一覧にclamd.amavisdが入っている。
どうやらGUIにはパッケージでインストールしたものしか反映されないっぽい。

とりあえず、起動してみる。
-------------------------------------

/etc/init.d/clamd.amavisd start

------------------------------------


よし!起動成功!
ついでにランレベル3から5をONにする。

----------------------------------------

chkconfig clamd.amavisd on

---------------------------------------


デーモンを起動するとmaillogで騒いでた、「clamd.sock」が「/var/spool/amavisd」の中に出現。

これで「clamd.sockが見つかりません」というエラーが解決でき、点と点がつながったわけだ。

あ、そうそう、freshclamの定期実行もデフォルトに戻ってしまうみたいなので、
「/etc/sysconfig/freshclam」を開いて、最後の行をコメントアウトする。

-----------------------------------------------------------------------

FRESHCLAM_DELAY=disabled-warn # REMOVE ME
     ↓
#FRESHCLAM_DELAY=disabled-warn # REMOVE ME

----------------------------------------------------------------------


しかしclamavのおかげで費やした労力は今までも計りしれず、これからもこんな感じでやんなきゃなんねーのかと思うと、他のアンチウィルスソフトを使いたくなってしまうのは私だけではないはず。



メルマガを発行していて部数が増えてくるとよくあるのが、宛先からの自動返信。

「勝手に送ってくんなボケ」とか
「Re:クソスパマーへ返信します。」

とかいろいろ。

あと最近多いのが、
「いつも、メルマガ、楽しみに拝見しています。
実は、今回、メルマガ発行者さんに伝えたいことがあってメールしました。
 ・
 ・
 ・
このシステムで毎月、収入を得ています。
何もできない私でできるのですから、こんな素晴らしいメルマガを
書かれる方なら、きっとできることでしょう。
一度、下記のホームページをご覧になって下さい。
→URL」

といった、稼げる系の情報商材を自動返信で売り込んでくるメール。

だいたい送信元はgooメールかGメールのどちらか。

もちろん私は同意を得ていないメールアドレスをメルマガに勝手に登録したりしませんから、ボケとかクソとかは完全に向こう側のおかどちがいなのですが、さすがに毎回ボケとかクソとか言われるのは腹が立つ。

過去記事(http://www.igreks.jp/dev/2009/06/pop.html)で書いたPOPアクセスを用いてメルマガなどのエラーアドレスを自動で処理できる。

しかし、このやり方だけだと自動返信メールが処理できない。
なぜなら故意に設定された自動返信メールは、本文中にFROMとかTOとかSMTPサーバの返すメッセージが書いてないから。
つまり、フツーのメールを装って送信されてくる。

なので、前回のスクリプトを改良して自動返信メールにも対応させてみる。




[動作条件]
・perl5以上(確認した環境はは5.10)かつMail::POP3Clientモジュールがインストールされていること。
・POPアクセスにSSLを用いる場合(Gmailなど)は、さらにIO::Socket::SSLモジュール(要コンパイラ)が必要。
・あらかじめエラーメール受信専用のアドレスを作っておいて、メール送信する時にエンペロープFROMをそのアドレスに指定しておく。
・CRONなどで以下のスクリプトを実行する。
-------------------------------------------------------------------
#/usr/bin/perl -w
use strict;
use Mail::POP3Client;

my $log = "POPサーバに接続中・・・\n";

#コンストラクタ 
my $pop = new Mail::POP3Client(
  USER => 'pop_user', #popサーバのユーザ名
  PASSWORD => 'pop_pwd', #同パスワード
  HOST => 'pop.gmail.com', #popサーバ名
  AUTH_MODE => 'BEST', #認証モード(たいていはBESTでOK)
  DEBUG => 0, #デバッグ有無(正の整数を指定すると、プロンプトにサーバとのやりとりが表示される)
  TIMEOUT => 10, #接続タイムアウト秒(デフォルトは60)
  USESSL => 'true' #SSLを使わない場合は0(Gmailは使う)
 );


if($pop->Count < 0){ #接続に失敗すると-1が返るらしい
 $log .= "POPサーバに接続できませんでした";
}
else{
 $log .= "ID[$id]のエラーメールアドレスを調査中・・・\n";
  if($pop->Count != 0){
   my $cnt = $pop->Count;
   my @err = ();
   my $suc = 0;
   my %diag = (); ### エラーの原因格納用ハッシュ(任意)
   my @next_ck = ();
   $log .= "  $cnt件のエラーメールアドレスを処理中・・・\n";
   for(my $i=1; $i<=$cnt; $i++){
    my $pars_ok = 0; #### パース成功フラグ
    foreach($pop->Body($i)){
     ###本文(SMTPサーバが返すメッセージ)からエラーになった宛先をパース
     if(
      $_ =~ /^To:.*?\?iso-2022-jp\?B\?.+?\?=.*?<([\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+)>/i ||
      $_ =~ /^Delivered-To:.*?([\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+)/i ||
      $_ =~ /^X-Yahoo-Forwarded:.*?from.*?([\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+).*?to/i
     ){
      $pars_ok = 1;
      push(@err,$1);
      $suc++;
      $pop->Delete($i);
      ####### Diagnosis エラーの原因チェック
      if($_ =~ /5\.4\.4|Host.*?not found/i){
       $diag{'Host_not_exists'}++; #ホストまたはドメインが存在しない
      }
      elsif($_ =~ /550|553|554|5\.0\.0|5\.1\.1|5\.7\.1/){
       $diag{'Account_not_exists'}++; #受信先又は転送先のアカウントが存在しない
      }
      elsif($_ =~ /421|450|4\.2\.1|User disk quota/i){
       $diag{'Mailbox_unavailable'}++; #受信先又は転送先のメールボックスが一時的に利用不可
      }
      elsif($_ =~ /451|452/){
       $diag{'Server_error'}++; #配信時サーバエラー
      }
      elsif($_ =~ /432|454|534|535|538/){
       $diag{'Authen_error'}++; #認証エラー
      }
      else{
       $diag{'Other'}++; #その他
      }
      last;
     }
    }#foreach
    ###### パースできなかったエラーメールは次のチェックへ
    push(@next_ck,$i) if !$pars_ok;
   }#for
   if(@next_ck != 0){
    for(my $i=0; $i<@next_ck; $i++){
     ####### 今度はヘッダをチェック
     foreach($pop->Head($next_ck[$i])){
      if(
       ###### 自動返信元をパース
       $_ =~ /^From:.*?([\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+)/i ||
       $_ =~ /^From:.*?\?iso-2022-jp\?B\?.+?\?=.*?<([\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+)>/i
      ){
       ### パースされたアドレスがデータベースにあるかチェック
       &db::query("SELECT email FROM usertable WHERE email='$1'");
       my $exists = $db::sth->fetchrow_array();
       if($exists){
        ### あれば削除対象に
        push(@err,$1);
       }
       $suc++;
       ##### メール削除フラグ
       $pop->Delete($next_ck[$i]);
       $diag{'Auto_return'}++; #自動返信が設定されている
       last;
      }
     }#foreach
    }#for
   }
   if(@err){
    ####エラーアドレスをDBから削除する処理など
    foreach(@err){
     &db::query("DELETE FROM usertable WHERE email='$_'");
    }
    $log .= "$suc件のエラーメールアドレスをデータベースから削除しました\n";
   }
   ###パースに失敗することもあるでしょう。
   if(($cnt- $suc) > 0){
    $log .= "※".($cnt- $suc)."件のエラーメールアドレスを削除できませんでした\n";
   }
 }
 else{
  $log .= "エラーメールアドレスはありませんでした\n";
 }
}

#接続終了(このときメールがサーバから削除される)
$pop->Close;

print $log;

------------------------------------------------------------------------




あー疲れた。




このアーカイブについて

このページには、2010年4月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2010年3月です。

次のアーカイブは2010年6月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

Powered by Movable Type 4.22-ja