SPAMBlock非公式マニュアル

移転しました

独自ドメインサイトへ移行しました。5秒後に

https://straypenguin.winfield-net.com/

へジャンプします。

このマニュアルは ASAHIネットからいかなる承認も公認も監修も受けたものではありません。独自の試験による分析なので、間違っているところもあるかも知れません。ただ、スパムブロックをできるだけ多くの人に賢く使ってもらいたい、願わくば、 SPAM が滅多に我々の目に触れなくなり、世の中にはびこる SPAM を実質的に無力化できれば、との思いからまとめたものです。

これはアサヒネットの迷惑メールフィルタリングシステム「スパムブロック」を利用する上でのやや上級者向け解説。オフィシャルページにも一通り説明はあるが、緻密に設定しようとするとあやふやな部分があるので、そこらへんを実験しながらまとめてみた。ちなみに、 IT 系 WEB ニュースによると、このシステムは DEEPSoft の SPAMBlock を asahi-net が独自に拡張したものらしい。

スパムブロックには一種の「育てゲー」的楽しさがあり、設定を煮詰めていくほどに、あれほど鬱陶しかった SPAM が「ほーら新しいパターンのヤツが来たね。どんなフィルタでブロックしてやろうかなぁ~ひひひひひ」という快感に変わってくる。この道具には、メーラーで受信してしまった SPAM を毎日毎日空しくゴミ箱へ捨てるという苦行を、設定作業の面白さへと昇華させる魅力がある。ちょっと大袈裟な表現かも知れないが、筆者の場合、実際にかなり気分が楽になった。最近では 98% ほどの確率で SPAM をブロックできている。設定しているフィルタは 40 から 50 個 (例外処理を除く) 前後だ。期間によってよく来る SPAM の傾向にばらつきがあるため、1 ~2 週間を目処にフィルタの最適化を行い、フィルタ数が 50 個を超えないように努めている。

このページでは、正規表現についても少々触れる。正規表現とは、特定の文字の並びを、*[]^$|() などの特殊記号を使ったで表そうというもので、一定範囲の揺らぎを吸収しながら曖昧な文字列比較ができる仕組み。後で簡単に説明するが、もっと詳しく知りたい人は Perl のページを見ていただくとよい(ただし SpamBlockで使える正規表現は Perl 完全互換ではないが)。また、補足説明に Perl の式を使っている部分があるが、そこは無視して頂いても肝心のコツは読み取れると思う (SPAMBlock が Perl で書かれているというわけではなく、比較的一般的な言語だから説明に使っているだけ)。

なお、設定例を示す場合には、逆に SPAM 発信者を利するとシャクに障るので、やや非現実的かつ不十分なものに留めることにする。例に用いているドメインや IP アドレスはその場の思いつきによる全く架空のもので、そのまま書き写しで設定しても何の効果もない。

Table of Contents

スパムブロックの動作概念

スパムブロックが単体のアプライアンスなのかメールサーバ上で走るソフトウェアなのかは知らないが、動作的には一種のメールプロクシとして働き、なおかつ独立したSMTPサーバのように機能している様子。もちろん、筆者は単なる一ユーザにすぎないので、これが的を射ているかどうかは分からない。あくまでも、実験と届いたメールの分析による推測だ。

なお、図中で用いている用語については以降で説明している。

おまかせフィルタは切るべし

マイフィルタを緻密に組み立てるにはお仕着せの「おまかせフィルタ」は邪魔になるので無効にする。「おまかせ」を切らなくても、好き好んで通販や色っぽい情報のメールマガジンでも購読していない限りは、ブロックしてほしくないメールがブロックされてしまうことは滅多にないが、どんな語句が盛り込まれているのか分からないので気持ち悪いし、オリジナルフィルタの検証を行いたい時に影響を及ぼすので、なるべく切ったほうがいい。

後日談:

しばらくカスタムメイドのフィルタのメンテナンスをさぼっていたら SPAM が増えてしまったので、マイフィルタを有効にしたまま「おまかせフィルタ」のほうもオンにしてみた。すると、設定した覚えのない正規表現フィルタにSPAMが引っかかっている。どうやら、おまかせフィルタも手動でASAHI-NETスタッフがコツコツとメンテしている正規表現フィルタ群であるらしい。

SPAMBlockという製品は管理者の設定によってベイジアンフィルタも有効にできるらしいのだが、ASAHI-NETに問い合わせてみたところ、おまかせフィルタでもベイジアンは有効にしていないとのこと。よって、「おまかせ」を有効にしたからといって劇的にブロック率が上がるわけではない。

マイフィルタの設定

設定のポイント

カスタマイズ可能なフィルタ「マイフィルタ」には、大別すると許可フィルタと拒否フィルタがある。マイフィルタを組み立てていくにあたっては、以下のポイントを頭に置いておこう:

スパムブロックの設定画面ではフィルタの順序が変えられないので、フィルタが増えてくると混乱してくる。エクセル表やテキストファイルなどでフィルタ管理リストを作っておいたほうが、無駄なく、効果的なフィルタが作っていける。フィルタを作成や変更したら、自分宛にメールを送信して効果を確かめたいだろうが、その際には、設定してから数分待ってから送信したほうがいい。反映されるまでに少々タイムラグがあるからだ。経験的には 3 ~ 5 分ほど。気のせいか、スパムブロック設定ページから一旦ログアウトしたほうが幾分確実なような気がする。

ここから先の章立ては悩みの種。先に スパムブロックと正規表現 の章を読んで頂いたほうがいいかも知れない。

どのフィルタに引っ掛かったかを知る

スパムブロックの「スパムリスト」画面で、捕まったメールのタイトルにカーソルを持っていき、コンマ数秒間じっとしていると、ヒットした条件がポップアップ表示される。筆者はこの機能に 2 ヶ月くらい気づかなかった。自分で作ったフィルタのヒット頻度を知っておくのは、フィルタを作る上で最も重要なことだ。時々チェックして、マイフィルタを研ぎ澄ましていこう。

