PerlのPOP3Client を使ったスパムメール対策(旧)
その気になったら、Vector の方にでも真面目にページを書きます。
→ Vector にページを作りました。
http://hp.vector.co.jp/authors/VA014481/return-path-checker/index.html
以下の内容は古いものです。
2006年5月7日 15:00 時点のもの。
目的:POP3 over SSL 通信で、プロバイダのメールボックスにあるスパムメールを除去する。
- ローカルのディスクにメールをダウンロードする前に、プロバイダ側にあるうちに片付けたい。
- ローカルに取り込んだメールは sssendmail のデータバックアップとして保管しているが、スパムメールのためにこのスペースを確保するのはもったいないし、煩わしい。
- スパムメールでも、ディスク書き込みのための時間を必要とする。
- ダウンロードした後のメールについては、procmail, annoyance-filter を使用して振り分け、判定を行っている。
スパムメール判定のためのパターン
幸い、無条件で(読まずに)消していいスパムメール判定のためのパターンをいくつか特定することができた。
- Return-Path: だけで判定できるもの
- info@.*.com
- 内容との組合せ
- .biz からくるもので、画像が添付されているもの
- .*@ocn.ne.jp からくるもので、特定のサイトの URL が書かれていもの
効果:プロバイダメールボックスに着信するメールの 2割程度は、読まずに除去できる。
- ローカルに取り込む時間の節約になる
- HDD 領域の節約になる。
- スパムメールの 2割 ではない。全体の2割。スパムメールに占める割合はもっと大きくなる。
使う物:Perl, Mail::POP3Client
使った物:
- Perl で書かれた pop3browser から、設定ファイルの読み込み部分をもらった。
- Mail::POP3Client について日本語で解説したサイト。
Googleで探してみると、いくつかみつかります。助かりました。
ライセンス
GPL とするので、好きにしてください。
設定ファイル
- 名前 $HOME/.return-path-readerrc
- 書式
サーバ名 ユーザ名 パスワード
ソースコード
システムの制限で表示されない部分が一部あるので、
添付もしておきます。
#!/usr/bin/perl -w
# POP3 folder cleaner over SSL
use strict;
#read config data
# this part is almost copy from pop3browser.
my $nhosts;
my @host;
my $i;
my $mode;
if (-e "$ENV{\"HOME\"}/.return-path-readerrc")
{
($mode)=(stat("$ENV{\"HOME\"}/.return-path-readerrc"))[2];
if ($mode != 0100600)
{
print "The configuration file was readable for other users than the file owner.\n";
print "Correcting it...\n";
#this file should only be read by the owner
chmod(0600,"$ENV{\"HOME\"}/.return-path-readerrc")
or die "FATAL: could't chmod the configfile. Do you own it?";
}
open(CONFIG,"$ENV{\"HOME\"}/.return-path-readerrc")
or die "FATAL: could't open the configfile. Do you own it?";
$i=0;
while ()
{
chomp();
s/^\s+//;
next if /^\#/;
next if /^$/;
($host[$i]{"host"},$host[$i]{"uid"},$host[$i]{"passwd"},$host[$i]{"protocol"})=split(/\s+/, $_, 4);
$i+=1;
}
$nhosts=$i;
close(CONFIG);
if ($nhosts==0)
{
print "No host definitions found in configuration file!\n";
exit 0;
}
}
else
{
print "No config file found!\n";
print "return-path-reader needs the file .return-path-readerrc in your home directory to work.\n";
print ".return-path-readerrc contains the definitions for your pop3 accounts.\n";
print "One definition per line and in the following form:\n";
print "hostname userid password\n";
print "The entries in one line may be separated by spaces or tabs,\n";
print "lines starting with \# are ignored.\n";
exit 0;
}
# POP3 server へ接続し Return-Path の一覧を読みとる
my $pop3_hostname = $host[0]{"host"};
my $pop3_user = $host[0]{"uid"};
my $pop3_password = $host[0]{"passwd"};
#POP3Client Object を生成
use Mail::POP3Client;
my $pop = Mail::POP3Client->new(
HOST => $pop3_hostname,
USER => $pop3_user,
PASSWORD => $pop3_password,
USESSL => "true",
# AUTH_MODE => 'PASS',
);
# メールボックス全てのメールを処理する
my $count = $pop->Count;
print "mail count $count \n";
my @returnpath;
my @subject;
my @nullarray = ();
my ($dummy, $retpath);
my $found_infocom = 0;
my $found_apacheinfo = 0;
my @attached_image_line;
my $found_attachedimage = 0;
my @body_line;
my $found_deai_site = 0;
my $found_messagescr = 0;
foreach my $msg (1..$pop->Count) {
# mail headerから "Return-Path:" の文字列で始まる要素を抽出、表示
@returnpath = grep { /^Return-Path: / } $pop->Head($msg);
if ( @returnpath != @nullarray ) {
# print "$msg $returnpath[0]";
# .*@.*.biz with image attached
if ( $retpath =~ /\<.*\.biz\>/i ) {
# print "end with .biz\n";
@attached_image_line = grep {/Content-Type: image\//} $pop->Body($msg);
if ( @attached_image_line != @nullarray ) {
print "end with .biz, with image attached.\n";
$found_attachedimage++;
# print "@attached_image_line\n";
# mark a message to delete .
$pop->Delete($msg);
next;
}
}
# .*@.*.com with image attached
if ( $retpath =~ /\<.*\.com\>/i ) {
@attached_image_line = grep {/^\tname="top\.jpg"/} $pop->Body($msg);
if ( @attached_image_line != @nullarray ) {
print "end with .com, with top.jpg attached.\n";
$found_attachedimage++;
# mark a message to delete .
$pop->Delete($msg);
next;
}
}
# apache@*.info
if ( $retpath =~ /\/i ) {
print "apache@*.info!!\n";
$found_apacheinfo++;
# mark a message to delete .
$pop->Delete($msg);
next;
}
# info@.*.com
if ( $retpath =~ /\/i ) {
print "infocom!!\n";
$found_infocom++;
# mark a message to delete .
$pop->Delete($msg);
next;
}
# .*@.*.ocn.ne.jp inclues http://www.meguriai-max.net/
if ( $retpath =~ /\<.*\@ocn.ne.jp\>/i ) {
@body_line = grep {/http:\/\/www\.(meguriai-max|gyakuten6)\.net\//} $pop->Body($msg);
if ( @body_line != @nullarray ) {
$found_deai_site++;
# print "@body_line\n";
# mark a message to delete .
$pop->Delete($msg);
next;
}
}
}
# Subject: Mail Delivery (failure hma@syd.odn.ne.jp) with message.scr attached
@subject = grep { /^Subject: Mail Delivery / } $pop->Head($msg);
if ( @subject != @nullarray ) {
@body_line = grep {/^\tname="message.scr"/} $pop->Body($msg);
if ( @body_line != @nullarray ) {
$found_messagescr++;
# mark a message to delete .
$pop->Delete($msg);
next;
}
}
}
# pop server から切断
$pop->Close( );
print "infocom: $found_infocom / $count, ";
print "attachedimage: $found_attachedimage / $count, ";
print "deai-site: $found_deai_site / $count, ";
print "apacheinfo: $found_apacheinfo / $count, ";
print "messagescr: $found_messagescr / $count\n ";
exit;

[hama]
著者: hama
作成日: 2006年07月26日16時29分30秒
return-path-reader.pl