スパム考

 ブログが放置状態なのは、別に死んだわけではなく、ちょっと仕事が立て込んでるからなんである。

 おまけに、これが例の美脚の会社なんである。

 色香に迷って必要以上の仕事までやっつけてしまった事に味をしめたらしく、テキは交渉相手として美脚を前面に立ててきたんである。こちらも慈善事業ではないんである。おまけに美脚は一点差二死満塁ノーストライク3ボールからの強打なんである。ヤリたくても絶対にヤラせてくれないのである。だけどムゲにはできないんである。男の悲しいサガなんである。

 さて。

 なんだか物凄く久しぶりにメール関係の仕事なのである。何を今更だが、スパムが多いねぇ。
 McColoロックアウトのつかの間の蜜月も、はや追憶のかなたって感じだ。

 設計し始めてまっさきに思ったのは、「もう、一段のフィルタリングじゃやってられない」ということである。

 昔(っても数年前)だったら接続時点にブラックリストで蹴るなり、コンテンツフィルタを入れるなりで充分だったように思うんだが、今時のスパムの量を考えると、フィルタリングを多段にする構成でないとやっていけないような気がする(多少のfalse-positiveは許容できるという幸せな場合は例外にして)。

 最低でも
  1. SMTP接続時点のフィルタ(お金のある会社ならスパム除去サービス)
  2. コンテンツフィルタ
  3. ユーザのMUA(付随するSPAM/ウィルス対策ソフト)