エクセルでフィルタ毎のカウント数を管理する時、ヒットした日付やカウント数をいちいち入力するのが面倒臭くなり、管理用のエクセル表を作った。こちらからダウンロードしていただきたい。

「メール本文」フィルタ -- ブロックの立役者

以降の例で使っている語彙 "AND" は「なお且つ」、 "OR" は「または」を意味する。

「メールの件名、本文、ヘッダで拒否する」設定ページにある「メール本文」フィルタ。本文つまりメールボディは、通常最も文字数が多く、迷惑メール判定には一番利用価値の高い部分だ。中には a を @ と書いたり O (オー) を 0 (ゼロ)、 g を q と書いたりしてフィルタリングを擦り抜けようとする姑息な SPAM もあるが、何が書いてあるのか理解できないほどになっては広告の意味がないわけで、フィルタリングの手段は必ず残る。送信者のメールアドレスやそのドメイン (@以降) 部分による判定がピンポイント的であるのに対して、本文による判定は広い網を張ることができ、ひいてはフィルタの数を減らすことにつながる。

スパムブロックの文字列検索は行単位

まず最初に意識しておかなければならないのは、スパムブロックの文字列検索処理は行単位で行われるということだ。或るルールに

登録.*無料

という正規表現を指定したとすると、「登録」と「無料」が 1 行の中に両方あればヒットするが、「登録」と「無料」の間のどこかで (明示的な) 改行がされているとヒットしない。「設定方法」が「一般テキスト」の時の "登録*無料" においても同じことが言える。
※ 本文以外のヘッダも行単位に分解されるのかどうかは未解明。

例:ワイルドカードと改行の関係

拒否フィルタ
主条件 = 本文 <正規表現> "女の子.*紹介"

実験結果
ケース1:「女の子を紹介します。」 => 拒否("女の子"と"紹介"が同一行内にあるのでヒット)
ケース2:「女の子です。<改行>
紹介します。」 => 許可(改行されて別の行にあるのでヒットせず)
ケース3:「紹介します女の子。」 => 許可("女の子"と"紹介"の出現順が指定と違うためヒットせず)

「キーワードを全部含む時だけブロック」するルールを作るには

~行単位」で紹介したワイルドカード式のやり方では、例で見たとおり文字列の出現順に左右されてしまうので、効果を考えると、例えば「女の子.*紹介」というフィルタと、前後を入れ替えた「紹介.*女の子」というフィルタを作らなければならなくなる。その点をクリアするには、 1 個の拒否フィルタの中で、ひとつの言葉をキーワードにした主条件と、やはり 1 語を「含まない」で条件にした例外処理を複数組み合わせる。拒否フィルタと例外処理との関係をまとめておこう:

例:「文字列1 AND (文字列2 AND 文字列3 [AND 文字列N..]) をブロック」するルール

拒否フィルタ
主条件 = 本文 <含む> "女の子"
例外処理1= <含まない> "紹介"
例外処理2= <含まない> "ftp:"

実験結果
ケース1:「女の子を紹介します。」=> 許可(例外処理2 に合致)
ケース2:「紹介します女の子。」 => 許可(同上。出現順は影響を与えない)
ケース3:「女の子です。<改行>
紹介します。」 => 許可(同上。改行は影響を与えない)
ケース4:「女の子ならftp://aa.cxm」 => 許可(例外処理1 に合致)
ケース5:「女の子です。<改行>
紹介します。<改行>
こちら ftp://aa.cxm」 => 拒否(主条件にのみヒット)
ケース6:「女の子です。」 => 許可(例外処理1,2 の両方に合致)

「主文字列と、副文字列1か副文字列2があったらブロック」するルールを作るには

「写真」という言葉は必ずあって、その他に「エロ」または「限定」があったら拒否したい、というようなケースはよくある。こういったルールを作るには、主条件に「"写真"を含む」を持った拒否フィルタをふたつ作り、一方のフィルタには「"エロ"を含まない」という例外処理を付加、もう一方には「"限定"を含まない」という例外フィルタを付ける。

しかし現行のスパムブロックでは、裏技的なやり方をしないと、これが実現できない。全く同一のキーワード文字列を持った拒否フィルタを幾つも作ることができないのだ。そこで、正規表現でバリエーションを作ることによって逃げる。例えば「写真」という言葉は、一般テキストでは "写真" でしか表せない。しかし正規表現なら、 写真, (写真), 写真{1} などといった具合に、幾つかので表すことができる。 SPAM で使われる可能性がなきにしもあらずの無駄な同義文字を足して組み合わせを増やす方法もある。例えば [女娘嬢姫] の正規表現バリエーションなんてものが考えられるし、英文字なら、無駄と知りつつ [Aa](A|a) といったように敢えて大文字と小文字を書いて表現方法を増やす手もある。

例:「文字列 AND (文字列1 OR 文字列2 [OR 文字列N..])をブロックする」ルール

拒否フィルタ1
主条件 = 本文 <正規表現> "[女娘]"
例外処理= <含まない> "紹介"

拒否フィルタ2
主条件 = 本文 <正規表現> "[娘女]"
例外処理= <含まない> "ftp:"

実験結果
ケース1:「女の子を紹介します。」=> 拒否(拒否フィルタ1 にヒット)
ケース2:「紹介します女の子。」 => 拒否(同上。出現順は関係ない)
ケース3:「女の子です。<改行>
紹介します。」 => 拒否(同上。改行を挟んでもいても問題ない)
ケース4:「女の子ならftp://aa.cxm」 => 拒否(拒否フィルタ2 にヒット)
ケース5:「女の子です。<改行>
紹介します。<改行>
こちら ftp://aa.cxm」 => 拒否(拒否フィルタ1,2 の両方にヒット)
ケース6:「女の子です。」 => 許可(両拒否フィルタの例外処理に合致)

「メールヘッダ」フィルタ -- 特定SPAMを狙い打ち

「メールの件名、本文、ヘッダで拒否する」設定ページにある「メールヘッダ」フィルタ。本文フィルタに次いで効果の高いフィルタだ。本文に比べればヒットするメールは限定されるが、特定のヘッダに固定的な特徴のある SPAM なら、かえって確実に捕獲できる。

ヘッダに関する文書

ヘッダフィルタを的確に設定するには各ヘッダの役割や規則性を知っておくと格段に効果が上がる。参考になるリンクを紹介しておこう。

いろいろなヘッダについてよく咀嚼して端的に解説したページ:

対SPAM情報に特化したサイト。調査ツールも豊富:

Eメールの規格を本格的に理解したい人は下記 RFC を読むべし:

信頼できるヘッダと当てにならないヘッダ

スパムブロックに利用する上での、主なヘッダの利用価値、利用法などをまとめてみた。ヘッダがどうやって作られるかを含めた詳細な考察は Receivedヘッダの読み方 で行っている。

ヘッダ 利用価値 傾向と利用法
From うわべの送信者。送信側でどうにでもなるが、特定のSPAM業者に定型や傾向があるなら積極的に使うべき
To うわべの宛先。自分に決まっているのだが、特定の呼称を使うSPAMに対しては使える
Subject 件名。特定の定型や傾向に対してはブロック項目と成り得るが、本文に比べて短いためヒット率が低い
Date メーラーや極悪MTA(メールサーバ)の設定次第でどうにでもなる。利用法が思いつかない
Return-Path レギュレーション上は、mail from コマンドで指定されたメールアドレスを、最終のMTAがこのヘッダへコピーすることになっている。手元のメーラーで振り分けする場合にはFromと同程度の有効性。しかし、ことスパムブロックに関しては、スキャンの段階ではまだ存在しないはずのヘッダなので、このターゲットの有効性はほぼゼロ。やるならX-FROM-EMAIL, X-FROM-DOMAINを狙えば実質的にこれと同じ部分がスキャンできる。「指定したヘッダが存在しない場合の挙動」も参照のこと
Received SPAMの送信に使われたMTAの、ドメイン、IP、id、サーバソフトウェア名、交信記録の記述の特徴など、さまざまな観点でふるいに掛けることができる。Fromなどメーラーで簡単に捏造できるものとは異なり、このヘッダでウソをつくにはMTAの設定について或る程度の技術が必要だという点も見逃せない。このヘッダは後で詳述する
X-Mailer メールを書くのに使ったメーラー。いかようにも捏造可能だし、 SPAMはこのヘッダを削除していることも多い。しかし、一握りだが、WelcomeMail, Easy DM Free などの同報メーラーを捕獲することができる
Message-ID メールを一意に識別するための文字列。RFCでは送り手のメーラーが付けることになっているが、欠如している場合には補う仕組みになっているMTAも少なくない。記述形式については、レギュレーション上の規則は緩いが慣例はある。それを無視した最低低俗なSPAM業者に対しては効き目あり (ヒント:「...を含まない」)。「指定したヘッダが存在しない場合の挙動」も参照のこと
X-FROM-EMAIL スパムブロックが検索前に付加する特別なヘッダ。mail from コマンドのメールアドレス、つまりエンベロープFromを反映する。「送信者のメールアドレスで拒否/許可」はここを見ている。偽装は簡単だがFromと同程度には利用価値あり
X-FROM-DOMAIN スパムブロックが検索前に付加する特別なヘッダ。mail from コマンドのメールアドレスつまりエンベロープFromのうち、ドメイン部 (@より後ろ) だけを抜き出したもの。@自体は含まない。「送信者のメールアドレスで拒否/許可」の中の「Domain/Email」はここを見ている
X-IP これもスパムブロックが付加する特殊ヘッダ。asahi-net 直前のMTAの実際のIPアドレスが入る。「IPアドレスで拒否/許可はこのヘッダを調べている

From ヘッダや X-FROM-EMAIL で網を張る際には、敵がサブドメインを差し挟んでくる可能性まで考慮して、正規表現で @(.*\.)*hotmail\.cxm のように設定するのがポイント。これなら info@hotmail.cxm はもちろん、 some@mail.hotmail.cxm や hoge@b1.hotmail.cxm などといった亜種もカバーできる。その際、手抜きをして @.*hotmail\.cxm としてしまうと、hoge@hithotmail.cxm や hoge@shotmail.cxm などもブロックしてしまうので注意 (敢えてそうするなら別だが)。 X-FROM-DOMAIN についても、 @ を含めないだけで、要領は同じだ。

ただし、 From ヘッダや X-FROM-EMAIL, X-FROM-DOAIN に載るメールアドレスやドメインは、あくまでも送信者や中継 MTA が名乗ったものに過ぎない。偽称も計算に入れた上でフィルタリングするのもひとつの有効な手段だが、もし本当のドメインで正確にブロックしたいならそれは無理なので、IPアドレスの範囲を割り出して X-IP ヘッダでふるいに掛けるか「IPアドレスで拒否」フィルタを使おう。

ASAHIネットに到達する以前のメールサーバに特定のホスト文字列や IP 、受付 ID などが見受けられる場合には、 Received ヘッダが効果を発揮する。スパムブロックは、自分の書くべき Received ヘッダをちゃんと書き加えてからスパム判定をしているので、直前の MTA の本当の IP アドレスReceived ヘッダから検出することも可能だ。ただし、IP アドレスでフィルタリングするなら、まさにその用途のためにある X-IP ヘッダを狙ったほうが確実。 IP やドメインを正規表現でセットする際には 61\.61\.61\.1[0-5][0-5] のようにドットをエスケープするのを忘れずに。また Received ヘッダ検索では、直前だけでなく、それ以前の Received 記録も対象となるので、例えば大元の SPAM 発信者と悪玉送信メールサーバとの交信記録に特徴が見られれば、それを検索対象にする手もある。