の三段構成くらいで考えないとマズいんではないか。

 一般的にコンテンツフィルタは計算コストが高い。
 電話で言えば、「いちおう電話には出てから相手の話の内容を判定して蹴る・蹴らないを決める」ようなものだ。スパムの量があまりに多いと運用がキツいはずである。典型的には、このコンテンツフィルタがボトルネックになってメール配信が遅延してしまうという危険性も無視できないくらいだ。

 かといってSMTP接続時点のフィルタ(例えばDNS-RBLみたいなブラックリスト方式)だけで済むか、というとこれが中々難しい。

 一例を挙げると、良くある接続時点フィルタ方式に「接続元のホスト名が逆引きできなかったらフィルタ」という考え方がある。

 この「逆引き」条件に関しては、ネット上でも賛否いろいろ議論があるが、俺の結論としては「海外相手に手広く通信してる場合にはヤバすぎて、いきなり拒否はできない」ということなんである。

 いろいろな人が言っているように、逆引き名(PTR)は絶対に付けなきゃいけないわけではないし、どうもこの「慣習」自体が存在しない国もあるようだ。DNSクエリだってコケることはある。

 根がマジメな上にある程度法律の網もかかっていて、OP25Bなど対策をとっている日本のISP/NSPならいざ知らず、海外のネットワークに一律適用するのは慎重にならざるを得ない。

 ところがこの「逆引き失敗」というのは、もっとも効果の大きなルールなのである。

 引き合いに出して恐縮だが、有名どころでS25Rというものがある。
 浅見秀雄さんが考えられたS25R(Selective SMTP Rejection)方式は、少ないルールで高い効果が期待できる実に巧妙な方法である。
 このS25Rにも「ルール0:逆引き失敗」というルールが取り入れられている。

 試しにS25Rのルールを手元のログに適用してみると、「ルール0:逆引き失敗」の対象になるだろうメールは全体の45~50%に上る(もちろん大半がスパムである)。これは残りのルール全部(名前が引けた場合に動的IPと思しきネーミングだったらフィルタ)で引っ掛ける総和とほぼ等しい。

 S25Rの他のルールは正規表現で逆引きホスト名を判定する方法なので、甘目辛目の調整もできるが、このルールだけはそうもいかない。
 で仕方なく、ルール0の適用を諦めるとなると、せっかく良く出来ているS25Rルールでもブロック率が半減してしまう…、という悲しいことになってしまうかもしれないわけだ。

 この辺の問題もあるので、現行のS25Rは、いきなり拒否ではなく再試行要求を返しておいてリトライしてきたものを救済する(ブラックではなく、いわゆるグレイリスト方式)という考え方になっているようである。これとピッティングを合わせて自動化したのが佐藤潔さんのtaRGreyだろう。

 リトライの挙動だけで救済すると、ちゃんとメールサーバを使ってくるスパム(最近の出会い系なんかみんなそうだ)が抜けてしまうので、多少辛めに色をつけてもいいかもしれない。

 SMTP接続時(つまりDATAコマンドの前)に、スパム判別に使えそうな特徴はいくつかあるように思う。例えば;
  1. Sender(MAIL)が異常
    1. Senderのチェックは相手の事情もあるのでムゲにキツクはできないし、ドメイン名でハジこう(例えば「これは出会い系のドメインなんでNG」みたいな)としても、ドメイン名は新規にいくらでも取れるので、ブラックリストが爆発的に増えてしまう。運用が難しい上にさほど効果が期待できない。
       だが、Bot相手ということなら、いくつか引っ掛けられそうな特徴がある。
       例えば「外から来たメールなのに、こっちのメールアドレスを名乗っている」、なんてのがそうだ。外部からの正規の転送ということはありうるが、情報漏洩の防止の観点から、そういうこと自体禁止、という会社も多いだろう。
    2. さらにヒドイのは「Sender=Recipentというメール」が無視できないほど多い。手抜きもいいところである。Bot作る奴ももう少し丁寧に作ったらどうか(爆)。
  2. Recipient(RCPT)が異常
    1. 宛先のドメイン名にこちらのサーバの名前(経路途中の内部サーバ名も含めて)をそのまま使っている。例えばドメイン名がfoo.co.jpで、メールサーバがmx1.foo.co.jpだったりすると、hogehoge@mx1.foo.co.jpなんて宛先で送ってこようとする(hogehoge@foo.co.jpが正解)。仕様上は合法かもしれないが、マトモな人が送ってくるメールだったらちょっと考えられない。
    2. 奇妙な記号で始まっている。例えば正しいメールアドレスがhogehoge@foo.co.jpの場合、この前に縦棒(|hogehoge@foo.co.jp)を付けてくる。おそらくパイプを利用した悪さか何かを狙ってるのだろうと思うが、単なるバグかもしれない(笑)。どっちみち内部配送でエラーにするので、入り口で蹴ってしまっても差し支えなかろう。このバー始まりのメアドというのは、想像していた以上に多いので、何か特定のBotの仕業なのかもしれない。
  3. ローカルパート(@の前)が16進くさい。
    1. a123bfcf.f8845cda@foo.co.jpみたいな。これもかなり多い。「正しいメールアドレスのローカルパートには数字が含まれない」なんて確信が持てるのなら、正規表現一行でかなりのスパムが弾けるだろう。
  4. HELO(EHLO)がマトモでない
    1. FQDNでなかったり、ヒドイのになるとlocalhostとか[127.0.0.1]とか、フザケルなと言いたくなる様な名前を名乗ってくるものがある。MUAの実装や相手のメール環境による可能性もあるが、フツーはあまりなかろう。
  5. Message-IDをつけて来ない
    1. これはDATA文の前ではないのでSMTP接続時の特徴ではないが、意外と判りやすい特徴なので挙げておく。メッセージIDはフツーはMUAか最初に踏んだMTAがつけるので、相手がフツーのメール環境だったら付けてくると期待してもあながち間違いではなかろう。必ず付けなさいというルールは無いかもしれないが、これが付いていないということは普通のMUA/MTAを使用しないで、こちらのメールサーバに直接繋いでいる可能性が高い。つまりマトモなショーバイ相手ではない(おいおい)ので、リトライ救済を前提としてなら蹴ってしまって構わないかもしれない。

 もちろん、どれも単一の合致でクロ判定ができるようなものではないので、重み付けで使うというのが正解だろう。何点か取得したら積極的に救済しないとか、一時的にグレイリストに入れる、みたいな。

 また、この種の特長は「汚いネットワーク」を探すことにも使えるかもしれない。
 ためしに受信ログから上に挙げたような特徴の加点方式で怪しげなIPを抜き出してみて、SenderBaseなどでチェックしてみると、かなりの高確率でPoor評価と一致し、イモヅル(CIDR)で「汚いネットワーク」を見つけることができるようだ。状況によってはテンポラリなブラックリストとしても利用できるかもしれない(総量からいえばゴミみたいなものなので効果としてはあまり期待できないが)。

 このようなヌルい方法だと、ユーザの手元に到達してしまうスパムはほぼ絶対に減らないが、SMTP接続レベルのフィルタは単に後段のコンテンツフィルタの負荷低減のためだけ=コンテンツフィルタの無制限なスケールアウト(笑)やフィルタリング起因の配信遅延の抑制程度にはなる、という見切った設計でもいいのではあるまいか。

 いずれにしても、
  1. 今やフィルタリングは「単一」ではなく「多段」で考えた方がよさそうだ
  2. スパムの手口も多様化してるし、false-positiveの許容度・許容できるコストも千差万別なので、フィルタリング方法・条件に万能薬はない。状況に合わせた調整が必要(ぶっちゃけ、どこぞのRBLを使ってるからOKとかS25Rで万全、なんてわけにはいかないということ)