この他に、スパムブロック特有のものとして X-SPAM-MARK ヘッダがある。これは、スパムブロックの「処理」を「印付配送」にした場合に、スパムだと判定されたメールにスパムブロック自体が付加するヘッダだ。実際に試してみたところ、"by Spam Filter Rule" という内容を持った X-SPAM-MARK ヘッダが付加されて送られてきた。とりあえず受け取ってから自分のメーラー側で振り分けする際に利用できる。

指定したヘッダが存在しない場合の挙動に注意

スパムブロックシステムは、 ASAHIネット本来のメールサーバに到着する寸前の状態でメールを検査する。メールヘッダの中には、本来の ASAHIネットメールサーバがメールを受け取って初めて付加されるヘッダもあり、それらはスパムブロックの目に触れない。そういうケースの起こり得るヘッダとしては Message-ID, Return-Path が挙げられる。

ひょんなことで判明したのだが、スパムブロックは、存在しないヘッダを無視しない。分かりにくいので例を示そう:
Message-ID ヘッダ」に「mail」というフレーズを「含まない」なら「拒否せよ」というフィルタを作ってあるとする。
ここに Message-ID ヘッダ自体をはなから持たないメールが入ってくる。 Message-ID ヘッダは本来は送信者のメーラーが付けることになっているが、ない場合には後から ASAHIネットの本来のメールサーバが付け加えることになる。しかし、スキャンの段階ではまだ存在しない。すると、 Message-ID の内容は "" つまり空白と判断されるため、上記の条件にヒットしてしまうのだ。これに注意しないと、思わぬメールが誤検出されてブロックされることがある。

Receivedヘッダの読み方

Received ヘッダは MTA (Message Transfer Agent = メールサーバソフトウェア) の交信記録だ。メールには、 MTA をひとつ経る毎に、Received ヘッダがヘッダ域の下方から上方へと、受け側MTAによって書き加えられていく。つまり、Received ヘッダ群を下から上へと辿って読んでいけば、そのメールが自分のメールボックスに入るまでにどんな MTA を通ってきたかが分かる。

Received ヘッダのフォーマットはメールサーバソフトによって多少異なるが、概ね下記のような格好をしている:

Received: from 渡し側が名乗った名前 (DNSで牽いて判明した名前 [渡し側IP])
	by 受け側MTA名 (MTAソフトウェア名) with プロトコル id 受け側MTAが生成した乱数
	for <メールの宛先>; ,    HH:MM:SS タイムゾーン
各セクションの説明  
渡し側が名乗った名前: 「受け側MTA」にメールを受け渡したメールサーバまたはメーラーが、HELO コマンド (下記参照) で名乗った名前。メーラーはもちろん、MTAでもちょっとした設定によってどうにでも名乗れる。
DNSで牽いて判明した名前: 下記の「渡し側IP」を元に「受け側MTA」がDNS検索して分かったインターネットホスト名。DHCPで割り当てられた一時的なアドレスだった場合や、わざとDNSに載せていないホストの場合は、ここがunknownだったりIPのままだったりする。真面目に検索するMTAばかりとも限らない。
渡し側IP: 渡し側のIPアドレス。渡し側と受け側MTAはネットワーク上で実際に通信を行うので、ここだけは真実であることが多い。少なくとも、自分のプロバイダのMTAが記したReceivedヘッダに見られるこの部分は間違いなく本物だ。フィルタへの適用上の留意点は「IPアドレスで拒否」フィルタを参照のこと
受け側MTA名: メールを受け取ったMTAのホスト名。設定次第の自己申告。
MTAソフトウェア名: メールを受け取ったMTAのソフトウェアやバージョン。一般的なMTAとしては sendmail, Postfix, qmail などがある。このセクションを記さないMTAもあるし、詐称する仕組みを持ったMTAも存在しそう。スパムブロックが記したReceivedヘッダは、ここが "SpamBlock何とか" となっている。その "SpamBlock何とか" となっているReceivedヘッダこそ、我々が敵のMTAのホスト名やIPを読み取るために最も着目すべき配送記録だ。
プロトコル: 通常はSMTPだが、"会話" を暗号化したりSMTP認証を使う際には拡張版のESMTPが利用される。WEBメールシステムの中には、WebDAVプロトコルを利用しているものもある。
受け側MTAが生成した乱数: 交信を一意に識別するために受け側MTAがその都度生成するランダムな文字列。
メールの宛先: 普段我々が指定する、そのメールの宛先、つまり目的の最終お届け先。
曜...HH:MM:SS: この "会話" が行われた日時。
タイムゾーン: 上記の「日時」がどのタイムゾーンで表されたものかを示す。例えば日本国内にあるサーバで、まともに設定されているなら +0900 (JST)。 GMTやUTCで記すMTAもある。
SMTPセッションとReceivedヘッダの関係

上で "Received ヘッダは通信記録だ" と書いたが、そもそも SMTP でどういった手続きが行われるのかを知っておくと Received ヘッダは理解しやすい。さっきから "会話" に喩えてきたが、サーバ構築の世界ではそれを、「一連の遣り取り一式 1 回分」の意味から、セッション (Session) という語彙で表す。そろそろ喩えに疲れてきたので、ここからはセッションという言葉を使わせていただく。 SMTP は非常に単純なプロトコルで、英数字だけの単純なメールなら、ターミナルソフト (TeraTerm やハイパーターミナルなど) でも送ることができる。グラフィカルインターフェースのメーラーも、実は裏でこういう交信を行っているのだ。では、具体的な通信例から SMTP セッションと Received ヘッダとの関係を観察してみよう。

SMTPセッション

太字はターミナルで打ったコマンド、細字はサーバからの回答を示す。このセッションは、
SPAM 送信者または悪玉MTA (IP:222.222.222.222, DNSホスト名:sv1.spammer.cxm) が、
メールをアドレス victim@victim.cxm へ送ろうとして、
良心的な受け側MTA (IP:123.123.123.123, ホスト名:mail.server.cxm, サーバソフト:Postfix) と交わしたセッションだと仮定しよう。

> telnet 123.123.123.123 25
Escape character is '^]'
220 mail.server.cxm ESMTP
helo virtual.cxm
250 mail.server.cxm
mail from: evilsender@evil.cxm
250 ok
rcpt to: victim@victim.cxm
250 ok
data
354 go ahead
From: Sales Department <sales@hotmail.cxm>
To: Customer <victim@victim.cxm>
Subject: SPAM test
Message-ID: 123456789012@evil.cxm
X-IP: 111.111.111.111
 
This is a test.
.
250 ok
quit
221 mail.server.cxm
Connection closed by foreign host.
>

受け側MTAが記録するであろうReceivedヘッダ

Received: from virtual.cxm (sv1.spammer.cxm [222.222.222.222])
	by mail.server.cxm (Postfix) with SMTP id 00987654321AX
	for <victim@victim.cxm>; Thu, 24 Nov 2005 14:31:59 +0900 (JST)

ここから分かることは、 SMTP というプロトコルが極めて性善説で成り立っているということ。 SMTP セッションは、 data コマンドの前と後で、大きくふたつの部分に分かれる。 data より前の遣り取りは、手紙で言えば封筒 (Envelope エンベロープ) に当たり、 data 以降は便箋 (Content = 内容) に当たる。現実世界で便箋に書く文面が誰にも拘束されないのと同じで、 data 以降は良識と常識を取っ払ってしまえば全く自由なのだ。例えば From と To は 2 種類あることに気づいたはずだ。封筒の外側に書くエンベロープFrom (mail from: コマンド) と便箋上のコンテントFrom、そして同様に、エンベロープTo (rcpt to: コマンド) と「コンテントTo」だ。 コンテント内のものが、エンベロープに書いたものと食い違っていようがウソ八百だろうが、 SMTP プロトコルはお構いなし。普段我々が目にする From と To は、後者のコンテントFrom/To のほうだ。また、題名 (Subject) やメッセージID といったヘッダも内容の一部なのでどうとでも書くことができる。上記のセッション例では X-IP ヘッダにさえ見当違いの IP をわざと書いている。

mail from コマンドのメールアドレス (ここでの evilsender@evil.cxm) は Received ヘッダには反映されない。このメールアドレスは次の MTA でも mail from コマンドとして繰り返され、 (レギュレーション上は) 最終の MTA が Return-Path ヘッダへコピーする。しかし、スパムブロックを採用する ASAHIネットでは、もう少し複雑 -- まずスパムブロックが mail fromX-FROM-EMAIL ヘッダへコピー、さらにそのドメイン部だけを X-FROM-DOMAIN にコピー。スパム検索を行った後、おとがめ無しならそのメールはスパムブロックから ASAHIネット本来のメールサーバへ転送され、そこで初めて Return-Path ヘッダへとコピーされる。

整理しておこう。スパムブロックにおいては X-FROM-EMAIL, X-FROM-DOMAIN, Return-Path はいずれも SMTPコマンドの mail from を参照する。ただし X-FROM-DOMAIN はドメイン部のみ。 Return-Path ヘッダはスパム検索時にはまだ存在しないのでフィルタには使わないほうがいい。

SMTP と ESMTP についてちょっと触れておこう。上のセッションの最初のところで、受け側のサーバが「コード220、こちらmail.server.cxm。ESMTPが使えるよ」と言っている。その後、送り側が helo の挨拶で始めれば以降の遣り取りは SMTP プロトコルで行われ、 ehlo で始めれば ESMTP プロトコルで行われる。この例では helo で口火を切っているので SMTP だ。

「IPアドレスで拒否」フィルタ

このフィルタは ASAHIネットのメールサーバに到達するひとつ前のメールサーバの IP アドレスを検索対象にしている。ほとんどの場合、それは SPAM 発信者が使った送信メールサーバだ。そのサーバは ASAHIネットのメールサーバと直接に SMTP セッションを交わすしかなく、ヘッダにその記録を残すのも信頼できる自分のプロバイダのMTAなので、 IP を偽ることは不可能だ。スパムブロックシステムは、メールを受け取ると、まずこのアドレスを新たな X-IP ヘッダに記入 (元々あればもうひとつ追加) し、それからスキャン作業に入る。つまり、このフィルタにセットすべき IP は、届いた SPAM の X-IP ヘッダか Received ヘッダを見れば分かる。

SPAM を観察していると、 SPAM の発信に同一 IP アドレスの MTA が続けて使われることはほとんどない。きゃつらはどうやら、 xDSL やダイヤルアップでサーバをインターネットにつなぎ、わざと頻繁に接続を切って別のアドレスを取り直すか、世にはびこる設定の甘いメールサーバ ("オープンリレー"と呼ぶ) のリストを持っていてそれらをグルグルと切り替えて使っているようだ。そのため、ひとつの特定 IP アドレスをフィルタにセットしても効果は全く期待できない。

そこで何らかの手段で IP を範囲でカバーしたいのだが、「IPアドレスで拒否」フィルタでは正規表現が使えない。例えば 61.61.61.*61.61.61.6* といった具合にシェル式のワイルドカード "*" は使えるが、かなり大ざっぱな指定になってしまうのが難点だ。 IP 範囲を絞り込んで指定したいと思うなら、前記の「メールヘッダ」フィルタで、 X-IP ヘッダ (または Received ヘッダ) を正規表現で検索させたほうが、多少なりとも正確な範囲指定ができる。

本当にブロックすべき IP アドレスなのかや、どんな範囲のアドレスを規制したらいいのか調べたい時には、先にも挙げた 迷惑メール(spam)撲滅私的調査会(高崎作成) が役に立つ。送信元を確かめる手段やドメインを突き止めるためのツールも紹介されている。特に Geek というツールには筆者もちょくちょくお世話になっている。