というのがここ最近の感想なんである。

…しかし、全世界でスパムで悩んでいる人から募金すればゴルゴ13を雇って主要スパマーを始末してもらうくらいできるんじゃなかろうか(爆)




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


メールで御質問いただいたので、「HELOのチェック」の所を補足しておく。

これもいろんな方が意見を述べておられるのであくまでも現時点での俺の個人的な見解なんだが、

「マトモな通信先」だったら、ちゃんとしたMTAをちゃんと設定して使っているはずだ。HELOに関して言えば、RFC2821/RFC5321に準拠して、FQDNか[]で括った10進可読のIPアドレス(アドレスリテラル)を使用するはず…と「希望的観測」を行っても大きく外れないはずである。
この仮定に立つと、「HELOの引数には必ず一つ以上のドットが含まれているはず」と仮定できるので、この逆、「HELOの引数にドットが含まれていない」場合は疑ってかかれる、という結論に達する。

/^(?!.+\.).+$/ → 怪しい

(もしかしたら、「FQDNということは、サーバ名.ドメイン.TLD だろうから、最低でもドットが2個以上は含まれる」と仮定しても、そんなに大きく誤爆しないかもしれない)

さらにいうと、確かに合法は合法だが、実際にHELOをアドレスリテラルで投げてくるような「マトモな通信先」がどの程度あるだろうか?
 HELOの引数はDNSの逆引きと違い、基本的に<自己申告>である。そもそも自分の名前をマトモに設定しないような「マトモなMTA」がそんなにいっぱいあるだろうか?

ということで、RFC上合法ではあるが、アドレスリテラルも対象に出来るのではないか。

/^\[/ → 怪しい。

もちろん、ドットが含まれているからと言って、アドレスリテラル形式になっていない「生IP」はRFC違反なので、

/^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/ → 怪しい

(もっと単純に /\.[0-9]{1,}$/ → 怪しい でもいいか)

さて、こう(=「HELOの引数として、FQDNだけを認めるつー方針にしよう」)考えてくると、

FQDNで認められない文字が含まれている:/^.*[^a-zA-Z0-9\[\]\.\-].*$/ → 怪しい

頭やおしりがドット:/^\./及び/\.$/ → 怪しい

なども検討する価値はあるだろうと思う。

さらにもちろん、この後にS25R流の動的IPっぽいホスト名を指定してもいいだろうし、こっちのFQDNを名乗ってくる不届き者や、頻繁にみかける「デタラメなTLD」(/\.lan$/ だの /\.firewall$/ だの)を個別に引っかけてもいいかもしれない。

前述のように、DNSの逆引きと違い、HELOのホスト名は基本的に<自己申告>である。

「運用コスト上の理由でゾーン持ってないんですよね」とか「ウチのISPは文化的に逆引き設定する習慣がないんで」とか「たまたまDNSが引けなかっただけ」的な事情はあまりないんじゃないか、と思えるのだ。

いわゆる「ホスト名逆引き」でのチェックを躊躇する場合は、検討する価値はあると思う。
[PR]
by SIGNAL-9 | 2009-06-09 00:00 | 情報保護・セキュリティ | Comments(0)
<< 空からオタマジャクシが降ってきた? 「オフレコ」ってなんなの? >>