ここで重要な注意。 Geek で調べのついたアドレス範囲が大手プロバイダの管轄だった場合には、決してそのネットワーク範囲を丸ごとブロックしてはいけない。おそらく肝心なメールもたくさんブロックされてしまうだろう。 (実際に、なんと ASAHIネット利用者が立てたと思われる MTA から発信されているケースもあった!) そんな時は本文他のヘッダに照準を切り替えよう。自分が受け取る善玉メールに影響のない海外プロバイダだったり聞いたこともないような団体だったら、迷うことなくバッサリとブロックだ。

なお、日本の大手プロバイダ管轄の IP だった時には、筆者はなるべく、そのプロバイダに苦情メールを出すことにしている。その際には「御社管轄のIP範囲にあるメールサーバを使用してスパムが発信されています。返答や対処を怠る場合はRBLに登録します。間違いだったらごめんなさい。」などと書き、SPAM のヘッダも含めて全文をペーストして送る。本文だけ送っても無意味だ。苦情メールの宛先は Geek でも調べられるし、そのプロバイダのホームページに書いてあることもある。ただし、特にブラウザもメーラーもマイクロソフトべったりの人は、ブラウザがトロイの木馬に侵されたり、メールアドレスが漏れたりといった危険を伴う可能性もあるので、聞いたこともない団体のホームページにアクセスしたりメールを送ったりするのは控えたほうがいいだろう。持っている IP の個数が 2 個とか 8 個といった小さな団体の場合は、メールをこちらから送っても、逆にこちらのメールアドレスを教えてやるだけのヤブヘビに終わるので、ひたすら無視するのが得策ではなかろうか。

※ RBL: Realtime Block List または Realtime Blackhole List の略。SPAM発信源になっているIPアドレスのリストを管理するデータベース。こうした組織は世界中にいくつもあり、例えば「サーバ管理者のスパム対策」というページで運用状況が紹介されている。MTAでRBL検索を実装すると、RBLに登録されているMTAの差し出すメールは全て着信不能となる。たいていのRBL組織は、SPAM発信源としての登録を解除するためには、運用の改善とそれなりの金額を要求する。RBLに登録されてしまうと、プロバイダは「商品」であるIPの一部が「傷もの」になるわけであり、それなりの痛手を被るはずだ。

戯れ言-- 「対応が悪い!」と真っ赤になって怒る前に --
ここは設定とは全く関係のないタワゴトなので、どうぞそこらへ放っておいて頂きたい。

世の中には「プロバイダに苦情を出したが返事が来ない」とか「(そのユーザを契約解除にするなどの) 処置・対応が遅い」などとカンカンになってイカりまくっている人を見かけるが、私はそういう方達を冷ややかに見ている。彼らはいったい、メールプロトコルやMTAの基礎を理解しているのだろうか、メールサーバを立ててセキュリティに頭をひねった経験はあるのだろうか。SPAM をはびこらせ小手先の「処置」でしか対応できなくしている根元の問題は、25 年も前、インターネットがまだ ARPANet という名で呼ばれていた時代に生まれて未だに使われている SMTP という「太古」のプロトコルにある。数百から数千程度の良識ある学者たちの間だけでメールがやりとりされていたそんな時代には、他人の名を騙ってメールを出すだの、バイアグラを売り込むだの援助交際に誘い込むだの「奈美ちゃんからおっぱいの写真が届いてるから見ろ」だのという現在の狂気は到底予測できなかった。 SMTP とは、そういうお人好しの爺さんプロトコルなのだ。

新しいメール配送プロトコルに一日も早く登場してほしいものだが、今の SMTP に代わる次世代 SMTP の案は、IETF でもまだ影も形もないらしい。仮に全く新しいプロトコルが制定されたとしても、既に世界中に増殖してしまった現行仕様のメールサーバやメールクライアントソフトを全部入れ替えるのに 10 年近くはかかるだろう。その他に、マイクロソフトやシスコシステムズや AOL などが、拡張版の DNS プロトコルと組み合わせたり、現在の SMTP プロトコルを拡張したりして、送信 PC 固有の指紋をメールに埋め込んで身元照会をする仕組みをひねり出したりしているが、どれも本命と言えるまでには至っていない。今はそういう状況であって、新しいプロトコル規格に微塵ほども貢献できるわけではない私などに、規格の欠点を無視して「SPAM送信者を罰せよ」だの「プロバイダよ明日にでも対応しろ」と怒鳴る資格はないし、百歩譲って口を出すのは勝手だとしても、巨木の先っぽの葉っぱ 1 枚の上で道を譲ったの譲らなかったのでつかみ合いをしている蟻ンコのようで、かえって空しさが募る気がする。

見境もなくイカる気になれないのにはもうひとつ理由がある。一言にプロバイダといっても形態は様々だ。大手プロバイダは、たいていインターネットという巨大ネットワークへのソケットを (正確ではないが) 自前で持っていて、我々のようなユーザは、契約というカタチでプロバイダのネットワーク設備へ接続してそこ経由でインターネットへ往き来できるルートを貸してもらっている。仮にこれを 1 次プロバイダと呼ぼう。しかし一方、自分ではソケットを持たず、そうした 1 次プロバイダから 128 個とかの IP をまとめて借りて、それらをさらにお客に貸している 2 次プロバイダというものもある。仮に私がその 2 次プロバイダの善良な 1 ユーザだったとしよう。しかもその 2 次プロバイダは、裏稼業として SPAM 送信の請け負いもやっている。「1 次プロバイダさんよ、その 2 次プロバイダは悪いヤツだから契約解除しろ」と誰かが言って排除したら、「私」達の権利はどうなる?

ケースはもっと複雑に枝分かれしている。一種のプロバイダやその子会社の中には、持っている IP アドレスを切り売りすることをナリワイとしている企業がある。そうした業態は全然特別な存在でなく、ダイヤルアップの時代から、方々の民間企業や団体はそうやって自社サーバをインターネットへ公開してきた (NTT独占の時代は或る固有商標で呼ばれたが今は何と呼ぶか分からない。「IP売りネットワーク業者」と表すことにしよう)。そうした IP 売りネットワーク業者はオプションサービスとしてサーバの構築も請け負うが、「構築はお客さんで勝手にやってネ」というスタンスが基本だ。世の中には間違いなく、SPAM 発信目的で立てたメールサーバが山ほどある。しかしその一方で、設定やセキュリティが不十分だったためとか、ウィルス経由でメール送信用パスワードが横取りされたなどの原因で、意図せず踏み台にされているメールサーバも多い。では、そういう不注意で SPAM の送信サーバを生んでしまった店子は、即刻排除されなければならないだろうか。

あるいは、踏み台に悪用される前の予防措置として、IP 売りネットワーク業者は無償サービスで「インターネットサーバ構築 夏期集中講座」を全ての店子に漏れなく実施しなければならないのか -- 値崩れの甚だしい今日の PC/ネットワーク業界で、そんなサービスをやっていて採算が合うわけがない。

ただ、 Linux の普及によって個人が自分でインターネットサーバを開放することもかなり手軽になったとはいえ、ウィンドウズクライアント感覚でインストールしたまま、ろくに設定も理解せずに公開するのだけは謹んでほしいものである。

残念ながら、自分の受け取った SPAM がどのパターンで生まれたものなのか、部外者である我々が自力で突き止めるのは極めて難しい。バックグラウンドに横たわるストーリーも知らずに担当者を罵倒したり追いつめたりするのは、どうなんだろうという気がするのだ。

「送信者のメールアドレスで拒否」「Domain/Emailで拒否」は要注意

スパムブロックの「送信者のメールアドレス、IPアドレスで拒否 (許可) する」の中の「Domain/Email で拒否 (許可)」は、メールの FROM ヘッダを参照するのではない。実質的には SMTP コマンドの mail from を検査するものだ。我々が普段「この人からだ」と思っているのは FROM ヘッダの情報なので、このふたつのインフォメーションを取り違えていると肩すかしを食う。 SPAM においては双方は食い違っていることが多いからだ。

スパムブロックは、メールを受信すると SMTP コマンドの mail from で渡されたメールアドレスX-FROM-EMAIL という特別なヘッダにコピーする。また、そのドメイン部分だけを X-FROM-DOMAIN にも書き写す。そして「Emailで拒否」フィルタならば X-FROM-EMAIL 内を検索、「Domainで拒否」ならば X-FROM-DOMAIN の検索を行う。しかし、このフィルタの不十分な点は正規表現が使えないことだ。「Domain/Emailで拒否」を使うくらいなら、「メールヘッダ」フィルタで直接 X-FROM-EMAIL ヘッダや X-FROM-DOMAIN ヘッダを指定したほうが、ずっと正確で柔軟性に富んだフィルタリングができる。

スパムブロックと正規表現

フィルタ作成手順

フィルタ一覧画面の下にある新規フィルタ作成フォームには、正規表現を選ぶ項目がない。正規表現で設定するには、以下の手順が必要だ:

  1. 新規作成フォームで、条件をひとまず「含む」か何かにしてフィルタを作成。
  2. フィルタ一覧表で、先ほど作ったフィルタの右端にある「修正」ボタンを押す。「フィルタ修正フォーム」が開く。
  3. 「設定方式」を「一般TEXT」から「正規表現」に変更して「設定」ボタンを押す。拒否条件の「含む」だったところが「----」に変わる。

現状、スパムブロックの設定画面の表示手法に不備があり、上記 3. を行った後に、死んでいるべきはずの拒否条件ドロップダウンメニューが操作できる状態になってしまう。設定方式を正規表現に設定してある場合には、拒否条件「含む」「含まない」などは非設定「----」であるのが正規で、もし仮に「含まない」などにセットしたとしても、動作上は無視される。

スパムブロックで使える正規表現特殊記号

スパムブロックでは基本正規表現だけが使用可能。拡張正規表現や PCRE (Perl互換正規表現) は使えない。もちろん日本語文字は使える。

特殊記号 用法
. 何らかの 1 文字を表す。 s.ck は sick, sack, sock のいずれにもヒットする。 . はスペースやタブにもヒットする
* 直前の文字が、無くてもいいし、あるならいくつあってもいい、の意。si*ck は sick, siick, siiiick, sck などにヒットするが sock, sieck, siieck にはヒットしない
.* 前記ふたつの組み合わせで、どんな文字が何文字でもいいし無くてもいい、というオールマイティカード。 s.*ck は "s" と "ck" の間に何が何文字挟まっていてもヒットするし、 sck にもヒットする
[] このうちの 1 文字のどれか、を表す。 s[aio]ck は sack, sick, sock にマッチするが suck, sck, sacck にはヒットしない
[a-z] アルファベットなら a, b, c....z までどの 1 文字でもいい、の意。 [] の間に 26 文字全部並べなくても済む。 [a-h] で「a から h までのどれか」を表せるし、 [0-9][0-6] といった風に数字を範囲指定することも可能。組み合わせて [a-z0-9][a-z0-9@#%] などというのもアリ。ただし [z-a] のようにひっくり返してはダメだ。[] の中で "-" という文字自体を表したい時には [] 内の最初か最後に書く
[]* * との組み合わせ。 s[aio]*ck は sck, saack, siiiick, sioiaiioock などにヒットする
[^] [] の意味を反転する。 s[^aio]ck[] 部は「a でも i でも o でもない 1 文字」を表し suck, seck などにヒットする。この使い方での ^ は必ず [ の直後に置かなければならない。 [aio^][ai^o] と書くと ^ は特殊記号の役割を失って「a か i か o か ^ のどれか」という意味になってしまう
{n} 直前の 1 文字が n 回繰り返されている、の意。 s[ao]{3}ck は saaack, sooock, soaock などにヒットする
{n,m} 直前の 1 文字が n 回以上 m 回以下繰り返されている、の意。 asahi-net の公式説明によるとスパムブロックでは正規表現文字 `?' が使えないようだが、同じ役割は {0,1} で表せる
{n,} 上記の m 部を省略すると、n 回以上なら何回でも、の意味になる。スパムブロックの正規表現では `+' が使えないようだが {1,} でそれと同じことが表せる
() 丸カッコは複数の文字を 1 つのかたまりとしてまとめる記号。 s(ac)*k は sack, sacack, sk にヒットするが sak, sck にはヒットしない
| 縦棒は「または」の意。 sac|ink と書くと「sac または ink」の意味になるが、どこまでを「または」の候補にしたいの分かりにくいので上記の () と組み合わせることが多い。 s(ac|in|pan)k は sack, sink, spank にヒットする
^ [] の外で、なおかつ正規表現の先頭に置いた ^ は「行頭」を示す。 ^mail は「mailください」という行にはヒットするが、「私にmailください」や「 mailください」(頭にスペースがある) という行にはヒットしない
$ 行末を表す。 mail$ は「くださいmail」という行にはヒットするが「mailください」という行にはヒットしない
^$ 上記ふたつの組み合わせ。スパムブロックで使う機会はまず無い。「改行されているだけで文字の無い行」を意味する
\ バックスラッシュおよび Yen 記号は正規表現特殊文字から特殊な意味を取り除く場合に前置きする (エスケープする、と呼ぶ)。 s.ck と書くと . は特殊文字だが、 s\.ck と書くと s.ck という文字列そのものを指す。 \ という「文字」自体を表したければ \\ と書く。特にドメインを正規表現で表したい時に忘れがちなので、例えば @hotmail\.cxm のようにドットをエスケープするのを忘れずに。ただし例外として [] の中では、 [ および ] 自体と [ 直後の ^ 以外は、自動的に特殊な意味を失う
<> おまかせフィルタの後日談 で述べたように「おまかせフィルタ」を有効にしてみて、SPAMブロックの正規表現で "<" と ">" が何か特別な意味を持っているようだったので、質問してみたところ、"<" と ">" は単語の区切り (Perl互換正規表現での "\b") を示すことが分かった。つまり、"<pill>" という正規表現フィルタを書くと、"buy pill." にはヒットするが "spill" や "pills" にはヒットしない。また、インターネットメールの書式を定めた RFC2822 では、ヘッダ中のアドレススペック (メールアドレス) は <hoge@hoge.cxm> のように "<>" で囲むことが許されて (推奨されて) いるが、実際にいろいろな正規表現を書いてみると、SPAMBlock ではコンテントの To: ヘッダや Cc: ヘッダを検索する際にはあらかじめそれらの "<" や ">" を外している - または無視しているように見受けられる。逆に、正規表現フィルタの中で文字通りの "<" や ">" 自体をヒットさせたい時には、 [] の中であれどこであれバックスラッシュでエスケープしてやる必要がある

スパムブロックの正規表現検索は常に「大文字小文字の区別無視」

実験の結果、スパムブロックは、正規表現で指定した半角英字は常に、大文字と小文字との区別をせずに検索していることが分かった。よって、次の各正規表現

sack
Sack
SACK
[Ss]ack

は全て同じ意味となり、最後の例はスパムブロックにおいては無駄な書き方。 Perl 風に書くと:

$x =~ /sack/i

という処理をやっているわけだ。かたや「設定方法」を「一般テキスト」に設定したルールでは大文字小文字が区別されるので注意が必要だ。しかし、 [Ss] といった大文字小文字選択の正規表現を使ってもエラーとなることは別段無く、記述のバリエーションを嵩増しするために使うのは全く問題ない。

行全体をヒットさせる必要はない

スパムブロックにおける正規表現での検索では、「マッチする表現がその行内にあるかどうか」を検査している。 grep 的というか、Perl の =~// 的な処理なので、前後を .* でカバーする必要はない。 com か cxm を含む行をヒットさせるには .*c[ox]m.* でなく、単に c[ox]m と書いておけばよい。

IP範囲をマッチさせる正規表現の例

X-IP ヘッダに対して特定の IP 範囲をマッチさせる時のことを考える。幾つか書いているうちに慣れてくるだろうが、最初はコツがつかみにくいと思うので例を示しておこう。

わりと単純な例: China Railway Telecom (61.232.0.0 - 61.237.255.255)
^61\.23[2-7]\.

頭の 2 オクテットだけがターゲットとなるので、間違って 202.61.232.1 といった IP までヒットしてしまわないよう先頭に ^ を付けている。また、この場合、2 オクテット目がたまたま 3 桁固定なので最後の \. は無くても構わない。

複雑な例: APOL 台湾 (210.200.0.0 - 210.203.127.255)
^210\.20([0-2]|3\.([0-9]{1,2}\.|1[01][0-9]|12[0-7]))

何をやっているのか記述順に噛み砕くと;
頭が必ず 210.20 で始まるが、
2 オクテット目が 200 以上 202 以下ならヒット、
2 オクテット目が 203 だったら、
3 オクテット目が 「1桁か 2桁」 か 「10x か 11x」 ならヒット、
3 オクテット目が 12x の時は x は 0 から 7 までのいずれか
ということになる。

正規表現の必要なし: HANANET 韓国 (211.208.0.0 - 211.208.255.255)

このように単純に頭の 2 オクテットだけでくくれる IP レンジは、なるべく正規表現を使わずに「~で始まる」の条件で設定する。そのほうが (おそらく) サーバに与える負荷が小さいはずだ。この例の場合 「211.208」「で始まる」 で良い。