spam filtering for mx (ja) / メール交換機でのスパム排除

98
メール交換機でのスパム排除 外部から来る SMTP トランザクションで不要メールを拒否するには Tor Slettnes 1 Joost De Cock 2 Devdas Bhagat 3 Tom Wright 4 , 5 4th July 2005 1 2 3 4 5

Upload: hatuka4030

Post on 27-Jul-2015

627 views

Category:

Documents


7 download

TRANSCRIPT

Page 1: Spam Filtering for MX (ja) / メール交換機でのスパム排除

メール交換機でのスパム排除

外部から来る SMTPトランザクションで不要メールを拒否するには

Tor Slettnes1 Joost De Cock2 Devdas Bhagat3 Tom Wright4

池田, 荘児5

4th July 2005

1著者2技術面の校閲3技術面の校閲4言語面の校閲5日本語訳

Page 2: Spam Filtering for MX (ja) / メール交換機でのスパム排除

Keywords

anti-spam, スパム対策, anti-virus,ウィルス対策, bogus virus warnings,いんちきウィルス警告, collateralspam, 巻き添えスパム, 後方散乱メール, delivery status notification, 配送状況通知, DSN, Exim, Exim4,Exiscan, Exiscan-ACL, greylisting, グレーリスト法, junk mail, 不要メール, SA-Exim, SMTP, spam,スパム, Spamassassin, teergrubing, タール坑法, transaction delay,トランザクションの遅延

Page 3: Spam Filtering for MX (ja) / メール交換機でのスパム排除

はじめに

この文書の目的

この文書では、メール交換機 (MXホスト)での外部から来る SMTPトランザクションの間に スパムやマルウェアを取り除くための、効果が高く悪影響が少ないさまざまな方法について論ずる。これらの方法

では、いわゆる巻き添えスパム [78]を除去することも重視している。議論はおおむね概念的であるが、 Exim MTAと特定のソフトウェアツールを使ったサンプル実装も提供

する。これには、議論で述べた以外にもさまざまな工夫をもりこんである。

対象者

この文書が意図する対象者はメールシステム管理者であり、SMTP, MTA/MDA/MUA, DNS/rDNS, MXレコードのような略号にはなじみがあるものとする。 メールリーダ (Evolution, Thunderbird, Mail.app,Outlook Express のような) でスパムを排除するための解決策を探しているエンドユーザは この文書の対象ではないが、自分のドメイン (企業、学校、ISP...) のメールシステム管理者に この文書の存在を知らせることができるであろう。

この文書の新版

この文書の最新版は http://slett.net/spam-filtering-for-mx/で見つかる。訂正や追補がないか、

定期的に確認してほしい。

改版履歴

改訂履歴

改訂 1.0 2004-09-08 TS

最初の一般公開。

改訂 0.18 2004-09-07 TS

Tom Wright による 2度目の言語面の校閲を反映。

改訂 0.17 2004-09-06 TS

Tom Wright による言語面の校閲を反映。

改訂 0.16 2004-08-13 TS

Devdas Bhagat の第 3次の変更を反映。

改訂 0.15 2004-08-04 TS

Devdas Bhagat の技術面の校閲に伴う第 3次の変更を反映。

改訂 0.14 2004-08-01 TS

Devdas Bhagat からの技術面の校閲での意見/訂正を反映。

改訂 0.13 2004-08-01 TS

Joost De Cock からの技術面の校閲を反映。

i

Page 4: Spam Filtering for MX (ja) / メール交換機でのスパム排除

改訂 0.12 2004-07-27 TS

"論争についての注" [A Note on Controversies] の節を、 より主張のはっきりした "善玉、悪玉、

卑劣漢" の節で置き換え。 また、DNS ブロックリストについての文章を書き換え。 Seymour J. Metz

からの若干の訂正。

改訂 0.11 2004-07-19 TS

Rick Stewart からの RMX++ についての意見を反映。 "テクニック" と "検討事項" の順序を入れ

換え。 Eximによる実装での書体の軽微な修正。

改訂 0.10 2004-07-16 TS

<?dbhtml..?> タグを追加して、生成される HTMLファイル名を制御 --- Google などでのリンク切

れを防げる。 "転送されてきたメール" と "ユーザの設定" の順序を入れ換え。 Tony Finch からの

Bayes式フィルタ についての訂正を反映; Johannes Berg によって、 Subject:、Date:、Message-

ID: ヘッダの検査をコメントアウト; Alan Flavell からの助言で、SMTP遅延の処理時間を減らす。

改訂 0.09 2004-07-13 TS

エンヴェロープ送信者のシグネチャとメーリングリストサーバの問題と、 ホスト/ドメインごとに任

意であるこのようなシグネチャを各々のユーザが作る方式 の部分を推敲。 "検討事項" の節を独立

の章に移動 --- "他の SMTPサーバへのアクセスを阻止する"、 "ユーザの設定"、"転送されてきた

メール" の節を追加。 シグネチャを生成する機構についての Matthew Byng-Maddick の意見、 Cris

Edwards の送信者の呼出し確認法についての意見、 Hadmut Danisch の RMX++ その他の話題につ

いての意見を反映。 許諾条項を変更 (GFDL から GPL へ)。

改訂 0.08 2004-07-09 TS

Eximによる実装への追加: Tollef Fog Heen からの助言により、 SpamAssassin のためのユーザ

ごとの設定とデータについての節を追加。 Exiscan-ACL による SPF検査を追加。 Sam Michaels か

らの訂正。

改訂 0.07 2004-07-08 TS

Eximのエンヴェロープ送信者のシグネチャの例に訂正。 また、Christian Balzer の助言により、

この仕様にユーザの "オプトイン" 対応を追加。

改訂 0.06 2004-07-08 TS

Exim/MySQLのグレーリスト法の実装と、 Johannes Berg によるさまざまな訂正を反映。 "送信者

認証方式" を 2段階上げて、テクニックの章の最上位の節にした。 空のエンヴェロープ送信者のため

の、DATA の後でのグレーリスト法を追加。 SpamAssassinの設定を、Eximの例に合うように追加。

Dominik Ruff, Mark Valites, "Andrew" at Supernews からの訂正を反映。

改訂 0.05 2004-07-07 TS

(中身のない) Sendmailによる実装はいまのところ外す、

改訂 0.04 2004-07-06 TS

レイアウトを若干再構成: "SMTPの時点での排除"、"SMTPの入門"、"検討事項" は単一の "背景"

の章にまとめた。 Eximによる実装 の中の "ACLの構築" の節は分離して最上位の節に。 SPF以外

の送信者認証方式を追加: Microsoft Caller-ID for E-mail と RMX++。 Ken Raeburn からの

意見を反映。

改訂 0.03 2004-07-02 TS

複数の受入用メール交換機についての議論を追加; 送信者の呼出し確認法に関係する軽微な訂正。

改訂 0.02 2004-06-30 TS

Eximによる実装を付録として追加

改訂 0.01 2004-06-16 TS

最初の草稿。

ii

Page 5: Spam Filtering for MX (ja) / メール交換機でのスパム排除

謝辞

[改版履歴] [i]に記してあるとおり、おおぜいの方々からフィードバック、訂正、寄贈を戴いている。 感謝する。

以下は、この文書にツールやアイディアを提供して下さった方々や組織の一部である (順不同)。

• Evan Harris <eharris a©puremagic.com>。グレーリスト法を発案し、その白書を著した。

• Axel Zinser <fifi a©hiss.org>。 タール坑法を発案したとされる。

• SPF1、 RMX++2 やその他の[送信者認証方式] [17]の開発者の方々。

• DCC3、 Razor4、 Pyzor5 のような、 分散型で協調型の不要メールシグネチャ集積システムの作成者とメンテナの方々。

• SpamCop6、 SpamHaus7、 SORBS8、 CBL9、 その他たくさん10 のような、 さまざまな DNSブロックリストやホワイトリストの作成者とメンテナの方々。

• SpamAssassin11 の開発者の方々12。彼らは、さまざまなスパム排除テクニックの開発と、洗練され

たヒューリスティックに基づくツールへの統合に長足の進歩をもたらした。

• Tim Jackson <tim a©timj.co.uk>。 いんちきウィルス警告の一覧をまとめ、 メンテナンスして、

SpamAssassin で利用できるようにした。

• 素晴らしい Exim MTA を開発した、 数々の明敏な方々: Philip Hazel <ph10 a©cus.cam.ac.uk>

(メンテナ)、 Tom Kistner <tom a©duncanthrax.net> (SMTP 時点でのコンテンツ検査のためのExiscan-ACL パッチを書いた)、 Andreas Metzler <ametzler a©debian.org> (Exim 4 の Debianパッケージをビルドするという、素晴らしい働きをした)、ほか。

• スパムの蔓延に抗するためのアイディア、ソフトウェア、その他のテクニックを提供して下さった、その他数多くの方々。

• 有用なコミュニケーションツールとしての電子メールを取り戻すことに関心を寄せ、この文書を読んで下さっている、あなた。

フィードバック

この文書で概説しているテクニックについての実地の体験や、その他のさまざまな意見や疑問や助言を

聞かせてもらうこと、寄贈をいただけることは、私にとって喜ばしいことだ。 <[email protected]>に電子

メールを送ってほしい13。

他のメール転送エージェント [79] (Sendmailや Postfix のような)での実装を提供できる方は、知らせてほしい。

1http://spf.pobox.com/2http://www.danisch.de/work/security/antispam.html3http://rhyolite.com/anti-spam/dcc/4http://razor.sf.net/5http://pyzor.sf.net/6http://www.spamcop.net/7http://www.spamhaus.org/8http://www.sorbs.net/9http://cbl.abuseat.org/

10http://moensted.dk/spam/11http://www.spamassassin.org/12http://www.spamassassin.org/full/3.0.x/dist/CREDITS13[訳注] 著者によると、日本語は読めないので、 英語 (かノルウェイ語 :-) がよいそうである。

iii

Page 6: Spam Filtering for MX (ja) / メール交換機でのスパム排除

翻訳

翻訳はまだない。やりたい方は、知らせてほしい。

著作権情報

[訳注: 本節は訳さない。]Copyright c©2004 Tor Slettnes.This document is free software; you can redistribute it and/or modify it under the terms of the GNU

General Public License as published by the Free Software Foundation; either version 2 of the License, or(at your option) any later version.

This document is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PUR-POSE. See the GNU General Public License for more details. A copy of the license is included in 付録 B[81].

Read The GNU Manifesto14 if you want to know why this license was chosen for this book.The logos, trademarks and symbols used in this book are the properties of their respective owners.

日本語訳について

Japanese translation is copyright c©2005 by IKEDA Soji.当日本語訳の翻訳物に関する著作隣接権は、池田荘児に帰属する。

当日本語訳の再配布等の条件は、原文の条件に準ずる。

必要なこと

この文書で説明するテクニックでは、自分が電子メールを受け取るインターネットドメインの 内部行き

のメール交換機 [79]のシステムへアクセスできることを前提にしている。つまり、自分でソフトウェアをインストールしたり、自分でそのシステムのメール転送エージェント [79]の設定ファイルを変更したりできなければいけない。

この文書での議論は、総じて概念的ではあるが、多くの異なるMTAで実現可能なものだから、Exim 4のサンプル実装も提供している。この実装ではまた、 SpamAssassin15 のようなほかのソフトウェアツー

ルを組み込んでいる。 詳細は付録 A [29]を見てほしい。

この文書の凡例

文中に現れる書体と用字は以下のとおり。

この文書の構成

この文書は、以下の章からなる:

[背景] [1] SMTPの時点での排除、および SMTPの一般的な紹介。

14http://www.fsf.org/gnu/manifesto.html15http://www.spamassassin.org/

iv

Page 7: Spam Filtering for MX (ja) / メール交換機でのスパム排除

Table 1: 書体と用字

書体 意味

「引用文」 発言の引用、計算機の出力の引用。

terminal view 端末から写し取った計算機の入出力そのもの。 普

通は薄灰色の背景で表示される。

command コマンドラインに入力されるコマンドの名前。

VARIABLE 変数の名前、変数の内容を示す。 例: $VARNAME

option コマンドのオプション。 例: 「ls コマンドの -a

オプション」。

argument コマンドの引数。例: 「man ls を読め」。

command options arguments

コマンドの書式や一般的な用法。 独立した行で表

記する。

filename ファイルやディレクトリの名前。 例えば 「/usr/

binディレクトリへ移動する。」

Key キーボードで打つキー。例: 「終了するには Q を

タイプする」。

Button OKボタンのように、 クリックできるグラフィカ

ルなボタン。

メニュー → 選択 グラフィカルなメニューから選択できるもの、例

えば: 「Webブラウザで ヘルプ → Mozilla につ

いて を選択する。」

用語 重要な用語や概念: 「Linux のカーネルは、システムの心臓部だ。」

[用語集] [75]を見よこの案内の中の関連する話題。

著者 http://slett.net/gallery/2003-05/

IMG 1655

外部のWebリソースへのクリックできるリンク。

[テクニック] [7] SMTPトランザクションで不要メールを阻止するさまざまな方法。

[検討事項] [25] トランザクションの時点での排除に関する課題。

[質問と回答] [27] あなたの疑問に先回りして答えてしまおうという試み。

付録 A [29]では、Eximによるサンプル実装を提供する。

v

Page 8: Spam Filtering for MX (ja) / メール交換機でのスパム排除
Page 9: Spam Filtering for MX (ja) / メール交換機でのスパム排除

目次

はじめに i

この文書の目的 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i対象者 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iこの文書の新版 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i改版履歴 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i謝辞 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iiiフィードバック . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii翻訳 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv著作権情報 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv

日本語訳について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv必要なこと . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ivこの文書の凡例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ivこの文書の構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv

第 1章 背景 1

1.1 SMTPトランザクションの間にメールを排除する理由 . . . . . . . . . . . . . . . . . . . . . 11.1.1 現状 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1.2 原因 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1.3 解決策 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.2 善玉、悪玉、卑劣漢 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 SMTPトランザクション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

第 2章 テクニック 7

2.1 SMTPトランザクションの遅延 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2 DNSによる検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.2.1 DNSによるブラックリスト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.2.2 DNSによる整合性検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.3 SMTPでの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.3.1 ハロー (HELO/EHLO) の検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.3.1.1 HELO/EHLOの簡易な構文検査 . . . . . . . . . . . . . . . . . . . . . . . 102.3.1.2 ハロー挨拶を DNSで確認する . . . . . . . . . . . . . . . . . . . . . . . . 11

2.3.2 送信者アドレスの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.3.2.1 送信者アドレスの構文検査 . . . . . . . . . . . . . . . . . . . . . . . . . . 122.3.2.2 詐称の検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.3.2.3 送信者アドレスの簡易な検証法 . . . . . . . . . . . . . . . . . . . . . . . . 122.3.2.4 送信者呼出し確認法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.3.3 受信者アドレスの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.3.3.1 開放型リレーの防止 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.3.3.2 受信者アドレスの確認 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.3.3.3 辞書攻撃の防止 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.3.3.4 受信者が一つの DSNだけを受け付ける . . . . . . . . . . . . . . . . . . . 15

2.4 グレーリスト法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.4.1 どのように動作するか . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.4.2 複数のメール交換機でのグレーリスト法 . . . . . . . . . . . . . . . . . . . . . . . . 162.4.3 結果 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

vii

Page 10: Spam Filtering for MX (ja) / メール交換機でのスパム排除

2.5 送信者認証方式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.5.1 Sender Policy Framework (SPF) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.5.2 Microsoft Caller-ID for E-Mail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.5.3 RMX++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.6 メッセージデータの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.6.1 ヘッダの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.6.1.1 ヘッダがない . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.6.1.2 ヘッダアドレスの構文検査 . . . . . . . . . . . . . . . . . . . . . . . . . . 192.6.1.3 ヘッダアドレスの簡易な検証法 . . . . . . . . . . . . . . . . . . . . . . . . 192.6.1.4 ヘッダアドレス呼出し確認法 . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.6.2 不要メールシグネチャ集積システム . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.6.3 バイナリゴミデータの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.6.4 MIMEの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.6.5 添付ファイルの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.6.6 ウィルス検出ソフトウェア . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.6.7 スパム検出ソフトウェア . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.7 巻き添えスパムの阻止 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.7.1 いんちきウィルス警告を排除する . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.7.2 自分のドメインの SPF情報を公開する . . . . . . . . . . . . . . . . . . . . . . . . . 222.7.3 エンヴェロープ送信者のシグネチャ . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.7.4 実在するユーザへのバウンスだけを受け付ける . . . . . . . . . . . . . . . . . . . . . 24

第 3章 検討事項 25

3.1 複数の受入用メール交換機 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.2 他の SMTPサーバへのアクセスを阻止する . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.3 転送されてきたメール . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.4 ユーザごとの設定とデータ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

第 4章 質問と回答 27

付録A Eximによる実装 29

A.1 必須事項 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29A.2 Eximの設定ファイル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

A.2.1 アクセス制御リスト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29A.2.2 展開 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

A.3 オプションと設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30A.4 ACLの構築 — 第一段階 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

A.4.1 acl connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32A.4.2 acl helo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32A.4.3 acl mail from . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32A.4.4 acl rcpt to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32A.4.5 acl data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

A.5 SMTPトランザクションの遅延を追加する . . . . . . . . . . . . . . . . . . . . . . . . . . . 37A.5.1 簡易な方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37A.5.2 選択的な遅延 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

A.6 グレーリスト法への対応を追加する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41A.6.1 greylistd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41A.6.2 MySQLによる実装 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

A.7 SPFの検査を追加する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

viii

Page 11: Spam Filtering for MX (ja) / メール交換機でのスパム排除

A.7.1 Exiscan-ACLによる SPFの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46A.7.2 Mail::SPF::Queryによる SPFの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . 47

A.8 MIMEとファイル型の検査を追加する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48A.9 ウィルス対策ソフトウェアを追加する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49A.10 SpamAssassinを追加する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

A.10.1 Exiscanから SpamAssassinを呼び出す . . . . . . . . . . . . . . . . . . . . . . . . . 49A.10.2 SpamAssassinの設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50A.10.3 ユーザごとの設定とデータ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

A.10.3.1 Eximが配送ごとに一つの受信者しか受け付けないようにする . . . . . . . 51A.10.3.2 SpamAssassinに受信者のユーザ名を渡す . . . . . . . . . . . . . . . . . . 51A.10.3.3 SpamAssassinでユーザごとの設定を有効にする . . . . . . . . . . . . . . . 52

A.11エンヴェロープ送信者のシグネチャを追加する . . . . . . . . . . . . . . . . . . . . . . . . . 53A.11.1 送信者アドレスに署名するためのトランスポートを作成する . . . . . . . . . . . . . 53A.11.2 リモート配送のためのルータを新たに作成する . . . . . . . . . . . . . . . . . . . . . 54A.11.3 ローカル配送のための転向ルータを新たに作成する . . . . . . . . . . . . . . . . . . 55A.11.4 ACLシグネチャの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

A.12実在するユーザへのバウンスだけを受け付ける . . . . . . . . . . . . . . . . . . . . . . . . . 56A.12.1 受信者のメールボックスの検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56A.12.2 エイリアスルータでの空送信者の検査 . . . . . . . . . . . . . . . . . . . . . . . . . 57

A.13転送されてきたメールを通す . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58A.14できあがった ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

A.14.1 acl connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60A.14.2 acl helo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61A.14.3 acl mail from . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62A.14.4 acl rcpt to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64A.14.5 acl data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

用語集 79

付録B GNU General Public License 81

B.1 Preamble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81B.2 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 81

B.2.1 Section 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82B.2.2 Section 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82B.2.3 Section 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82B.2.4 Section 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83B.2.5 Section 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83B.2.6 Section 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84B.2.7 Section 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84B.2.8 Section 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84B.2.9 Section 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84B.2.10 Section 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84B.2.11 Section 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85B.2.12 NO WARRANTY Section 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85B.2.13 Section 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

B.3 How to Apply These Terms to Your New Programs . . . . . . . . . . . . . . . . . . . . . . 85

ix

Page 12: Spam Filtering for MX (ja) / メール交換機でのスパム排除
Page 13: Spam Filtering for MX (ja) / メール交換機でのスパム排除

第1章 背景

概要ここでは、 メールのルーティングや配送の段階での通常のアプローチによるのではなく、外部から来

る SMTPトランザクションの間にメールを排除することの利点を説明する。 また、SMTPトランザクションの簡単な紹介もする。

1.1 SMTPトランザクションの間にメールを排除する理由

1.1.1 現状

スパムを受け取ってる人、手を挙げて。手は挙げたままにしといてね。

コンピュータウィルスやその他のマルウェア1を受け取ってる人も、手を挙げて。

自分が送ってもいないメッセージについて、いんちきな配送状況通知 [78] (DSN) (「Message Undeliv-erable」というようなの) とか、「Virus found」とか、「Please confirm delivery」などのメッセージをいっぱい受け取ってる人も、手を挙げて。こういうものを巻き添えスパム [78]と言う。いま言ったものは、実に厄介だ。なぜなら、「標準的な」 スパムやマルウェアより取り除きにくいし、

メッセージヘッダを読み解く神業を身につけていない受信者だと、このようなメッセージがあると混乱し

てしまうからだ。これがウィルス警告だった場合は、受信者側に不必要な心配をさせてしまうことも、よ

くあることだ — これが常態化すると、多くのひとはこのようなメッセージをすべて無視するようになり、

そのため、真っ当な DSNまで見落とすことになる。じゃあ最後。スパム検出ソフトウェアやウィルス検出ソフトウェアの設定ミスで、真っ当なメールが虚

空のかなたに消え去っちゃったことのある人は、— 両足あげて。

さっきから立っていて、いまでも立っていられる人がいるとしたら、その人は、自分のメールがどうなっ

ているかをちゃんと把握できていないのだろう。どんなやりかたでスパム排除をやってきた人でも (DNSブラックリスト — SpamHaus, SPEWS, SORBS... — のような素朴な排除テクニックを実践してきた人は

もちろん、 メールをメールリーダのゴミ箱フォルダに手作業で移動しているだけの人であっても)、 必要なメールを失っている可能性はあるのだ。

1.1.2 原因

スパムは、貪欲2の罪業が生み出してきたさまざまな人造物と同じく、 社会の病理である。蕩尽熱3とで

も呼ぶがよかろう— インターネットという生態系は愚かな人間どもの活動によって危機に瀕しており、ひ

いてはこのことがインターネット上での人類の生存をも脅かしかねないのである。

社会の大問題やよりよい人生の在り方についてはひとまず置いておくが、あなた — メールシステム管

理者 — 自身も、このゴミを始末するための方法について、 極めて具体的な実生活上のジレンマに直面す

1[訳注] malware — ラテン語 mal- (悪い) と softwareによる造語。コンピュータウィルス、ワーム、トロイの木馬などの、「悪意のこもった」ソフトウェアの総称。

2[訳注] greed。 中世ヨーロッパキリスト教での「七つの大罪」の一つ。3[訳注] affluenza — affluence と influenza による造語。 大量生産、大量消費の現代社会では、物質的な欲望が肥大して、いく

ら消費しても精神的に満たされることがなく、借金や長時間労働のためにストレスはますます増大する。いっぽうで、貧富の格差はますます広がり、 一部の人々、企業、国だけに富が偏在している。 このような社会状況を伝染性疾患に見立てた語。

1

Page 14: Spam Filtering for MX (ja) / メール交換機でのスパム排除

ることになる。

メールの処理を メール転送やメール配送のためのさまざまなコンポーネントに丸投げするという従来の

方法では、いくつかの制限があることが判明している。伝統的な設定では、一つまたはそれ以上のメール

交換機 [79]で、ドメインのアドレス宛てに外部から来るメールの配送の ほとんど (ないしはすべて) を受け付ける。それから、よくあることだが、 メールを一つまたはそれ以上の計算機に転送してさらに処理し

たり、ユーザのメールボックスへ配送したりする。これらのサーバのいずれかで要求された配送や機能を

実行できないときは、 DSNを生成して、元のメールの送信者アドレスへ送り返す。多くの組織では、スパムやウィルスの検出ソフトウェアを使い始めたとき、こういうソフトウェアはメッ

セージの配送経路上で動かすのが最善だと考えた。こういうソフトウェアを、メールが受入用メール交換

機 [79]から内部の配送先ホストや配送用ソフトウェアに転送されるメッセージ配送の途上で働かせる、ということである。例えば、スパム排除をするには、まずメールが SpamAssassin などのソフトウェアを通るようにルーティングし、その後にメールをユーザのメールボックスに配送したり ユーザのメール利用者

エージェント [79]でのスパム排除機能に委ねたりする、という方法をとるのが一般的になっている。その際にスパムやウィルスに選別されたメールをどう始末するかについては、選択肢が限られる:

• 送信者に配送状況通知 [78]を送り返す。 問題は、スパムやウィルスが生み出す電子メールのほとんどすべてが 偽の送信者アドレスをつかって配送されているという点だ。こういうメールに返送する

と、必ずと言っていいくらい、 無辜の第三者 — きっと、韓国のおばあちゃんだね。 Mac OS X を使っていて、コンピュータのことはよく分からない — に、あなたは Blasterワームに感染していますなどというメールが 行ってしまうことになる。換言すれば、巻き添えスパム [78]を発生させることになる。

• 送信者になにも通知を送り返さず、メッセージをビットバケツに放り込んでしまう、というのはどうだろうか。これは、メッセージが偽陽性 [76]であった場合に より大きな問題を引き起こしてしまう。なぜなら、送り手も受け手もメッセージがどうなったか分からない (受け手にとっては、それが存在したことすら分からない) からだ。

• ユーザがメールにアクセスする方法によっては (例えば、IMAPプロトコルやWebに基づくメールリーダでアクセスしていて、POP-3でメールを取り込んでいないとしたら)、—たぶんユーザのアカウント設定のオプションに応じて — 別のゴミ箱フォルダに移してしまうこともできるかもしれない。

これは、3つの選択肢のうちでは最善のものだ。しかし、メッセージを見ないでほおっておくユーザもいるだろう。自分の「ゴミ箱」フォルダに入ったメールをちゃんと調べて 不要なものだけ削除し

てくれる受け手もいるだろうが、見落としはあるだろう。

1.1.3 解決策

この問題の唯一の正しい解決策は、ドメインの内部行きメール交換機でメールを受け取る際に、リモー

トホストとの SMTP通信の間にスパムやウィルスの排除を行なってしまうことだ、ということを、分かっていただけると思う。この方法では、望ましくないメールだと判明したときでも 先に述べたようなジレン

マに直面することなく SMTP拒否応答を発行できる。 その結果:

• SMTPトランザクション初期の 実際のメッセージデータを受け取る以前にほとんどの不要メールの配送を 止めることができるから、ネットワークの帯域と CPUの処理能力の両方を節約できる。

• [SMTPトランザクションの遅延] [7]や[グレーリスト法] [15]のような スパム排除テクニックを、かなり早い段階で使うことができる。

• 配送が (例えば有効でない受信者アドレスのために)失敗した場合も、直接的には巻き添えスパム [78]を発生させることなく、送信者に知らせることができるようになる。

2

Page 15: Spam Filtering for MX (ja) / メール交換機でのスパム排除

メーリングリストサーバや他のサイトのメールアカウントのような 信頼できる出所から転送されて

くるメールを拒否した結果、間接的に巻き添えスパムを起こしてしまうことを防止する方法について

は、後ほど論じることにしよう4。

• よそからの巻き添えスパム (ウィルス対策ソフトウェアからのいんちきな「You have a Virus」メッセージのような) も、防止できる。

よーし、じゃあ、手をおろしていいよ。 地に足がつかなくなってた人も、立ち上がっていいよ。

1.2 善玉、悪玉、卑劣漢

排除テクニックの中には、他の手法とくらべて SMTPトランザクションの間に使うのにより向いているものがある。あるものはほかのものよりすぐれている。ほとんどのやりかたには、それぞれ擁護派と反対

派がいる5。

言うまでもなく、こういった論争はこの文書で論じる手法に対しても起きている。例えば:

• [DNSによる検査] [8]は、個々のメール送信者を利用するインターネットサービスプロヴァイダ (ISP)だけに基づいて罰するもので、メッセージそのものの評価に基づいていない、という主張もある。

• [SMTPトランザクションの遅延] [7]や[グレーリスト法] [15]といったラットウェア向けのトラップは容易に乗り越えることができ、 時間がかかる割に効果が薄く、そのいっぽうで真っ当なメールに対

するサービスの品質を低下させていく、という指摘もある。

• [Sender Policy Framework] [17]といった[送信者認証方式] [17]は、 ISPが顧客を囲い込む手段を与え、異なるネットワークの間を移動するユーザや 電子メールをあるホストから他のホストへ転送す

るユーザをうまく扱えない ことが分かってきている。

私は、こうした論争には触れないことにする。 その代り、利用できるさまざまなテクニックの機能面を、

ありうる副作用も含めて説明することにし、そのうちのいくつかを使ってみた私自身の経験を少々述べる

ことにする。

とはいうものの、今日利用されている排除手法のうちいくつかには、この文書ではわざと触れていない:

• チャレンジ-レスポンス・システム (TMDA6 など)。これは、SMTPの時点での排除には向かない。最初にメールを受け付けることになっていて、それから確認要求をエンヴェロープ送信者 [76]に送り返すからだ。このテクニックはそのため、この文書では扱わない7。

• Bayes式フィルタ [75]。これは、特定のユーザ、そしてまた特定の言語ごとに特化した学習を必要とする。そのため、これも通常は SMTPトランザクションの間に使うのには向かない (が、[ユーザごとの設定とデータ] [26]も見てほしい)。

• 小額課金方式 [77]は、この世のあらゆる真っ当なメールに仮想的な切手が ついて送られるようになるまでは、実際には不要メールを取り除くのには向かない (だが、当面はこれを逆の目的に使える。つまり、他の方法では拒否されてしまうメールでも、切手があれば受け付けることにするのだ)。

4それでも、信頼できない第三者ホストのメールを拒否すると、巻き添えスパムを発生させるかもしれない。しかしながら、そのホストが開放型プロキシ [76]や開放型リレー [76]でない限り、そのホストは真っ当な送信者からのメールを配送していると考えられるので、そのアドレスは有効であるはずだ。そのホストが 開放型のプロキシや SMTP リレーであるのなら — そうだねえ、メールは拒否して、そのホストの 送出用メールキューに留めておくほうが、 自分のところに留めるよりもいいだろう。 いつか、そのサーバの持ち主の手がかりにならないとも限らないから。

5[訳注] 本節の表題は 「The Good, The Bad, The Ugly」 (Il Buono, il brutto, il cattivo) (監督: Sergio Leone。1966 年イタリア。 出演: Clint Eastwood, Lee Van Cleef 他。 邦題「続・夕陽のガンマン」) から採られているようだ。

6http://tmda.net/7個人的には、チャレンジ-レスポンス・システムはどんな場合でもいい考えではない、と思う。これは巻き添えスパム [78]を発

生させるし、毎月の銀行の明細のような自動化された出所からのメールに特別な配慮が必要になるし、人々が制約なく自由に触れ合えるという電子メールの利便性を損なう。よくあることだが、真っ当なメールの送信者は 確認要求を処理しなければならないのをいやがるか、 またはそんなことをしなければならないことに気づかない。 そのため、メールを失う。

3

Page 16: Spam Filtering for MX (ja) / メール交換機でのスパム排除

総じて、できるだけ精度が高いテクニックを採用するようにし、偽陽性 [76]を避けることに意を用いるようにした。だれにとっても、自分の電子メールは大切なものだ。だから、時間と労力を費やして書く。私

見だが、真っ当なメールを大量に拒否してしまうテクニックやツールをあえて使うことは、それで直接影

響を被る人々にも、またインターネット全体に対しても、礼を失した行ないだと思う8。これはとりわけ、

SMTP時点でのシステム全体での排除について言えることだ。なぜなら、最終受信者は普通、メールの排除に使う基準をほとんど、あるいはまったく、制御できないのだから。

1.3 SMTPトランザクション

SMTPは、インターネットでのメール配送に使うプロトコルである。 このプロトコルの詳細な記述は、RFC 28219や、Dave Crocker の インターネットメールのアーキテクチャ1011の紹介を参照してほしい。

メールの配送には、 接続してきたホスト (クライアント) と受信側のホスト (サーバ) の間での SMTPトランザクションが伴う。ここでの議論では、接続してきたホストが相手側で、受信側のホストが自分の

サーバである。

典型的な SMTPトランザクションでは、クライアントは EHLO、MAIL FROM:、 RCPT TO:、

DATA のような SMTPコマンドを発行する。 サーバは、ひとつひとつのコマンドに対して 3桁の数値コードで応答し、コマンドを受け付けた (2xx)か、一時的な失敗や制約がある (4xx)か、確定的、永続的な失敗 (5xx)かを示す。その後には、人間が読みやすい説明がつく。コードの完全な説明は RFC 282112

の中にある。

最善の場合の筋書きによる SMTPトランザクションは、典型的には以下の一連の手順から成る:

8私のこの見解は、 SPEWS http://www.spews.org/ブラックリストのメンテナのような 世のおおぜいの「スパム・ハクティヴィスト」 [訳注: hacktivist は hack (ハックする) と activist (活動家) を組み合わせた造語。「技術的な手段を駆使してスパム撲滅のために闘う人 (々)」 の意] のそれとは、好対照をなしている。 これらのリストの狙いのひとつを正確に言うと、「ISPが苦情に反応するよう圧力をかける手段として巻き添え被害 [78]の試練を与えること」である。 リストに載せられたことに異義を申し立てても、しばしば 「我々ではなく、あなたの ISPを責めなさい」とか 「ISPを替えなさい」というような 木で鼻をくくったような返事しか返ってこない。これはまた、実現不能な選択肢であることも多い。開発途上国のことを考えてみるとよい。ついでに、ほぼすべての地域で広帯域

プロヴァイダは寡占状態にある、という事実についても考えてみるとよい。 このような傾向が、こういったグループを信頼すべきかどうかという問題の鍵を握ると、私は思う。賭けてもよいが、 不要メールを排除するには、より良く、より的確な方法がある。9http://www.ietf.org/rfc/rfc2821.txt

10http://www.ietf.org/internet-drafts/draft-crocker-email-arch-04.txt11[訳注] 翻訳の時点では新版に更新されていたので、原文の URLを修正した。12http://www.ietf.org/rfc/rfc2821.txt

4

Page 17: Spam Filtering for MX (ja) / メール交換機でのスパム排除

Table 1.1: 単純な SMTP通信

クライアント サーバ

サーバへの TCP接続を開始する。 SMTPバナー — これは、コード 220 で始まる挨

拶で、 SMTP (か、普通は ESMTP — SMTPのスーパーセット) で話す用意ができたことを示す— を表示する: 220 サーバの.f.q.d.n ESTMP...

ハローコマンドを使って、自己紹介をする。こ

れは HELO (いまや旧式) か EHLO のいずれ

かのコマンドで、後にクライアント自身の完全

修飾ドメイン名 [76]が付く: EHLO クライアントの.f.q.d.n

その挨拶を 250 応答で受け入れる。クライアント

がハローコマンドの拡張版 (EHLO) を使っていれば、サーバにはクライアントが複数行の応答を扱

えると分かるので、通常は、このサーバで使える

機能を示す数行のテキストを送り返す: 250-サーバの.f.q.d.n Hello ... 250-SIZE 52428800

250-8BITMIME 250-PIPELINING 250-STARTTLS

250-AUTH 250 HELP PIPELINING 機能が応答

に示されていれば、クライアントはその時点から、

ひとつひとつのコマンドへの応答を待たずに、い

くつかのコマンドを一度に先行して発行できる。

エンヴェロープ送信者 [76]を指定することにより、新たにメールトランザクションを始める: MAILFROM:<送り手の@アドレス>

250 応答を発行して、送信者を受け付けたことを

示す。

メッセージのエンヴェロープ受信者 [75]を一度に一つずつ列挙する。 次のコマンドを使う: RCPTTO:<受け手の@アドレス>

それぞれのコマンドに応答 (その受信者への配送が受け付けられたか、一時的に失敗しているか、

拒否されたかによって、 2xx、 4xx、 5xx) を発行する。

DATA コマンドを発行して、 メッセージを送る

用意ができたことを示す。

354 で応えて、コマンドをとりあえず受け付けた

ことを示す。

メッセージを伝達する。 メッセージは RFC 2822準拠のヘッダ部 (From:、To:、Subject:、Date:、

Message-ID: のような) で始まる。ヘッダと本体は空行で区切る。クライアントは、 メッセージの

終りに単一のピリオド (”.”) から成る単独の行を送る。

250 で応じて、 メッセージを受け付けたことを示

す。

配送したいメッセージがまだあれば、次の MAIL

FROM: コマンドを発行する。 そうでなければ、

QUIT と言うか、 (まれなケースだが) 単に接続を切る。

切断。

5

Page 18: Spam Filtering for MX (ja) / メール交換機でのスパム排除
Page 19: Spam Filtering for MX (ja) / メール交換機でのスパム排除

第2章 テクニック

概要本章では、リモートホストからの SMTPトランザクションの間に不要メールを取り除く さまざまな

方法を見る。 また、これらのテクニックを用いることによる副作用についても検討してみる。

2.1 SMTPトランザクションの遅延

内部行きの SMTP通信にトランザクションの遅延をはさむことが、 スパムを止めるのにかなり効果的だということが判明している。 これは タール坑法1 (http://www.iks-jena.de/mitarb/lutz/usenet/teergrube.en.html を見てほしい) の素朴な形態である。多くのスパムと、ウィルスが生み出す電子メールのほぼすべてが、大量のメールを極めて短時間で送信

できるように最適化された特殊な SMTPクライアントソフトウェアを使って サーバに直接配送される。このようなクライアントは一般にラットウェア [79]として知られる。この仕事をやり遂げるために、ラットウェアの作者はたいがい近道、というか、RFC 2821 仕様からの若干の 「逸脱」をしようとする。 ラットウェアならではの特徴として、それが名うての短気者であると

いうことがある。 特に、ゆっくり応答するメールサーバに対してそうだ。 サーバが最初の SMTPバナーを示す前に HELO コマンドや EHLO コマンドを発行したり、サーバが PIPELINING 機能をまだ広

告していないのに SMTPコマンドをパイプラインしようとしたりする。ある種のメール転送エージェント [79] (Eximのような) は、このような SMTPプロトコル違反を自動的に同期エラーとして扱い、即座に外部からの接続を切る。このようなMTAを使っていれば、ログファイルにはこの効果によるエントリが多数現れていることだろう。 事実、 最初の SMTPバナーを表示するのに先立って時間のかかる検査 ([DNSによる検査] [8]のような) を実施しているときは、ラットウェアクライアントであればサーバが活動を始めるのを待たないから、このようなエラーが頻繁に起きる (こういうことをするのは、スパムを送信しようとする者だ)。さらに遅延をはさむことも役立つ。例えば、次のようなときに待つようにすることもできる:

• 最初の SMTPバナーを表示する前に、20秒、

• ハロー (EHLO か HELO) の挨拶の後で、20秒、

• MAIL FROM: コマンドの後で、20秒、

• RCPT TO: コマンドの後ごとに、20秒。

20秒という数字はどこから来たのだろうか。なぜ 1分とか数分ではいけないのか。 RFC 2821は、送信側のホスト (クライアント)が SMTP応答ごとに数分は待たなければならないと定めているというのに。 問題は、受信側のホストによっては (特に Exim を使っているものでは)、外部から来るメールの配送の試みへの応答の際に [送信者呼出し確認法] [12]を実行するものがあるという点だ。ユーザがこのようなホストにメールを送ると、ドメインのメール交換機 [79] (MXホスト)に接続して、送信者アドレスを確認するための SMTP通信を始める。 このような[送信者呼出し確認法] [12]の既定のタイムアウトは、30秒である— この長さまで遅延をはさむと、相手の送信者呼出し確認法が失敗してしまい、次に、ユーザからの元々

1[訳注] teergrubing —ドイツ語 Teergrube (タール坑) より。 tarpitting — 英語 tarpit (同意) より — と表記している文献もある。

7

Page 20: Spam Filtering for MX (ja) / メール交換機でのスパム排除

のメール配送が拒否されるおそれがある (普通は一時的な失敗なので、メッセージの配送を 5日くらい再試行することになり、 メールは最後には送信者に返送される)。言い替えると、20秒というのは、真っ当なメールの配送を妨げることなく足留めしておけるほぼぎりぎ

りの長さなのだ。

このような遅延をすべての SMTPトランザクションにはさみたくないときは (サイトが非常に多忙で計算機の資源が少ない、といったときだね)、「選択的な」トランザクションの遅延にすることもできる。この場合は、次のようなときに遅延をはさむ:

• 相手の DNS情報に問題があるとき ([DNSによる検査] [8] を見てほしい)。

• SMTPトランザクションの間に何か問題の徴候が見つかったら、その後に ([SMTPでの検査] [10]を見てほしい)。

• DNSゾーン中のMXホストのうち、番号の一番大きいもの、つまり、最も優先度の低いメール交換機だけで。よくあることだが、ラットウェア [79]はこういうホストを特に狙う。 真っ当なMTAであればまず、より番号の小さいMXホストを使おうとする。

実際は、選択的なトランザクションの遅延は、以下の節で議論するあまり決定的でないいくつかの検査と

併用するのに いい方法かもしれない。 例えば、SPEWSブラックリストの結果を見て即座にメールを 拒否したくはないだろうが、その結果がやっかいごとの徴候をはっきり示していれば、トランザクションの

遅延をはさんでみてもよいだろう。そうしたとしても、真っ当なメール配送であれば、わずかに遅延を余

儀なくされるほかは影響を受けない。

逆に、スパム送信の決定的な証拠 (例えば[SMTPでの検査] [10]での方法によるもの)が見つかり、サーバに余裕があれば、最終的に配送を拒否する前に、より長い遅延 (例えば 15分くらい) をはさむこともできる 2。スパム送信者は、DNSブラックリストや他の協調型ネットワーク検査に追いつかれるまでに できるだけ多くの人々を探索しようとする。 SMTPトランザクションの遅延はその歩みをほんのわずか遅めるが、それ以外にはたいして得になることはない。 いわば、純粋な利他の行ないだね。:-)私自身の場合、選択的なトランザクションの遅延と SMTP同期エラーとで、 外部からの配送の試みの

50%近くを拒否できている。これは大雑把に言い替えると、外部から来る不要メールの 50%近くは SMTPトランザクションの遅延だけで止められる、ということだ。

スパム送信者が適応してきたら...も見てほしい。

2.2 DNSによる検査

SMTPコマンドがまだ発行されていないうちでも、特定の相手の整合性の指標をいくつかドメインネームシステム [77] (DNS)から拾いあげることができる。特に、さまざまな DNSによるブラックリストを使えば、特定の IPアドレスがある基準を満足したり基準からはずれていたりするかどうかが分かる。 簡単な正引き/逆引き (DNS/rDNS) の検索結果を比べるだけでも、ホストの一般的な整合性のおおまかな指標になる。

さらに、SMTP通信の間に示されるさまざまなデータ (ハロー挨拶で表示する名前のような)も、利用できるようになればすぐ DNSでの検証にかけることができる。こういったデータについての議論は 下の[SMTPでの検査] [10]についての節を見てほしい。しかし、気をつけなければならないことがある。 DNSによる検査はいつも決定的なものではない (例えば、必要な DNS サーバが応答しないこともある)し、いつもスパムかどうかを言明するものでもない。さらに、非常に多忙なサイトでは これはメッセージの処理時間の面で高くつくかもしれない。とはいえこの

検査では、ログに記録するのが目的のときやより全般的な整合性検査の一部にするようなときには、有用

な情報を得ることができる。2外部から来る SMTP 配送を保持している間は、 サーバの TCPソケットやメモリなどのサーバ資源も保持しているのだという

ことに気をつけよう。 一般に多忙なサーバで SMTPトランザクションの遅延をはさむと、サービス不能攻撃に対する脆弱さを増すことになる。 より「スケーラブル」な選択肢も考えられる。 送信者がラットウェアクライアントであるという決定的な証拠をつかんだら すぐに接続を切る、というものだ。

8

Page 21: Spam Filtering for MX (ja) / メール交換機でのスパム排除

2.2.1 DNSによるブラックリスト

DNSによるブラックリスト (DNSbl、かつては元々のブラックリスト ”mail-abuse.org”にちなんで ”Real-time Black-hole Lists” と言った)は、トランザクションの時点でのスパムの阻止を実施するための、おそらくもっとも一般的な方法になった。 受信側のサーバは、相手の IPアドレスに対してさまざまな DNSblゾーン (”dnsbl.sorbs.net”、”opm.blitzed.org”、 ”lists.dsbl.org”、等のような) の中での DNS逆引きを実施する。 一致する DNSレコードが見つかったときの典型的な動作は、 メール配送を拒否するというものだ3。

DNSアドレス (”A”レコード )に加えて、エントリの ”TXT”レコードも検索すれば、典型的にはリスト登録についての 1行の説明を受け取ることができ、 SMTPの拒否応答に含めるのに役立つ。 試してみるには、ほとんどの Linux システムや UNIX システムで提供される ”host” コマンドが使える:

host -t txt 2.0.0.127.dnsbl.sorbs.net

現在、こういうリストが何百もあり、それぞれのリストに入れる基準は異なっていて、 リスト登録/削除の方針も異なっている。一部のリストでは、ひとつの DNSblで複数のリスト登録基準を併用していて、与えられたアドレスがどの基準に触れるかによって DNS逆引き応答で異なるデータを発行する。例えば、sbl-xbl.spamhaus.org に対する DNS逆引きでは SpamHaus のスタッフがスパム送信者とそのプロヴァイダに直接属していると考える IPアドレスには 127.0.0.2 を返し、ゾンビホスト [77]には 127.0.0.4 を、開放型プロキシ [76]サーバには 127.0.0.6 を返す。残念なことに、こういうリストの多くが、申し立てられた違反に直接責任のないより広範囲の IPアドレスブロックを登録したり、 リスト登録/削除の方針を明確にしていなかったり、アドレスの登録について誤った情報を公告していたりする4。このようなリストを鵜呑みにすると、巻き添え被害 [78] (巻き添えスパム [78]と混同しないように) と呼ばれるものを大量に生み出すことがしばしばある。このため、多くの管理者が、 DNSによるブラックリストから肯定的な応答を一つだけ受け取ったことに基づいて 即座に拒否応答をするより、こういうリストをより微妙なやりかたで使うことを好む。複数のリ

ストを参考にして、肯定的な応答ごとに ”得点” をつける。与えられた IPアドレスの得点の合計が決まった閾値に達すると、そのアドレスからの配送を拒否する。これが、SpamAssassin ([スパム検出ソフトウェア] [21]) のような排除ソフトウェアで DNSブラックリストを使うときのやりかたである。また、このようなリストを外部からの接続での SMTPトランザクションの遅延 (別名 ”タール坑法”) を使うきっかけにすることもできよう。 あるホストがある DNSblに登録されていたら、 自分のサーバでは相手が発行する SMTPコマンドごとに応答に遅延を、そう、たとえば、20秒入れる。他のいくつかの基準もこのような遅延のきっかけに使える — [SMTPトランザクションの遅延] [7]についての節を見てほしい。

2.2.2 DNSによる整合性検査

DNSの別の使いかたとして、相手の IPアドレスの逆引きを実施してから結果の名前を正引きする、というものがある。 結果が元の IPアドレスを含んでいれば、 そのホストの DNS整合性が検証できたことになる。 そうでなければ、接続してきているホストの DNS情報は有効なものではない。この基準に基づいてメールを拒否してもかまわない場合があるとすれば、 自分が DNS治安部隊の戦闘的な隊員であり、受入用MXを自分の個人的なドメイン用にだけ設置していて、たとえ真っ当なメールで

3目的の異なる類似のリストが存在する。例えば、「bondedsender.org」は DNSによるホワイトリスト (DNSwl) で、「信頼できる」 IPアドレスを含んでいる。このアドレスの持ち主は保証金を積んでおり、そのアドレスからスパムが発生することがあれば、保証金は没収される。 他にも、特定の国や ISPなどが使う IPアドレスを含むリストがある。

4例えば、いまこれを書いているときにも、 世界最大のインターネットサービスプロヴァイダ (ISP) である comcast.net の送出用メール交換機 (「スマートホスト」)が、 SPEWS の Level 1 リストに登録されている。これは、Comcastが自身の定めた AUP[訳注: Acceptable Use Policy。 ユーザのネットワーク利用に対して、利用目的に制限を加える規則] をより厳格に適用すべきであるという観点からすれば、 全面的に不当なものとは言えない。が、リストへの登録は、米国の全インターネット ユーザの 30% (ほとんどが私のような 「無辜の」 契約者) に影響を与えているのだ。さらにひどいのは、SPEWS FAQ http://spews.org/faq.html で公表されている案内が、こう表明していることだ: Level 1 リ

ストの大多数は、スパム送信者か、 彼らのスパム行為を幇助する機関が有するネットブロックで、 他に真っ当な顧客がほとんど、またはまったく見つからなかったものである。 形式的には、この案内は (a) Comcast を 「スパム幇助機関」とみなし、(b)「他に」という語に注意を払えば、正確である。だが語釈としてはそうでも、この案内は明らかに誤っている。

9

Page 22: Spam Filtering for MX (ja) / メール交換機でのスパム排除

も拒否すれば送信者のほうがシステム管理者に DNSレコードの整頓を頼まなければならないと実感してくれるからかまわない、というときだけだろう。 そうでないのなら、DNSによる整合性検査の結果はおそらく、より大きなヒューリスティックの中のデータのひとつとしてだけ使うべきだろう。その代わりに上

記のように、 設定がおかしいホストには SMTPトランザクションの遅延を使うというのは 悪くない考えだろう。

2.3 SMTPでの検査

SMTP通信が始まってからも、リモートホストが示すコマンドや引数についてのさまざまな検査を実施できる。 例えば、ハロー挨拶で示す名前が有効かどうかを確認するとよいかもしれない。

ただし、SMTPトランザクションの初期のうちに配送の試みを拒否すると決まったときでも、実際にはすぐに拒否を実施しないほうがよいかもしれない。かわりに、RCPT TO: の後の SMTPトランザクションの遅延で 送信者を足留めし、それからそのメールを拒否するほうがよい。

そのわけは、ラットウェアのの中には SMTPトランザクションの初期に拒否されても気づかないものがあるためだ — それでも送信を続けようとする。いっぼう RCPT TO:が失敗すると、たいていは諦める。

それはともかく、これは小規模なタール坑法を 実行するのにはよい機会だ。

2.3.1 ハロー (HELO/EHLO) の検査

RFC 2821によれば、クライアントが最初に発行する SMTPコマンドは EHLO (あるいは対応していなければ HELO)でなければならず、これには そのクライアントのプライマリ完全修飾ドメイン名 [76]が続かなければならない。 これをハロー挨拶と言う。意味のある FQDNが使えないときは、 クライアントは自分の IPアドレスを角括弧で囲んだものを使える: ”[1.2.3.4]”。後のほうの形式を、IPv4アドレス ”リテラル” 表記と言う。至極当然なことだが、ラットウェア [79]がハロー挨拶で自分自身の FQDNを表示することはまずない。むしろ、ラットウェアからの挨拶では普通、送信側のホストの素性を隠そうとしたり、困惑させ誤解させ

るような ”Received:” 経路を メッセージヘッダに入れようとしたりする。このような挨拶の例をいくつか挙げる:

• 非修飾名 (つまり、ピリオドのない名前)。 受信者アドレスの「ローカル部」 (ユーザ名) など。

• 裸の IPアドレス (つまり、IPリテラルではない) — 普通はサーバのアドレスだが、でたらめなもの

もある。

• サーバのドメイン名、あるいはサーバの FQDN.

• 第三者のドメイン名。 yahoo.com や hotmail.com など。

• 存在しないドメイン名、あるいは存在しないネームサーバのドメイン名。

• 挨拶をまったくしない。

2.3.1.1 HELO/EHLOの簡易な構文検査

これらの RFC 2821 違反のいくつかは、容易に検査でき、送信側のホストがある種のラットウェア [79]を 実行していることの明白なしるしにもなる。このような挨拶は拒否してよい — すぐにでもよいし、例

えば RCPT TO: コマンドのあとでもよい。

10

Page 23: Spam Filtering for MX (ja) / メール交換機でのスパム排除

まず、ハロー挨拶に裸の IPアドレスがあったら、遠慮なく拒否しよう。 たとえあなたが RFC 2821 で定め、推奨し、 示唆するようなものはなんでも気前よく受け付けたいのだとしても、 IPアドレスを名前の代わりにするときは角括弧で囲まなければならないのだ5。

特に、あなたの IPアドレスで — またはあなたのホスト名で — 自分を紹介するようなホストには、強

い調子の拒否メッセージを発行してもいいだろう。嘘をついていることは明らかだ。この送信者の挨拶へ

の応答では、桁外れに長い SMTPトランザクションの遅延で足どめしておくのもいいだろう — そう、数

時間くらい。

ちなみに私の経験では、インターネット上の真っ当なサイトなら、他のインターネットサイトに自分を示

すときに IPアドレスリテラル ([x.y.z.w] 表記) を使うことはない。 そんなことをすべきでもない — イン

ターネット上で直接メールを送信しているホストはすべて、自身の有効な完全修飾ドメイン名 [76]を使うべきだ。 私が見かける IPリテラルは、私のローカルエリアネットワークで、私のサーバを送出用 SMTPサーバ (スマートホスト) に使うように設定してある メール利用者エージェント (Ximian Evolution のような)が使っているものだけだ。 事実、私は自分の LANから来るリテラルしか受け付けない。非修飾ホスト名 (ピリオドのないホスト名)は、拒否したほうがいいかもしれないし、しないほうがいい

かもしれない。これが真っ当なホストであることはまずない (が、まったくないのではない — 否定の否定

でわかりにくいな)6。同様に、無効な文字を含むホスト名も拒否できる。 インターネットのドメインには、英数字とハイフン

だけが有効な文字である — ハイフンは最初の文字にはできない (アンダースコアも有効な文字とすることを検討したほういいかもしれない。 なぜなら、これは設定は間違っているが悪意の全然ない Windowsクライアントで、とてもよく見かけるからだ)。最後に、始めにハロー挨拶を受け取っていないのに MAIL FROM:コマンドを受け取ったとき。そう。

礼儀をわきまえている人なら、まず挨拶するものだ。

私のサーバでは、上のいずれかの構文検査で失敗した挨拶は拒否する。しかし、拒否は RCPT TO:コ

マンドの後まで行なわない。 この間、 それぞれの SMTPコマンド (HELO/EHLO, MAIL FROM:,RCPT TO:) の後に 20秒のトランザクションの遅延をはさむ。

2.3.1.2 ハロー挨拶を DNSで確認する

ホストは、少なくとも見た目にはもっともらしい挨拶を示してきた。では今度は、与えられた名前をDNSで確認しよう。 次のようにすればできる:

• 与えられた名前の正引きを実施し、結果を相手の IPアドレスと照合する。

• 相手の IPアドレスの逆引きを実施し、挨拶で与えられた名前と照合する。

この 2つの検査のどちらかが成功すれば、その名前は確認できたことにする。MTAに、この検査を実施する組み込みのオプションがあるかもしれない。例えば、Exim (付録A [29]を

見てほしい)では、 ”helo try verify hosts = *”を設定し、 ”verify = helo” 条件に基づいて動作する ACLを作成するとよいかもしれない。

この検査は、処理時間とネットワーク資源の面で、簡易な構文検査よりは少し高くつく。それだけでな

く、構文検査とちがい、照合ができなかったことがいつもラットウェアのしるしになるわけではない — い

くつかの大規模なインターネットサイト (hotmail.com, yahoo.com, amazon.com のような) は頻繁に、確認できないハロー挨拶を示す。

5この検査は通常は、ゴミを取り除くのにとても効果があるのだが、 L-Soft listserv http://www.lsoft.com/products/

default.asp?item=listserv のインストレーションにはバグがあるものがあって、 リストサーバの裸の IP アドレスで挨拶する、との報告がある。

6[訳注] 同様のものとして、 インターネット上に存在しない最上位ドメインをもつ「FQDN」が、たまに見受けられる。例えばsmtp.example.local のようなもの。これは、非修飾ホスト名の場合と同様な原因で発生すると考えられる。つまり、ラットウェアが身許を隠そうとしているか 真っ当

なメールを送ろうとしている送信側ホストだが MTAが適切に設定されていないか、のいずれかである。 後者はまずない (が、まったくないとは言い切れない)。 いずれにせよ、拒否したければしてよい。

2005 年 6 月現在、インターネット上で有効な最上位ドメイン名は、 2 文字の英字による国コード最上位ドメイン名 (ccTLD) と、その他の 14 種の最上位ドメイン名 (arpa はハロー挨拶には使わないので、この数には含めていない) である。

11

Page 24: Spam Filtering for MX (ja) / メール交換機でのスパム排除

私のサーバでは、先立つ検査に基づいて送信者をトランザクションの遅延で足留めしていないときだけ、

ハロー挨拶の DNS検証をする。そして、この検査が失敗したら、 そこから後の SMTPコマンドごとに20秒の遅延をはさんでいる。 また、「X-HELO-Warning:」 ヘッダを用意して 後でメッセージに付加し、SpamAssassinの得点を引き上げることで、メッセージデータを受信した後の拒否が起こりやすくしている。

2.3.2 送信者アドレスの検査

クライアントが MAIL FROM: <アドレス> コマンドを示した後では、与えられるエンヴェロープ送

信者 [76]アドレスを次のようにして検証できる7:

2.3.2.1 送信者アドレスの構文検査

与えられたアドレスは <ローカル部@ドメイン> の形式になっているか。ドメインの部分は、構文的に

有効な完全修飾ドメイン名 [76]か。この検査は、MTAの既定動作として実施されるようになっていることも多い。

2.3.2.2 詐称の検査

ユーザが外部へ行くメールすべてをごく限られたサーバからしか送信していない場合、送信者アドレス

の「ドメイン」が自分自身のものであるメッセージが 他のホストから来たら、拒否してよい。

この検査のより一般的な代替策が、 [Sender Policy Framework] [17]である。

2.3.2.3 送信者アドレスの簡易な検証法

アドレスがローカルのものであるとき、「ローカル部」 (@ 記号の前の部分) は、システムにある有効なメールボックスか。

アドレスがリモートのものであるとき、「ドメイン部」 (@ 記号の後の部分) は、存在するドメインか。

2.3.2.4 送信者呼出し確認法

Exim や Postfix のようないくつかのMTAで提案されている。 リモートの送信者アドレスの「ローカル部」を確認する機構である。 Postfix の用語では「送信者アドレス検証」と言う8。

サーバは、 送信者アドレスから与えられるドメインの MXと接触し、このアドレスにメールを配送するかのような 第二の SMTPトランザクションを開始しようと試みる。 ここでは、実際にはメールはなにも送信しない — 代わりに、 リモートホストが RCPT TO: コマンドを受け入れるか拒否するかすると、

サーバは QUIT を送信する。

Exim は、既定ではこの呼出し確認で空のエンヴェロープ送信者アドレスを使う。 そのため、この送信者に配送状況通知 [78]を返信したときに 受け付けられるかどうかを確認できる。いっぼう Postfix では、アドレスの確認に使う送信者アドレスは既定では <postmaster@ドメイン> と

なる (ドメイン は $myorigin 変数からとる)。このため、この送信者アドレスを空のエンヴェロープ送信者を扱うのと同じように扱うべきだろう (例えば、[SMTPトランザクションの遅延] [7]や[グレーリスト法][15]を行なわないようにするが、 受信者アドレスには[エンヴェロープ送信者のシグネチャ] [22]が必要なようにする)。これについては、付録の実装でさらに触れる。

7特別な場合として、空のエンヴェロープ送信者アドレス (つまり MAIL FROM: <>)がある。これは、配送状況通知 [78]その他の自動的に生成される応答に使う。 このアドレスは、いつも受け付けなければいけない。

8[訳注] Postfix 2.1 以降で使える。 Postfix でのこの機構については Postfix アドレス検証 Howto http://

www.kobitosan.net/postfix/trans-2.1/jhtml/ADDRESS VERIFICATION README.html (原 文 http://www.postfix.org/

ADDRESS VERIFICATION README.html) を参照。

12

Page 25: Spam Filtering for MX (ja) / メール交換機でのスパム排除

この検査だけでは、外部から来るメールの拒否のきっかけにならないこともあるだろう。真っ当なメー

ル (定期的な支払明細のような)を自動化されたサービスで送信するときなどに 無効な返信アドレスを使っていることがある9。また、 スパムの残念な副作用であるが、 外部へ行くメールの返信アドレスを隠そう

とするユーザもいる (しかし、この影響はエンヴェロープ送信者 [76]よりもメッセージの「From:」ヘッダに現れることのほうが多い)。さらに、この検査ではアドレスが有効であることを確認できるだけで、それが特定のメッセージの送り

手であることを請け合うものではない (が、[エンヴェロープ送信者のシグネチャ] [22]も見てほしい)。最後に、「aol.com」のようなサイトでは、送信者呼出し要求をしているシステムはなんでも機械的に

ブラックリストに入れてしまう、との報告がある。このようなサイトはたびたびなりすましメール [78]の犠牲者となっており、 その結果、土砂降りのような送信者呼出し要求を浴びている。 このような DDoS(分散型サービス不能) 攻撃に加わる者は、実質的にスパム送信者の手先になってしまう10。

2.3.3 受信者アドレスの検査

こんなことは単純なことだと思うだろう。受信者アドレスが有効な場合は、メールを配送する。無効な

場合は、既定では MTAで拒否するように気をつける。でも、ちょっと考えてみよう。いいかな。

2.3.3.1 開放型リレーの防止

メールはリモートホストからリモートアドレスへリレーしてはいけない! (送信者が認証されていない限り)。多くの人は分かりきったことだと思っているだろうが、 実はこれはしょっちゅう見過ごされていること

なのだ。それに、電子メールアドレスや配送経路に関わるインターネットのさまざまな標準を、すべての

ひとが完全に理解しているわけではないようだ (「パーセント書き換えをするドメイン」、「バング (!) 経路」、なども検討しよう)。自分のMTAが開放型リレー [76]になっていないかどうかがはっきりしないときは、「relay-test.mail-

abuse.org」でテストできる。 自分のサーバのシェルプロンプトで、次のようにタイプする:

telnet relay-test.mail-abuse.org

これは、リモートの電子メールアドレスや 上で述べたようなアドレスの「ハック」へ SMTPサーバがメールを転送してしまわないかどうかを、さまざまなテストで調べてくれるサービスだ。

自分のサーバが開放型リレーになるのを防止することは、極めて重要だ。開放型リレーのサーバがスパ

ム送信者に見つかってしまうと、たちまち数多の DNSによるブラックリストに登録されてしまう。 他のいくつかの DNSによるブラックリストのメンテナに見つかってしまうと (メンテナが自分で調べることもあるし、苦情を聞いて見つけることもある)、相当長い期間登録されることになる。

2.3.3.2 受信者アドレスの確認

これも、自明なことのように思えるかもしれないが、かならずしもそうではない。

ユーザのメールアカウントやメールボックスが受入用メール交換機に格納されるのなら、単に受信者ア

ドレスの「ローカル部」が有効なメールボックスにあたるかどうかを検査すればよい。これは問題ない。

受信者アドレスの確認が面倒になるような筋書きは、2つある:

• その計算機が、受信者のドメインのバックアップ MXである。9[訳注] また、MTAによっては、 RCPT TO: コマンドの引数が自ドメインのアドレスであれば それが実在しようがしまいが

受け付けるものもある。 こういうサイトのアドレスを検査するのは、無駄なことである。 以上のような理由から、 検査をよく詐称されるドメインのアドレスだけに限定するとよいかもしれない。

10[訳注] 多くの送信者呼出し確認法の実装では、確認結果をキャッシュすることができるので 確認の頻度を減らせる。使っているMTAの文書を参照してほしい。

13

Page 26: Spam Filtering for MX (ja) / メール交換機でのスパム排除

• その計算機が、自分のドメインへのメールを全て他の (たぶん内部の) サーバへ転送している。

このような場合は、受信者アドレスの確認をすることなく、それぞれのドメインの受信者アドレスを全て

受け付けてしまう。そうすると、その後目的地のサーバで受信者アドレスが無効と分かったときに、その

アドレスについての配送状況通知 [78]を生成せざるをえない。つまるところ、これは巻き添えスパムを発生させてしまうことになる。

このことを念頭に置きながら、上に挙げた筋書きでどうやって受信者を確認したらよいかを見ていこう。

受信者呼出し確認法

Exim や Postfix のようないくつかのMTAで提案されている。 リモートの受信者アドレスの「ローカル部」を確認する機構である (これがどうやって動くかの説明は[送信者呼出し確認法] [12]を見てほしい)。Postfix の用語では「受信者アドレス検証」と言う11。

この場合、サーバは相手からの RCPT TO: を受け入れる前に、 最終宛先ホストに接触してそれぞれ

の受信者アドレスを検証する。 それから、相手からの RCPT TO: コマンドを受け入れる。

この解決策は、簡易でエレガントなものだ。これは最終宛先ホストで動作しているMTAがどんなものでも動くだろうし、なにか特別なディレクトリサービスなどにアクセスする必要もない。そのうえこの検査

は、そのMTAが受信者アドレスを正確に照合できなくても (Lotus Domino サーバの場合がそうだ)、 受信者アドレスがいつか受け入れられるものかそうでないかを正確に反映する — 後で述べるように、そうで

はない場合もあるにはあるが。

受信者呼出しでは、元のエンヴェロープ送信者 [76]を手付かずで渡すようにする。そうしないと、宛先ホストからの応答が正確でなくなるかもしれない。例えば、システムユーザやエイリアスへのバウンス (エンヴェロープ送信者のないメール)は、[実在するユーザへのバウンスだけを受け付ける] [24]で述べるとおり、拒否されるかもしれない。

主要なMTAのうちでは、Exim と Postfixがこの機構に対応している。

ディレクトリサービス

別の良い解決策は、MTAがディレクトリサービス (例えば 1つまたはそれ以上の LDAP サーバ)に問い合わせられるようにしておくことだろう。多くの一般的なMTAはすべて LDAP、NIS、その他さまざまなバックエンドに対応していて、これらは主にユーザアカウント情報を提供するのに使われている。

しかし、難点がある。電子メールの最終宛先ホストでユーザ名をメールボックスに対応づけるのに ディ

レクトリサービスを使っていないときは、設定するのにかなりの作業が必要になるのだ。

メールボックス一覧を複製する

上の選択肢がいずれも実現不可能なら、「貧者のディレクトリサービス」に頼ることもできる。 メー

ルボックスが置かれている計算機から MXホストへ、 現在のメールボックスの一覧を定期的に複写する。そしてMTAでは、このリストを見て外部から来るメールの RCPT TO: コマンドを検証する。

メールボックスを持つ計算機が UNIX や Linux の類で動いているのなら、 まず、こういう一覧を (たぶん、 ローカルの 「/etc/passwd」 ファイルから) 生成してそれを OpenSSH12スイートに 入っている

「scp」 コマンドで MXホストに複写する スクリプトを書く。 つぎに、「cron」ジョブを設定 (詳しくはman cron とタイプしよう)して、このスクリプトを定期的に実行する。

2.3.3.3 辞書攻撃の防止

辞書攻撃とは、送信側のホストが一般的な名前 (アルファベット順に「aaron」から始まることが多いが、アルファベットのもっと後ろのほうから始まったり、でたらめな順序だったりすることもある) に基

11[訳注] Postfix 2.1 以降で使える。 Postfix でのこの機構については Postfix アドレス検証 Howto http://

www.kobitosan.net/postfix/trans-2.1/jhtml/ADDRESS VERIFICATION README.html (原 文 http://www.postfix.org/

ADDRESS VERIFICATION README.html) を参照。12http://www.openssh.org/

14

Page 27: Spam Filtering for MX (ja) / メール交換機でのスパム排除

づいて RCPT TO: コマンドを発行し続け、ありそうな受信者アドレスを探る SMTPトランザクションのことを指す用語だ。サーバが特定のアドレスを受け付けると、そのアドレスはスパム送信者の武器庫に

加えられる。

サイトによっては、特に大きいところほど、たびたびこのような攻撃の標的になっている。スパム送信

者から見れば、ごくわずかのユーザしかいないサイトより 大規模なサイトのほうがある名前が見つかる機

会が増えるからだ。

辞書攻撃と闘う効果的な方法のひとつに、アドレスが失敗するにつれてトランザクションの遅延を増大

させていく、というものがある。例えば、最初の存在しない受信者アドレスを拒否したら 20秒の遅延、つぎのアドレスでは 30秒の遅延、といったふうにできる。

2.3.3.4 受信者が一つのDSNだけを受け付ける

真っ当な配送状況通知 [78]なら、一つの受信者アドレス — 通知のきっかけとなった元のメッセージの

送信者 —だけに送られるはずだ。エンヴェロープ送信者 [76]アドレスが空なのに複数の受信者があれば、接続を切ってよい。

2.4 グレーリスト法

グレーリスト法13の概念は、Evan Harrisの白書で提示されている: http://projects.puremagic.com/greylisting/。

2.4.1 どのように動作するか

[SMTPトランザクションの遅延] [7]に似て、グレーリスト法は単純だが、 ラットウェア [79]を介して配送されてくるメッセージを極めて効果的に取り除ける機構である。考え方は、 メッセージの送り手と受

け手の間に以前も結びつきが存在していたかどうかを確認する、というものだ。多くの真っ当なメールは

そう確認でき、配送は正常に進む。

いっぼう、以前に結びつきが存在しなければ、配送を一時的に (451 SMTP応答で) 拒否する。 真っ当な MTAであればこの応答を適切に扱い、 すこし後に配送を再試行する14。いっぽうラットウェアは、す

ぐに配送の試みを繰り返すか、あるいは簡単に諦めてしまってアドレスリストのつぎのアドレスに照準を

移す。

配送の試みから 3点の情報を取り出す。これを三つ組と呼び、送り手と受け手の間の関連を一意に識別するのに使う:

• エンヴェロープ送信者 [76]。

• 送信側のホストの IPアドレス。

• エンヴェロープ受信者 [75]。

配送の試みを一時的に拒否したときに、この三つ組をキャッシュする。これをまずグレーリストに入れる。

決められた時間 (1時間としよう)が経った後に 新たに配送の試みがあれば受け付け、三つ組をホワイトリストへ移す。 ただし、決められた期限切れ (4時間としよう) までに新たな配送の試みがなければ、 三つ組をキャッシュから消す。

ホワイトリストに入った三つ組がさらに長い期間 (月次の支払明細のようなものを考慮して、最低でも1ヶ月) 現れなかったときは、消す。これで、リストが無制限に膨らむのを防げる。

13[訳注] greylisting。14まれなことだが、「真っ当な」バルクメール送信者 (groups.yahoo.com のような) の中には、 一時的に失敗した配送を再試行

しないものもある。 Evan Harris がこういう送信者の一覧をまとめているので、 この方式の適用外にする目的に使える: http://

cvs.puremagic.com/viewcvs/greylisting/schema/whitelist ip.txt?view=markup。

15

Page 28: Spam Filtering for MX (ja) / メール交換機でのスパム排除

この 3種の期限切れは Evan Harris の元々のグレーリスト法白書 (いや、「灰書」と言うべきかな)から取った。ある人によれば、グレーリストに入れた三つ組を消すまでの期限切れを もっと長くする必要があ

り得る。なぜなら ISPによっては (たとえば earthlink.net)、配送の再試行を 6時間くらいごとにしかしないからだ1516。

2.4.2 複数のメール交換機でのグレーリスト法

複数の受入用メール交換機を運用していて、それぞれの交換機が別々のグレーリスト法キャッシュを持っ

ているとする。すると:

• 理論上は、ある送信者からユーザへの初回の配送は 最初の 1時間の遅延の N 倍だけ遅れることにな

る。 N はメール交換機の数である。 理由は、メッセージの再送は 始めの配送で 451 応答したサー

バとは 別のサーバに対して起こりやすいためだ。 最悪の場合、送信者ホストが最初の交換機へ配送

を再試行しに戻ってくるまでに 4時間では間に合わなかったり、グレーリストに入った三つ組が消えてからになったりする。 このため、配送の試みは幾度も繰り返し拒否されることになり、 送信者

ホストが諦めるまで続く (普通は 4日くらいかかる)。

実際問題、これは好ましくない。送信者ホストは通常、 配送の試みが一時的に失敗したら即座に別

のMXを使って配送を再試行する。だから、1時間後にはどのMXホストでもメッセージを受け入れるべきだ。

• 三つ組が MXのどれか一つでホワイトリストに入った後でも、 同じ三つ組の別のメッセージが別のMXに配送されると、そこではグレーリストに入ってしまう。

このような理由から、受入用メール交換機同士でグレーリストに入る三つ組のデータベースを共有できる

ように実装すべきだろう。しかし、このデータベースを持っている計算機が唯一の弱点になってしまうの

で、その計算機が落ちてもうまく動作する (例えば、全ての配送を受け付けるようにする、など) ようにしておくべきだろう。あるいは、データベース複製のテクニックを使って、 SMTPサーバが検索のときに替わりの複製サーバを見にいくようにもできるかもしれない。

2.4.3 結果

私自身の経験では、グレーリスト法は 不要メール配送数のおよそ 90% を止めることができる。 もちろん、すでに説明したさまざまな[SMTPでの検査] [10]を 適用した上でのことだ。グレーリスト法を最初の防衛線にすれば、外部から来る不要メールをさらに高い率で捕らえてくれそうだ。

逆に、このテクニックによる偽陽性 [76]は、実質的にゼロである。主要なメール転送エージェント [79]は全て、一時的な失敗の後に配送の再試行を実施する。このため、いつかは配送に成功するのだ。

グレーリスト法の欠点は、真っ当なメールであっても 特定の受信者に対して過去に電子メールを送った

ことのない人からのものなら 1時間の遅延 (複数のMXホストを運用していれば複数時間)を受ける、という点だ。

スパム送信者が適応してきたら... も見てほしい。

15大規模なサイトによくあることだが、外部へ行くメールを複数のサーバで扱っていることがある。例えば、一つあるいはいくつかのサーバだけを即時の配送につかっていることがある。このようなサイトでは、最初の配送の試みが失敗すると メールを大きな待ち行列を扱えるように調整された予備サーバに渡す。このため、このようなサイトから来るメールでは、最初の 2回の配送の試みが失敗することになろう。

16[訳注] 実際のグレーリスト法の実装では、一時的に失敗させる期間をもっと短く (例えば 300秒程度) とっているものが多い。多くの MTAで、 一時的な失敗の後に再送を開始するまでの時間は 1 時間より短く (例えば qmail では 400 秒、Postfix では既定で1000 秒)、 その後は再送の間隔を延ばしていく。 いっぽう、一時的に失敗させる期間をあまり長くすると、 送信者に再試行中であることを知らせる配送状況通知を送る (だいたい数時間後) よう設定されている送信者サイトでは、真っ当な送信者を困惑させるかもしれない。現在存在するグレーリスト法の実装などの情報については、 http://www.greylisting.org/ を参照。グレーリスト法に似ているがより簡易な方式として、 三つ組の代わりにクライアントの IPアドレスだけを用いるお馴染さん方式

http://moin.qmail.jp/ a4 aa c6 eb c0 f7 a4 b5 a4 f3 ca fd bc b0がある。

16

Page 29: Spam Filtering for MX (ja) / メール交換機でのスパム排除

2.5 送信者認証方式

送信者の確認のために、さまざまな方式が開発されている。これらの方式では、送信者アドレスの有効

性だけでなく、信頼性も検査する。 インターネットドメインの持ち主がなんらかの基準を指定すると、送

信者からドメイン内への配送はこの基準による信頼性を満たさなければならなくなる。

この種の方式で、初期に提案されていたものが 2つある:

• MAIL-FROM MXレコード。Paul Vixie <paul a©vix.com>が発案した。

• 逆メール交換機 (RMX) レコード。これは DNS そのものに追加するもので、 Hadmut Danisch<hadmut a©danisch.de>が発案し公表した。

どちらの方式でも、 <ユーザ@ドメイン.com> からのメールは <ドメイン.com> の DNSゾーンに指定してあるホストから来なければいけないことになっていた。

この 2つの方式が発展してきた。だが悲しいかな、またもや分裂してしまうのであった。

2.5.1 Sender Policy Framework (SPF)

「Sender Policy Framework」 (以前は「Sender Permitted From」と言った)は、たぶん最もよく知られた送信者認証の方式だ。これは上で述べた元の方式にいくらか基づいているが、ドメインの持ち主がも

う少し柔軟な基準を公告できるようになっている。

SPF情報は、ドメインの最上位の DNSゾーンで TXTレコードとして公開する。このレコードで次のも

のを指定できる:

• そのドメインからのメールを送ることを認めるホストはどれか。

• そのドメインから外部へ行くメールが GPG (GNU Privacy Guard) 署名を持たねばならないか。

• その他の基準 — 詳しくは: http://spf.pobox.com/ を見てほしい。

TXTレコードの構造はいまでも開発中だが、 上記のことを実現するだけの基本的な仕様はもう固まって

いる。 v=spf1 で始まり、次のような修飾子がその後に続く:

• a —ドメイン自身の IPアドレスが 有効な送信者ホストである。

• mx — そのドメインの受入用メール交換機も 有効な送信者ホストである。

• ptr — 送信側のホストの IPアドレスの DNS逆引きが送信者アドレスのドメイン部分の名前を含めば、有効な送信者ホストである。

それぞれの修飾子の前に、プラス記号 (+)、マイナス記号 (-)、疑問符 (?)、or チルダ (˜)をつけることができる。これはそれぞれ、信頼できる出所、信頼できない出所、中立、信頼できそうにない出所、を示す。

修飾子の後には、コロンとそれに続く代替のドメイン名をつけられる。例えば、Comcast の契約者であれば、自分の DNSゾーンに「-ptr:クライアント.comcast.net ptr:comcast.net」を入れて、外部へ

行くそのドメインの電子メールは なにか.クライアント.comcast.net に解決されるホストから来ることは絶対になく、なにか.comcast.net に解決される別のホストからは来る、ということを示せる。

現在、いくつかの大規模なインターネットドメイン (aol.com、altavista.com、dyndns.org、earthlink.net、google.com のような)が、SPF情報を公開している。送信者認証方式は、一般的にそうだが SPFに限ったとしても、普遍的に受け入れられているわけではな

い。特に、ドメインの持ち主がユーザ/顧客から外部へ行くメールのリレーを容易に独占できてしまう、という批判がある。

別の批判としては、SPF が伝統的な電子メール転送をぶちこわす、というものがある — 転送元ホスト

が、エンヴェロープ送信者のドメインにある SPF情報では 転送できるだけの信頼度を得られないことがあ

17

Page 30: Spam Filtering for MX (ja) / メール交換機でのスパム排除

る。 こういったものの一部は、SRS17 や 送信者書き換え方式で扱える。 これらの方法では、メールの転

送元がエンヴェロープ送信者 [76]アドレスを次の形式に改変する:

ユーザ=出所の.ドメイン@転送元の.ドメイン

2.5.2 Microsoft Caller-ID for E-Mail

SPFと同様、受け入れの基準は送り手のドメインの DNSで TXTレコードによって公告する。しかしMS CIDE の情報は、簡易なキーワードによってではなく、 XMLにエンコードされたまことに巨大な構造体でできている。 その XMLのスキーマは Microsoft の許諾の下に発行されている。

SPFは名前のとおり電子メールのエンヴェロープ送信者 [76]アドレスを検査するのに使うが、いっぼうMS CIDEは主にメッセージ自身の RFC 2822 ヘッダを検証するツールである。そのため、そのような検査ができる最初の時点は、 メッセージデータが配送された後で、最後の 250 応答を発行する前となる。

率直に言って、「仏造って魂入れず」だ。 特許の問題と送信者側での繁雑さがあだになっている。

とはいえ、最近 http://spf.pobox.com/に投稿されている SPFツールは、SPFに加えて MS Caller-ID情報も検査する能力がある。

2.5.3 RMX++

(Simple Caller Authorization Framework — SCAF の一部) この方式は Hadmut Danisch が開発した。彼は、元の RMX の発案者でもある。

RMX++では、HTTPサーバを通じての動的認証もできる。ドメインの持ち主は DNSによってサーバの場所を公表し、 受信側のホストはこのサーバに接触することで 認証レコードを獲得する。 これで発信

者の信頼性を確認する。

この方式では、ドメインの持ち主は (固定的な TXTレコードによる SPF情報のように) ネットワークの構成を一般に知らせることなく、送信者アドレスの認証に使う基準をよりきめ細かく制御できる。例え

ば Hadmutによる例では、あるアドレスからのメッセージをビジネスアワーの後は 1日 5件以内しか受け付けず、上限に達したら警報を発するような認証サーバがある。

しかも、SCAF の用途は電子メールに限られない。他の Voice over IP (VoIP) のようなサービスに呼出し認証機能を与えることもできる。

RMX++の難点はおそらく、Rick Stewart <rick.stewart a©theinternetco.net>が注意しているよ

うに、 計算機資源やネットワーク資源に悪影響を与えることだろう: HTTPサーバからの応答は DNSで情報を直接扱うときほど広範にはキャッシュされないし、 HTTP要求の発行は DNS要求とくらべて著しく高くつく。

Rick はさらに、RMX++ の動的な性格が誤りの発見を困難にすることも指摘している。 上の例のように 1日 5件の上限があるとして、1つのメッセージが 5回検査されてしまうと、 単一のメッセージで上限に達してしまう。このため、メッセージの再検査が不可能になる。

RMX、RMX++、SCAFについてのさらなる情報は、次を参照: http://www.danisch.de/work/security/antispam.html。

2.6 メッセージデータの検査

ようやく、メッセージの内容そのものに目を向けるときがきた。これは従来はスパムやウィルスの検出

ソフトウェアがやっていたことで、通常はメッセージが受け付けられてからの処理だった。しかし我々の

場合は、この検査を最後の 250 応答を発行する 前に実施する。そのため、巻き添えスパム [78]を生成せずにその場でメールを拒否する機会ができる。

17http://spf.pobox.com/srs.html

18

Page 31: Spam Filtering for MX (ja) / メール交換機でのスパム排除

受入用メール交換機が非常に多忙 (つまりサイトは大規模で計算機は少ない) だと、 メール交換機でここに述べる検査の一部または全部を実施することが あまりに高くつくこともあるかもしれない。 とりわ

け[ウィルス検出ソフトウェア] [21]や[スパム検出ソフトウェア] [21]の実行は、CPU帯域と時間を相当食う。もしそうなら、こういう検出作業のために専用の計算機を立ち上げるべきかもしれない。 多くのサーバ

側でのスパム対策やウィルス対策のソフトウェアは、ネットワークごしに (つまりメール交換機から) 実行できる。 以下の章では、この点についてのさまざまなMTAでの実装についても議論する。

2.6.1 ヘッダの検査

2.6.1.1 ヘッダがない

RFC 282218では、メッセージは少なくとも 次のヘッダを含まなければならないと定めている:

From: ...

To: ...

Subject: ...

Message-ID: ...

Date: ...

これらのヘッダのいずれかがなければ、 メッセージは主流のメール利用者エージェント [79]が生成したものではなく、ゴミかもしれないということだ19。

2.6.1.2 ヘッダアドレスの構文検査

メッセージヘッダに現れるアドレス (つまり To:、Cc:、 From: ... といった項目)は、構文的に有効なものでなければならない。これはもう説明しなくてもわかるだろうが。

2.6.1.3 ヘッダアドレスの簡易な検証法

メッセージヘッダにあるアドレスそれぞれについて:

• アドレスがローカルのものであるとき、「ローカル部」 (@ 記号の前の部分) は有効なメールボックスか。

• アドレスがリモートのものであるとき、「ドメイン部」 (@ 記号の後の部分) は存在するドメインか。

2.6.1.4 ヘッダアドレス呼出し確認法

これは[送信者呼出し確認法] [12]や[受信者呼出し確認法] [14]と似た働きをする。ヘッダのアドレスのうちリモートのものについては、そのドメインのプライマリMXを呼び出して 配送状況通知 [78]を受け付けられるかどうか確認する。

2.6.2 不要メールシグネチャ集積システム

18http://www.ietf.org/rfc/rfc2822.txt19一部の特殊化した MTA (ある種のメーリングリストサーバのような) は、「バウンスした」 メッセージ (配送状況通知 [78]) の

Message-ID: ヘッダを自動的には生成しない。 このようなメッセージは、空のエンヴェロープ送信者 [76]で区別がつく。

19

Page 32: Spam Filtering for MX (ja) / メール交換機でのスパム排除

不要メールの特性のひとつに、多数のアドレスに送られるということがある。すでに 50人の受信者があるメッセージをスパムと判定しているときには、その事実を使って、自分にそのメッセージが配送されて

きたときに受け取るかどうかを決めてはどうだろうか。どうせならスパムトラップ [77]を作って、スパムと分かっているものの貯蔵庫に集めてはどうだろうか。

よくぞ聞いてくれました。そういう貯蔵庫は存在することが判明している:

• Razor20

• Pyzor21

• Distributed Checksum Clearinghouse (DCC)22

単純なシグネチャ検査だと、不要メールと分かっているものとまったく同一のメッセージを受け取ったと

きだけ動くが、ここで述べているツールはそれよりも進歩したものだ。それどころか、メッセージのヘッ

ダや本体のわずかな変異があっても、よくあるパターンを見抜く。

2.6.3 バイナリゴミデータの検査

メッセージが印字不可文字を含むことはまれだ。そういうものが見つかったら、メッセージはほぼ確実

にウィルスである。 また、非西洋言語で書かれたスパムで 適切な MIMEエンコードがされていないものの場合もある。

はっきりしている場合がひとつある。それは、メッセージが NUL文字 (序数ゼロ)を含んでいる場合だ。印字不可文字とはどういう意味かをはっきりさせることは なかなかややこしく23、さほど益もないことで

はある。が、この文字についてだけは検査を検討したほうがよい。なぜなら、一部のメール配送エージェ

ント [79] (Cyrus Mail Suite24 のような)では、これを含むメールは拒否してしまうからだ25。このような

ソフトウェアを使っているのなら、 NUL文字をなくすことを必ず検討しなければならない。いっぼう、(いまでは旧式の) RFC 822 仕様では メッセージの NUL文字を明確には禁止していない。こ

のため、この文字を含むメールを拒否するのではなく、 Cyrus にメッセージを配送する前にこの文字を取り除くことも考えられる。

2.6.4 MIMEの検査

同様に、外部から来るメッセージの MIME構造を検証するのも有益だろう。 MIMEのデコードでのエラーや不一致は、それほどしょっちゅう起こるものではない —しかし起こるのなら、メッセージは疑いもなくゴミである。それだけではなく、このようなエラーは [添付ファイルの検査] [20]、[ウィルス検出ソフトウェア] [21]、 [スパム検出ソフトウェア] [21]のようなこの後に続く検査で 問題をひき起こしかねない。言い替えると、MIMEエンコードが不正なら、メッセージは拒否する。

2.6.5 添付ファイルの検査

Windowsスクリーンセーバー (「 .scr」ファイル) や Windowsプログラム情報ファイル (「 .pif」)がどうしても欲しくて、だれかに送ってもらった、などということが、これまでにあっただろうか。

20http://razor.sf.net/21http://pyzor.sf.net/22http://rhyolite.com/anti-spam/dcc/23[訳注] 非西洋言語地域 (日本を除いてほとんどが、 近年になってインターネット利用が盛んになってきた地域でもある) の一部

から来るメールには、本体のテキストに非 ASCII文字を含んでいても base64 や quoted-printable によるエンコードをしないものがしばしば見受けられる。 そのため、非 ASCII 文字であればすなわち印字不可文字とは言えない。ただし MIMEによれば、ヘッダは非 ASCII文字を含む場合にはエンコードしなければならない。したがって、ヘッダに非 ASCII文字を含むものはスパムの可能性が高い。

24http://asg.web.cmu.edu/cyrus/25IMAPプロトコルでは、 NUL 文字をメール利用者エージェントに伝達することを認めていない。 そこで Cyrus の開発者たち

は、それを含むメールは拒否するという、 いちばん簡単な方法をとることにした。

20

Page 33: Spam Filtering for MX (ja) / メール交換機でのスパム排除

「Windows実行ファイル」の添付ファイル — つまり、ファイル名の最後が上に挙げたようなピリオド

とそれに続く 3文字の組合せになっているファイル名 — をもつメッセージの拒否を検討しよう。 この検

査は、[ウィルス検出ソフトウェア] [21]と比べると サーバの資源はずっとわずかしか消費しないし ウィルス検出ソフトウェアにまだシグネチャが存在していないような 新しいウィルスも捕らえることができるか

もしれない。

このような「ファイル名拡張子」のより詳しい一覧は、次を見てほしい: http://support.microsoft.com/?kbid=29049726。

2.6.6 ウィルス検出ソフトウェア

サーバ側でのウィルス検出のためのソフトウェアには、さまざまなものがある。少しだけ名前を挙げる:

• Sophie27

• KAVDaemon28

• ClamAV29

• DrWeb30

ファイル名だけに基づいて危険そうなファイルを阻止しては困る場面 (「 .zip」ファイルをどうするか検討しよう) では、このような検出ソフトウェアは役に立つ。それに、このようなソフトウェアは添付ファイルで伝達されるのではないウィルス (2004年 3月に現れた「Bagle.R」ウィルスのような) も捕らえることができる。

多くの場合、ウィルス検出を実行する計算機がメール交換機である必要はない。こういうウィルス対策

ソフトウェアの多くは、別のホストからネットワーク接続を介して実行できる。

ウィルス対策ソフトウェアは、主に既知のウィルスのシグネチャ (ウィルス定義)に基づいてウィルスを検出している。 新しいウィルスも開発されるため、このシグネチャは常に更新しつづけることが必要だ。

それに、ソフトウェアそのものの正確性を最大限にするためにも、常に最新の状態にしておかなければい

けない。

2.6.7 スパム検出ソフトウェア

同様に、スパム対策ソフトウェアを使えば、 ヒューリスティック (メッセージの内容、標準への準拠、[DNSによるブラックリスト] [9]や[不要メールシグネチャ集積システム] [19]のようなさまざまなネットワーク検査など) の巨大な集合に基づいてメッセージを選別できる。このようなソフトウェアでは典型的には、メッセージごとに総合的な「得点」を決定することになる。これがメッセージのスパムらしさを示し、こ

の得点がある閾値を越えたらメッセージをスパムに選別する。

もっともよく普及しているサーバ側でのヒューリスティックスパム対策ソフトウェアを 2つ挙げる:

• SpamAssassin31

• BrightMail32

このようなツールは、スパム送信者がさまざまな検査を回避する方法を見つけていくにつれ、進化し続

けている。例えば、「GR0W lO 1NCH35」のような「独創的な」つづりなど。そのため、ウィルス対策

26[訳注] 原文の URLは、翻訳の時点ではアクセスできなくなっていたので修正した。27http://www.vanja.com/tools/sophie/28http://www.kapersky.com/29http://clamav.elektrapro.com/30http://www.sald.com/31http://www.spamassassin.org/32http://www.brightmail.com/

21

Page 34: Spam Filtering for MX (ja) / メール交換機でのスパム排除

ソフトウェアと同じことだが、スパム対策ソフトウェアを使うのならば 高度な正確性を得るために頻繁に

アップデートしなければいけない。

私は SpamAssassin を使っているが、計算機資源への影響を少なくするため、これはもはや私の最初の防衛線ではなくなっている。私の個人アドレスには日に約 500件の不要メール配送の試みが来るが、そのうちおよそ 50件が SpamAssassin による検査にかかる (これは主に、私のほかのアカウントから転送されてくるもので、上に述べたような検査が効果を挙げないためだ)。この 50件のメッセージのうち、私の受信フォルダにまで届くメッセージは 2、3日ごとに 1件程度だ。

2.7 巻き添えスパムの阻止

巻き添えスパム [78]は、これまでに述べたテクニックだけでは 阻止が難しい。なぜなら、これは真っ当なサイトから 標準的なメール転送ソフトウェア (Sendmail、Postfix、Exim のような) を使って届くからだ。あるメッセージが自サイトのユーザ自身が送ったメールに応える有効な配送状況通知 [78]であるかどうかを決定することは、取り組みがいのある課題だ。これをする方法をいくつか挙げる:

2.7.1 いんちきウィルス警告を排除する

巻き添えスパムの多くは、ウィルス対策ソフトウェアが生成するウィルス警告である33。だから、こう

いうウィルス警告の Subject: ヘッダの文面やその他の特徴は、ウィルス対策ソフトウェア自身が与えて

いるものだ。そういうわけで、よくある特徴の一覧を作成すれば このようないんちきウィルス警告を排除

できるかもしれない。

いやあ、あなたは運がいい — もうやってくれた人がいる。 :-)Tim Jackson <tim a©timj.co.uk>がいんちきウィルス警告の一覧をメンテナンスしていて、SpamAssassin

で使えるようにしている。ここで手に入る: http://www.timj.co.uk/linux/bogus-virus-warnings.cf。

2.7.2 自分のドメインの SPF情報を公開する

[Sender Policy Framework] [17] の目的は、なりすましメール [78] — つまり、有効な電子メールアドレ

スを騙られること — を厳密に防ぐことである。

自分のドメインの DNSゾーンで SPFレコードを公開すると、 SPF検査を組み込んでいる受信者ホストでは そのドメインのアドレスを詐称したメッセージを受け取らなくなる。そのため、公開したサイトに配

送状況通知 [78]を送ってこなくなる。

2.7.3 エンヴェロープ送信者のシグネチャ

私が現在実験している別のアプローチとして、外部へ行くメールのエンヴェロープ送信者 [76]アドレスのローカル部にシグネチャを追加し、外部からの配送状況通知 [78]を受け付ける前にエンヴェロープ受信者 [75]アドレスにあるこのシグネチャを検査する、というものがある。生成される送信者アドレスは、例えば次のような形式になろう:

ローカル部=シグネチャ@ドメイン

通常のメッセージ返信に影響はない。返信は メッセージの From: や Reply-To: の項目にあるアドレス

へ行く。これらの項目は手つかずのままである。

簡単そうに見えるね。だが残念ながら、この目的に合うようなシグネチャを生成するのは、見た目ほど

簡単なことではない。これを使えるようにする上で、互いに相反するような検討事項がある。

33ウィルス対策ソフトウェアの作者はなにを血迷って、ウィルスを含む電子メールの送信者アドレスを信頼してしまうようなまねをするのか、の解明は、むしろ精神分析学の課題だろう。

22

Page 35: Spam Filtering for MX (ja) / メール交換機でのスパム排除

• この手法が効果をあげるためには、生成したサインつきエンヴェロープ送信者アドレスをスパム送信者が手に入れても、役にたたないようにしなければならない。典型的には、シグネチャに有効期限

をつけられるように タイムスタンプを入れておくことになろう:

送信者=タイムスタンプ=ハッシュ@ドメイン

• [グレーリスト法] [15]を組み込んでいるサイトにメールを送るときは、エンヴェロープ送信者アドレスは特定の受信者に対して一定でなければならない。そうでないと、メールはいつまでもグレーリス

トに入り続ける。

このことを念頭に置くと、エンヴェロープ送信者 [76]をエンヴェロープ受信者 [75]に基づいて生成することも 考えられる:

送信者=受信者=受信者の.ドメイン=ハッシュ@ドメイン

このアドレスには有効期限がないものの、このアドレスに不要メールが送られ始めたら すくなくと

もどこから漏れたのかはわかる — 受信者アドレスに組み込んであるアドレスだ。さらに、同じ受信

者への通常のメール配送に影響を与えることなく、特定の受信者アドレスシグネチャを容易に阻止で

きる。

• メーリングリストサーバでは、さらに 2つの問題が起こる。普通、リクエストメール (「subscribe」/「unsubscribe」のような) への返信はエンヴェロープ送信者なしで送られる。

– 一つめの問題は、 リクエストメールのエンヴェロープ送信者 [76] アドレス に返信するサーバ ( <[email protected]> のような)についてだ。 メーリングリストサーバへのコマンド(subscribeや unsubscribeのような)は、典型的には、リストへのメールに使うアドレスとは別の 一つかそれ以上の異なるアドレス (例えば、それぞれ <[email protected]>

と <[email protected]>) に送られる、という問題がある。 このため、購読者のアドレスは リストそのものに送られたメッセージの送信者アドレスとは — そしてこの

例では、購読停止要求のために生成されるアドレスとも — 異なる。この結果、リストへ投稿し

たり リストを購読停止したりできなくなることがある。

妥協案として、送信者のシグネチャに 受信者のドメインだけを組み込むことにするのもよいか

もしれない。すると送信者アドレスは次のようになる:

購読者名=en.tldp.org=ハッシュ@購読者の.ドメイン

– 二つめの問題は、リクエストメールのメッセージヘッダにある 返信アドレスに返信するサーバ (<[email protected]> のような) についてだ。 このアドレスはサインつきではないので、サーバはリストサーバからの応答を阻止してしまう。

これについてできることはあまりない。そういうやりかたをする特定のサーバを「ホワイトリ

スト」に入れ、サインなしの受信者アドレスへの返信を受け入れるようにするしかない。

ここまで来ると、このアプローチは切れ味が鈍ってくる。 さらに、元々のメールが自分のサーバから送信

されたのではなければ、 それに対する真っ当な DSNも拒否される。したがって、 ユーザが移動 [ローミング] をしない場合、 あるいは逆に、自分で制御できない外部のサーバからユーザがメールを送る場合にだけ、実施を検討するべきだ。

とはいえ、上の検討事項がいずれも当てはまらない状況では、この手法は巻き添えスパムを除去する手

段になるのはもちろん、サイトの管理者に (おそらく意図せず) 巻き添えスパムを発生させていることを教える手段にもなる。 さらに副次効果として、[送信者呼出し確認法] [12]を実行しているサイトでは、元々のメールが実際に自分のサイトから送られているときだけ 肯定応答を受け取ることになる。要するに、ス

パム送信者の送信者アドレス詐称に曝されにくくしていることになる。

23

Page 36: Spam Filtering for MX (ja) / メール交換機でのスパム排除

外部へ行くメールにサインをつけるかどうかを、 ユーザに指定させたいかもしれない。そうであれば、

サインなし版のアドレスへメールを返送することを認めるホストはどれなのかを 指定しなければならない。

例えば、ユーザがメールサーバのシステムアカウントを持っているときは、ユーザのホームディレクトリ

にあるファイルが存在するかやその内容を検査できるだろう。

2.7.4 実在するユーザへのバウンスだけを受け付ける

エンヴェロープ送信者のシグネチャ検査にも抜け穴があって、いんちきバウンスを受け付けてしまうこ

とがある。特に、ユーザがこの方式に自分で加入しなければならないようにしているのなら、 postmaster

や mailer-daemon のような システムエイリアスに送られてくるメールについてはシグネチャを検査する

わけにいかない。そのうえ、こういうアドレスは外部へ行くメールを生成しない。だから、こういうアド

レスではどんなバウンスも受け取ってはいけない。

メールがこのようなシステムエイリアスに送られてきたら、拒否してよい。 または、与えられた受信者

アドレスがメールボックスを持っていなければ拒否する、ということにしてもよい。

24

Page 37: Spam Filtering for MX (ja) / メール交換機でのスパム排除

第3章 検討事項

概要システム全体での SMTPの時点での排除が働くようにする前に、特に検討すべきことがいくつかある。

3.1 複数の受入用メール交換機

多くのドメインが複数の受入用 メール交換機 [79] (別名「MXホスト」) を持っている。そうなっているのなら、効果を挙げるためにプライマリMXで行なっている SMTPの時点での排除はほかのMXでも行なうように 気をつけよう。そうしないと、送信側のホストはバックアップサーバで再送を試みることで

排除をすり抜けられる。

バックアップサーバを自分で制御できないのなら、まず、複数のMXが本当に必要なのか自問してみることだ。 こういう状況では、そのサーバが単に冗長なメールサーバとして働いていて メールをプライマ

リMXに転送しているだけ、という可能性もある。もしそうなら、おそらくそういうものは必要ないだろう。 ホストがときに短時間落ちたとしても、問題はない — 正しく動作する送信者ホストは、数日のあい

だ配送を再試行してからでないと 配送を諦めたりしない?。

いくつかのサーバの間で負荷分散を実施するために、複数のMXを必要とする かもしれないという状況— つまり、一つの計算機だけでは処理できないほどたくさんのメールを受け取っているとき。 この場合、

なにかの処理 (ウィルスや スパムの検出のような) を他の計算機に移し、 負荷を下げることによってそのような必要性を軽減したり除去したりすることも考えてみよう。

それでも複数のMXを使い続けると決めたのなら、バックアップサーバではプライマリサーバと同等 (以上) の制限をかける必要がある、そうしないと、プライマリMXでの排除が役に立たなくなる。複数のMXホストに関わるさらなる考慮点として、 [グレーリスト法] [15]についての節も見てほしい。

3.2 他のSMTPサーバへのアクセスを阻止する

自分のドメインの DNSゾーンで公開のメール交換機 [79]に挙げられていない SMTPサーバはどれも、インターネットからの外部接続を受け付けてはいけない。 外部から来るメールトラフィックはすべて、受

入用メール交換機を通さなければいけない。

この検討事項は、SMTPサーバに限ったことではない。サイト内で内部利用目的だけで提供している計算機は、ファイアウォールを使ってアクセスを制限しよう。

規則には当然、例外がある。しかし、その例外がどんなものか分からない人は、上に書いたことを守る

こと。

3.3 転送されてきたメール

メールが次のような 「友好的」な出所から転送されてきたときは、 スパム排除の結果で拒否しないよ

うに気をつけよう:

• バックアップ MXホスト (あれば)。そこでは、すでにほとんどのゴミを排除しているはずだから ([複数の受入用メール交換機] [25]を見てほしい)。

25

Page 38: Spam Filtering for MX (ja) / メール交換機でのスパム排除

• 自分のユーザが購読しているメーリングリスト。こういうメールを排除するのはかまわない (受け付けたうえで配送せずに捨ててしまったとしても、さほど深刻な問題は起きないだろう)。しかしこういうメールを拒否してしまうと、リストサーバが受信者を自動的に退会させてしまうことになるかも

しれない。

• 受信者がよそのサイトに持っているアカウント。やはり、拒否は巻き添えスパムを引き起こすか、あるいは、メールを転送しているホストで問題を起こす。

これらの出所のうち、あとの 2つでは配送上の問題がありそうだ: これらの出所は受信者ごとに特有のものだ。それぞれのユーザに、ホワイトリストに入れるホストをどうやって指定させるか、そして、そういっ

た個々人のリストをどうやってシステム全体の SMTPの時点での排除に使うか。 メッセージが自分のサイトのある受信者に転送されてきているもの (メーリングリストの場合はたいていがこれに当てはまる)なら、誰のホワイトリストを使うかをどうやって決定するか。

この問題の解決法に、決定打はない。そこで、すこしだけ作業をしなければならない。受信者の誰かの

ホワイトリストにあるホストから送られてくるかぎりは スパム分類の結果に関わらずすべてのメールを受

け入れる、と決めることもできる。例えば、それぞれのRCPT TO:コマンドへの応答の最中に、送信側

のホストを関係するユーザのホワイトリストと照合する。ホワイトリストに見つかればフラグを立て、以

降は拒否しないようにする。実用上は、それぞれの受信者のホワイトリストを 総合したものを使うといい

だろう。

付録の実装では、この方法をより詳細に説明する。

3.4 ユーザごとの設定とデータ

状況によっては、サイトのユーザそれぞれの設定やデータに対応したほうがいいだろう。例えば、外部

から来るメールを SpamAssassin ([スパム検出ソフトウェア] [21] を見てほしい) で検査しているのなら、スパム閾値、受け入れる言語や文字集合、Bayes式の学習やデータを、 個々人が選べるようにしたほうがいいだろう。

これの難点は、外部から来るメールの SMTPの時点での排除は メールが特定のユーザに配送される前にシステム段階で行なわれており、そのため個々人の設定条件を十分に活用できない、という点だ。一つ一

つのメッセージには、複数の受信者がありうる — そして[転送されてきたメール] [25]の場合とはちがい、それぞれの受信者の設定条件を総合するのは、よい選択肢ではない。 異なる言語的背景を持つユーザがい

る場合の筋書きも検討するようにしよう。

だが、これはやりかた次第では正しくないことが判明している。 外部から来るメッセージの受信者の数

を 1つに限ってしまう、という手だ。こうすれば、メッセージを一人一人のユーザの設定やデータで解析できる。

これをするには、最初の RCPT TO: は受け付け、残りのコマンドには SMTP 451 (延期) 応答を発行すればよい。 呼出し側が正しく動作するMTAであれば、こういう応答の解釈のしかたが分かっているから、後でまた接続してくる (これで呼出し側が混乱してしまうようなら、それはおそらく、もともとメールを受け取りたくないような送信者からのものだろうね)。しかしすぐにわかることだが、これはその場しのぎの方法でしかない。 サイトの複数のユーザに送られ

るすべてのメールは、受信者ごとに 30分かそれ以上遅れていく。特に法人組織では、電子メールでの討論が内部の複数の人々や外部の他の人々との間で進むことはよくあり、 メール配送の迅速さが重視される

ので、これはおそらく良い解決策とは言えないだろう。

主に法人企業や大規模なサイトで起きる問題は他にもある。しばしば、外部から来るメールを内部の計

算機に転送してから配送しており、受信者は通常はメール交換機のアカウントを持っていない、というも

のだ。 こういう状況でも、ユーザ特有の設定やデータに対応することは可能 (例えばデータベース検索やLDAP問合せを通じて)だが、そこまでする価値があるのかどうか検討は必要だろう。とはいえ、サイトが小規模で、配送の遅延が起こっても構わないのなら、ユーザごとに排除の基準を細

かく調整できるようにする方法として受け入れられるかもしれない。

26

Page 39: Spam Filtering for MX (ja) / メール交換機でのスパム排除

第4章 質問と回答

概要本節では、ありそうな質問を検討し、回答をしてみる。ここにない疑問をお持ちの方や、本節に付け

加えられることのある方からの フィードバックをお待ちしている。

スパム送信者が適応してきたら

1. Q: スパム送信者が、この文書で説明しているテクニックに適応して テクニックを回避しようとしてき

たら、どうなりますか。

A: まあ、状況によるね。:-)この文書で説明した検査のいくつか ([SMTPでの検査] [10]や[グレーリスト法] [15] のような)は、ラッ

トウェアの振舞いに特に狙いをつけている。十分な数のサイトでこの検査が採用されるようになれば、振

舞いが変化することも十分考えられる。 Hatmut Danisch の注釈: ラットウェアにはバグのある SMTPプロトコルが入っているが、これは、もっとよいものがさしあたり必要ないからだ。 それで十分用が足りて

いるのに、 さらに時間をかけなければいけない理由があるだろうか? だがこの間、「ラットウェア」 の品質は高くなってきており、 スパムメッセージの品質も著しく改善されてきている。 出来の悪い SMTPプロトコルを検出することでスパムを拒否する人が十分に増えれば、 スパムソフトウェアの作者だってソフ

トウェアを改善するだろう。

とはいえ、このようなラットウェアには、まだ試練が立ちはだかっている:

• [SMTPトランザクションの遅延] [7]を回避するには、受け手の SMTPサーバからの応答をいちいち待つ必要がある。この点で、我々は共同して、あるスパム送信ホストが単位時間あたりに配送可能

なメールの量の 顕著な低下を達成してきている。 スパム送信者が DNSブロックリストや協調型コンテンツフィルタに追いつかれるまでに できるだけ多くのメールを送ろうと大忙しの間にも、 我々

はこういうツールの有効性を高めていくのである。

効果は、小額課金方式 [77]の結果と似たものになる。この方式では、 送信者はメールの受信者ごとに計算問題をこなすのに数秒間を費やし、結果として受信者を確認するためのシグネチャを電子メー

ルヘッダに加える。 大きな違いは (この方式の複雑さは別にして)、小額課金方式では実質的に世界全体の参加がないとスパムを取り除くのに役立たないのに対して、 SMTPトランザクションの遅延は それを実装する最初の受信者の計算機ですぐ役立つという点である。

• [HELO/EHLO 検査] [10]を回避するには、適切な挨拶をする、つまり、有効な完全修飾ドメイン名[76]で身許を明かす必要がある。 これは、(とりわけ、 メッセージの Received: ヘッダに自動的にDNS逆引きの結果を挿入しない 受信側メール転送エージェント [79]では) 追跡可能性を増大させる。

• [送信者アドレスの検査] [12]をすべてかいくぐるには、自身の有効な送信者アドレス (か、少なくとも自身のドメインで有効な送信者アドレスの一つ) を使う必要がある。言うまでもないことだが。

• [グレーリスト法] [15]を回避するには、一時的に失敗した受信者アドレスへの配送を 1時間後に (ただし 4時間経たないうちに) 再試行する必要がある。 (実装に関して言えば、ラットウェアは計算機資源を最小化するために、一時的に失敗したメールの写しをひとつひとつ保持するのではなく 一時

的に失敗した受信者の一覧を保持し、 1、2時間経ってからそのアドレスを再度調べるようになるだろう)。

27

Page 40: Spam Filtering for MX (ja) / メール交換機でのスパム排除

たとえそうなっても、グレーリスト法は、 スパムトラップ [77]がもたらす[DNSによるブラックリスト] [9]と組み合わせることで、依然としてかなりの効果を挙げることができる。なぜならば、1時間の再送遅延が義務づけられているため、送信側のホストがリストに入る機会が増えるからだ。

[スパム検出ソフトウェア] [21]や[ウィルス検出ソフトウェア] [21]のようなソフトウェアツールは、たえず進歩し続けている。スパム送信者が進歩するにつれ、これらのツールも進歩する (逆も言える)。これらのツールの最新版を使っている限り、それは効果的であり続ける。

最後に、この文書そのものも、変化をまぬがれない。 不要メールの性質が変化していくにつれて、多く

の人々が、新たな、独創的な阻止の方法を編み出すことだろう。

28

Page 41: Spam Filtering for MX (ja) / メール交換機でのスパム排除

付録A Eximによる実装

概要ここでは、この文書で説明したテクニックやツールの Eximメール転送エージェント [79]への統合に

ついて説明する。

A.1 必須事項

ここでの例には Eximメール転送エージェント [79]が必要だ。 Tom Kistner の Exiscan-ACLパッチが適

用してあることが望ましい。 Linuxのよく普及しているディストリビューションや FreeBSDのためのビルドずみ Exim+Exiscan-ACL パッケージもある — 詳しくは Exiscan-ACL1 ホームページを見てほしい23。

ここでの実装例には、最終的には次のツールも取り込むことになる:

• SpamAssassin4 — よく普及しているスパム排除ツールで、 メールの内容を巨大で高度に洗練された

ヒューリスティックで解析する。

• greylistd5 — 著者が書いた、簡易なグレーリスト法の解決策。Eximを特に念頭に置いて書いてある。

その他にも、例の全体を通じて、補助的なソフトウェアを使う。

A.2 Eximの設定ファイル

Eximの設定ファイルの最初には、全般的な定義 (これを 首節と呼ぼう)が置かれ、その後にほかの節がいくつか続く6。ほかの節はそれぞれ:

begin 節

で始まる。

主に acl 節 (つまり begin acl の後)に時間をかける —しかし、 transports 節や routers 節、さら

にファイルの最初にある首節でも、多少の項目を追加したり変更したりする。

A.2.1 アクセス制御リスト

1http://duncanthrax.net/exiscan-acl/2Eximは、とりわけ Debian GNU/Linux http://www.debian.org/のユーザの間ではおそらく最もよく普及しているMTAで、

このディストリビューションの既定のMTAになっている。Debian (「Sarge」かそれ以降)を使っているのなら、exim4-daemon-heavy

パッケージを導入すれば Exim+Exiscan-ACL を使えるようになる: # apt-get install exim4-daemon-heavy3[訳注] Exim 4.50 からは、 Exiscan-ACL パッチは Exim に標準で含まれるようになった。4http://www.spamassassin.org/5http://packages.debian.org/unstable/mail/greylistd6Debian ユーザ: exim4-config パッケージでは、 [訳注: パッケージをインストールする際に] Eximの設定を分割した細かい断

片として /etc/exim4/conf.d 配下のサブディレクトリにおさめるか、それとも設定全部を単一のファイルにおさめるかを選べる。前のほうの選択肢 (こちらがお勧め!) を選んだのなら、 exim4-config パッケージが提供する標準の設定を変更せずに保っ

たまま、 それとは別にサブディレクトリの中に新しいファイルを作成してカスタマイズができる。 例えば、/etc/exim4/conf.

d/acl/80 local-config rcpt to という名前のファイルを作成して RCPT TO: コマンドのための ACL を定義したりできる (下記 を見てほしい)。

Eximの「init」スクリプト (/etc/init.d/exim4)が、次に (再)起動するときに、自動的にこれらのファイルすべてを単一の巨大な実行時設定ファイルにまとめる。

29

Page 42: Spam Filtering for MX (ja) / メール交換機でのスパム排除

4.xx版から、 Exim はいわゆるアクセス制御リスト (ACL) を採り入れている。これはとても洗練されていて柔軟な機構で、 SMTPのあらゆる時点で排除を有効にできる。

ACLは、外部から来るメッセージのトランザクションのある状態 (リモートホストからの接続、HELO/EHLO、

MAIL FROM:、 RCPT TO: といった SMTPコマンドなど) を、受け付けるか拒否するかを判定するのに使える。例えば、 acl rcpt to という名前の ACLで、相手から受信する RCPT TO: コマンドをひ

とつひとつ確認したりもできる。

ACLは、一連の文 (あるいは 規則)から成る。文はそれぞれ、accept [受け入れ]、warn [警告]、require

[要求]、 defer [延期]、 deny [拒否] のような動作語7で始まり、その後に条件、オプション、その他その

文に関係する設定が続く。各々の文は記述された順序どおりに適用され、動作が決まるとそこで実行は終

る (warn は別)。ACLの終りには暗黙の denyがあるものとされる。

上記の acl rcpt to ACLの文は、たとえばこんなふうになる:

deny

message = relay not permitted

!hosts = +relay_from_hosts

!domains = +local_domains : +relay_to_domains

delay = 1m

この文では、「+relay from hosts」のホストリストにあるホストから配送されておらず、受信者のドメインが 「+local domains」か「+relay to domains」のドメインリストにない場合、 RCPT TO: コマ

ンドを拒否する。ただし、サーバはこのコマンドに「550」 SMTP応答を発行する前に 1分間待つ。メッセージトランザクションのある段階に特定の ACLを適用するには、 Exim の方針制御子8のどれか

一つをその ACLに向ける必要がある。 例えば、上で触れた acl rcpt to ACLを使って RCPT TO: に

適用するには、Exim 設定ファイルの首節 (全ての begin キーワードより前) に次のものを含める:

acl_smtp_rcpt = acl_rcpt_to

このような方針制御子の完全な一覧は、 Exim specifications の 14.11節を参照してほしい。

A.2.2 展開

さまざまな展開要素9を使える。これには実行時変数、検索関数、文字列/正規表現操作、ホスト/ドメインリスト、などなどがある。最新の x.x0 リリース版 (つまり 4.20, 4.30..) での網羅的なリファレンスは、「spec.txt」ファイルにある — ACLは 38節 [訳注: 4.50版では 39節] で説明してある。特に、Eximには 20種の汎用展開変数があり、ACL文の中でこれに値を代入できる:

• $acl c0 から $acl c9 までは、ある SMTP接続が続く間は持続的に値を保持できる。

• $acl m0から $acl m9 までは、メッセージを受け取っている間は値を保持できるが その後に初期化

される。これらはまた HELO、 EHLO、MAIL、 RSET の各コマンドでも初期化される。

A.3 オプションと設定

Exim設定ファイルの首節 (最初の beginキーワードより前)は、さまざまなマクロ、方針制御子、その他の一般設定を含む。まず、後で使うマクロをいくつか 定義しておこう:

# メッセージサイズの限度を定義する --- これは DATA ACL で使う.

MESSAGE_SIZE_LIMIT = 10M7[訳注] verb。8[訳注] policy control。9[訳注] expansion item。

30

Page 43: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# スパムやウィルスの検出を実行するメッセージサイズの最大.

# これで、極めて大きなメッセージでサーバに負荷がかかってしまうことを減らせる.

MESSAGE_SIZE_SPAM_MAX = 1M

# さまざまなハッシュを生成するための秘密の文字列を定義するマクロ.

# *必ず変えてほしい*.

SECRET = some-secret

一般的な Exim の設定をまとめておこう:

# DNSの失敗 (SERVFAIL) を検索失敗とみなす.

# これは, 存在しないドメインやネームサーバが存在しないドメインの

# 送信者アドレスを, 後で拒否するためである.

dns_again_means_nonexist = !+local_domains : !+relay_to_domains

# すべてのホストに対して, ACL にある HELO 確認を有効にする.

helo_try_verify_hosts = *

# 外部から一度に受け付けられる接続最大数の制限をすべてなくす. これは

# あとでスパム送信者に SMTPトランザクションの遅延をはさんでいる間も新たな

# 接続を拒絶しないためである.

smtp_accept_max = 0

# ..ただし, システム負荷が 10 を超せば接続を拒絶する.

smtp_load_reserve = 10

# ESMTP の "PIPELINING" を, どのホストにも広告しない.

# これは, いつでもパイプラインを試すようなラットウェアをけつまずかせるためだ.

pipelining_advertise_hosts = :

最後に、Eximの方針制御子をこれから作成する 5つの ACLに向け、 外部から来る SMTPトランザクションのさまざまな段階で適用できるようにする。

acl_smtp_connect = acl_connect

acl_smtp_helo = acl_helo

acl_smtp_mail = acl_mail_from

acl_smtp_rcpt = acl_rcpt_to

acl_smtp_data = acl_data

A.4 ACLの構築 — 第一段階

acl 節 (begin acl に続く箇所) では、 以下の ACL を定義する必要がある。これによって、この文書の前のほうで述べた基本的な[テクニック] [7]をいくつか組み込むことができる — [DNSによる検査] [8]と[SMTPでの検査] [10]である。この段階では、[acl rcpt to] [32]で検査のほとんどを行ない、他の ACLはほとんど空にしておく。なぜ

なら、よく使われているラットウェアのほとんどは、 SMTPトランザクション初期に拒否しても気づかないからだ — 送信を試しつづける。いっぼうラットウェアクライアントのほとんどは、RCPT TO:が失

敗すると諦める。

しかし、これらの ACLすべてを作成しておく。後で使うことになるからだ。

31

Page 44: Spam Filtering for MX (ja) / メール交換機でのスパム排除

A.4.1 acl connect

# このアクセス制御リストは, 外部からの接続の開始の際に使う.

# 検査は順に実行され, 接続を受け付けるか拒否するまで続く.

acl_connect:

# 現段階では, ここでなんの検査も実施しない.

accept

A.4.2 acl helo

# このアクセス制御リストは, 外部から来る SMTPトランザクションの HELO コマンドや

# EHLO コマンドで使う. 検査は順に実行され. 挨拶を受け付けるか拒否するまで続く.

acl_helo:

# 現段階では, ここでなんの検査も実施しない.

accept

A.4.3 acl mail from

# このアクセス制御リストは, 外部から来る SMTPトランザクションの MAIL FROM:

# コマンドに使う. テストは順に実行され, 送信者アドレスが受け付けられるか拒否

# されるかすると, そこで終る.

#

acl_mail_from:

# コマンドを受け付ける.

accept

A.4.4 acl rcpt to

# このアクセス制御リストは, 外部からの SMTP メッセージの RCPT コマンドごと

# に使う. テストは順に実行され, 受信者アドレスが受け付けられるか拒否される

# かすると, そこで終る.

acl_rcpt_to:

# ローカルの SMTP経由 (つまり TCP/IP 経由でない) で受け取ったメールを受

# け付ける. 空の送信側ホスト項目でこれをテストする.

32

Page 45: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# また, メールのリレーのためのホストからのメールも受け付ける.

#

# 受信者確認はここではしない. しばしば, クライアントが低能な MUA で,

# こういったものは SMTPエラー応答にうまく対応できないためだ.

#

accept

hosts = : +relay_from_hosts

# メッセージが認証された接続を通じて届いたら, どのホストからでも受け付ける.

# ここでも, こういったメッセージは普通は MUA からなので, 受信者確認はしない.

#

accept

authenticated = *

######################################################################

# DNSによる検査

######################################################################

#

# 以下の検査の結果はキャッシュされるので, 複数の受信者があっても

# 複数の DNS検索は発生しない.

#

# 接続してきているホストが特に選別した DNSbl に登録されていれば,

# メッセージを拒否する. リストの選別には注意を要する --- 多くのものが,

# 大量の偽陽性を発生させるし, また, リストからの削除について明確な方針が

# なかったりする.

#

deny

dnslists = dnsbl.sorbs.net : \

dnsbl.njabl.org : \

cbl.abuseat.org : \

bl.spamcop.net

message = $sender_host_address is listed in $dnslist_domain\

${if def:dnslist_text { ($dnslist_text)}}

# 送信者ホストの DNS逆引きが失敗したら (つまり, 逆引きエントリがないか, 逆引き

# の結果の名前の正引きが元の IPアドレスに一致しなかったら), メッセージを拒否する.

#

deny

message = Reverse DNS lookup failed for host $sender_host_address.

!verify = reverse_host_lookup

######################################################################

33

Page 46: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# ハローの検査

######################################################################

# リモートホストが IPアドレスで挨拶してきたら, メールを拒否する.

#

deny

message = message was delivered by ratware

log_message = remote host used IP address in HELO/EHLO greeting

condition = ${if isip {$sender_helo_name}{true}{false}}

# 相手が自分の名前のどれかで挨拶してきたときも同様

#

deny

message = message was delivered by ratware

log_message = remote host used our name in HELO/EHLO greeting.

condition = ${if match_domain{$sender_helo_name}\

{$primary_hostname:+local_domains:+relay_to_domains}\

{true}{false}}

deny

message = message was delivered by ratware

log_message = remote host did not present HELO/EHLO greeting.

condition = ${if def:sender_helo_name {false}{true}}

# HELOの確認が失敗したら, X-HELO-Warning: ヘッダをメッセージに追加する.

#

warn

message = X-HELO-Warning: remote host $sender_host_address \

${if def:sender_host_name {($sender_host_name) }}\

incorrectly presented itself as $sender_helo_name

log_message = remote host presented unverifiable HELO/EHLO greeting.

!verify = helo

######################################################################

# 送信者アドレスの検査

######################################################################

# 送信者アドレスが確認できなければ, メッセージを拒絶する.

#

# "callout" [呼出し] オプションを削除してもよい. 特に,

# 外部へ行くメールをスマートホストを通じて送っているのなら, これは有用な情報を

# なにも与えてくれない.

#

34

Page 47: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# 呼出し確認が 550 応答で失敗する場合について --- これをしないためには,

# "sender/callout" を "sender/callout,no_details" に変える.

#

deny

message = <$sender_address> does not appear to be a \

valid sender address.

!verify = sender/callout

######################################################################

# 受信者アドレスの検査

######################################################################

# ローカル部が @ や % や / や | や ! を含んでいれば拒絶.

# こういったものは, 本物のローカル部にはまず現れないが, リレー制限の抜け穴

# を探す輩がよく試すものだ.

#

# ドットで始まるローカル部なら, これも拒絶. 空のコンポーネントは厳密には

# RFC 2822 違反だが, これはよくあるので Exim では受け入れる. しかし,

# ドットで始まっているものは, ローカル部がファイル名として使われる場合

# (例えばメーリングリストのために) にトラブルを起こすかもしれない.

#

deny

local_parts = ^.*[@%!/|] : ^\\.

# エンヴェロープ送信者が空なのに受信者アドレスが複数あれば, 接続を切る.

# 真っ当な DSN は, 1つより多くのアドレスに送ったりしない.

#

drop

message = Legitimate bounces are never sent to more than one \

recipient.

senders = : postmaster@*

condition = $recipients_count

# 我々がメールを扱うドメインにない受信者アドレスなら拒否する.

#

deny

message = relay not permitted

!domains = +local_domains : +relay_to_domains

# 有効なメールボックスでない受信者は拒絶する.

# メールボックスが我々のシステムにないのなら (例えば受信者ドメインの

# バックアップ MXであるのなら), 呼出し確認を実施する --- しかし,

# もしも目的のサーバが応答しなければ, 受信者はいずれにせよ受け付ける.

35

Page 48: Spam Filtering for MX (ja) / メール交換機でのスパム排除

#

deny

message = unknown user

!verify = recipient/callout=20s,defer_ok

# さもなければ, 受信者アドレスは問題ない.

#

accept

A.4.5 acl data

# このアクセス制御リストは, SMTPを通じて受け取るメッセージデータに使う.

# テストは順に実行され, 受信者アドレスが受け付けられるか拒絶されたところ

# で終る.

acl_data:

# 自身のホストから受け取ったメッセージに Message-ID がなければ追加する.

warn

condition = ${if !def:h_Message-ID: {1}}

hosts = : +relay_from_hosts

message = Message-ID: <E$message_id@$primary_hostname>

# ローカルの SMTP経由 (つまり TCP/IP 経由でない) で受け取ったメールを受け付ける.

# 空の送信側のホスト項目をテストすることで, これを行なう.

# また, メールのリレーに使うホストから受け取ったメールも受け付ける.

#

accept

hosts = : +relay_from_hosts

# メッセージが認証された接続を通じて届いたら, どんなホストでも受け付ける.

#

accept

authenticated = *

# メッセージサイズの限度を課す

#

deny

message = Message size $message_size is larger than limit of \

MESSAGE_SIZE_LIMIT

condition = ${if >{$message_size}{MESSAGE_SIZE_LIMIT}{true}{false}}

# アドレスリストのヘッダが構文的に正しくなければ拒絶する.

36

Page 49: Spam Filtering for MX (ja) / メール交換機でのスパム排除

#

deny

message = Your message does not conform to RFC2822 standard

log_message = message header fail syntax check

!verify = header_syntax

# Message-ID や Date のない非ローカルメッセージは拒絶する

#

# 一部の特殊化された MTA (ある種のメーリングリストサーバのような) は,

# バウンスの Message-ID を自動的に生成しないことに注意.

# そのため, 空でない送信者の検査も追加する.

#

deny

message = Your message does not conform to RFC2822 standard

log_message = missing header lines

!hosts = +relay_from_hosts

!senders = : postmaster@*

condition = ${if or {{!def:h_Message-ID:}\

{!def:h_Date:}\

{!def:h_Subject:}} {true}{false}}

# 少なくとも "Sender:", "Reply-To:", "From:" のヘッダのいずれかに

# 確認できる送信者アドレスがなければ, 警告する.

#

warn

message = X-Sender-Verify-Failed: No valid sender in message header

log_message = No valid sender in message header

!verify = header_sender

# メッセージを受け付ける.

#

accept

A.5 SMTPトランザクションの遅延を追加する

A.5.1 簡易な方法

SMTPトランザクションの遅延を追加するいちばん簡単な方法は、 定義した ACLそれぞれの最後のaccept 文に delay 制御子を追加することだ。次のようにする:

accept

delay = 20s

加えて、 [acl rcpt to] [32] 中で deny 文に、 無効な受信者に関する文 (「unknown user」)ごとに増加

37

Page 50: Spam Filtering for MX (ja) / メール交換機でのスパム排除

していく遅延を追加することもできよう。これは辞書攻撃を遅める。 例えば:

deny

message = unknown user

!verify = recipient/callout=20s,defer_ok,use_sender

delay = ${eval:$rcpt_fail_count*10 + 20}s

[acl data] [36] の中でメッセージデータを受け取ってしまった後には、遅延をはさめるところはないことに注意しなければならない。 ラットウェアはしばしば、サーバからの応答を受信する前でも、ここで切断

する。 Eximは、クライアントがここで切断してもしなくても関係なくいつでも、 メッセージの配送を続行する。

A.5.2 選択的な遅延

SMTPトランザクションの遅延を、どのホストではさむか選べるようにしたくないだろうか。 例えば、この文書の前のほうで述べたように、 DNSによるブラックリストで一致するものや EHLO/HELO挨拶での確認ができないものは、それだけでは拒否してよいと断定できる条件ではないと言えそうだ —しかし、こういったものはトランザクションの遅延には充分な契機となる。

選択的な遅延を実施するために、以前は [acl rcpt to] [32]でしていた検査を、 SMTPトランザクションの初期に移動する。これは、問題の徴候が見つかったらできるだけ早く遅延をはさみはじめられるように

し、そうすることでラットウェアが同期エラーその他の問題を起こす機会を増やすためだ。

具体的には、次のようにしたい:

• DNSによる検査を [acl connect] [60] へ移動する。

• ハローの検査を [acl helo] [61] へ移動する。 例外が一つある: そこでは、ハロー挨拶がないことの検査はまだできない。なぜならその ACLは、 EHLOコマンドや HELOコマンドへの応答の際に 処理されるからだ。この検査は [acl mail from] [62] ACLでする。

• 送信者アドレスの検査を [acl mail from] [62] へ移動する。

ただし、上で述べた理由から、RCPT TO: コマンドより後になるまでは実際にメールを拒否したくはな

い。かわりに、ACLのはじめのほうのさまざまな deny [拒絶] 文を warn [警告] 文に変更し、 Exim の汎用 ACL変数にエラーメッセージや警告を格納しておいて、RCPT TO:コマンドの後で使うことにする。

以下のようにしてできる:

• 配送を拒否すると判断したら、後の 550 応答で使うメッセージを $acl c0 か $acl m0 に格納する:

– メール配送が始まるより前 (つまり [acl connect] [60]か [acl helo] [61] の中で)に条件を満たしたら、接続の間維持される変数 $acl c0 を使う

– メールトランザクションが始まってしまったら (つまり MAIL FROM: コマンドより後)、$acl c0の内容はなんでも、メッセージごとの変数 $acl m0に複写し、以降は後者を使う。こ

れにより、特定のメッセージが満たす条件は、 以後同じ接続で受け取るメッセージには影響し

ない。

また、関連する 記録メッセージ を $acl c1 か $acl m1 に、同様のやりかたで格納する。

• 即座に拒否してよいと断定できない条件に出くわしたときは、 $acl c1 か $acl m1 に警告メッセー

ジを格納するだけにして、 メールトランザクションが始まってから (つまり [acl mail from] [62] の中で)、この変数の内容をメッセージヘッダに追加する。

• 以降の検査 (SpamAssassin による検出のような) の結果に関わらずメッセージを受け付けることになったら、 $acl c0 か $acl m0 にフラグをセットするが、 $acl c1 や $acl m1 は空にする。

38

Page 51: Spam Filtering for MX (ja) / メール交換機でのスパム排除

• すべての ACLの最初と [acl mail from] [62]で、$acl m2に現在のタイムスタンプを記録する。ACLの最後では、$acl c1 か $acl m1が存在すれば、 合計 20秒が経過するまで SMTPトランザクションの遅延をする。

以下に、変数の用法をまとめておく:

Table A.1: ACLでの接続/メッセージ変数の用法

変数: $acl [cm]0 未代入 $acl [cm]0 代入ずみ

$acl [cm]1 未代入 (未定) メールを受け付け

$acl [cm]1 代入ずみ ヘッダに警告を追加 メールを拒否

このアプローチの例として、ハロー挨拶への応答のときに行なう 2つの検査を考えてみよう — ひとつ

は、相手が IPアドレスで挨拶したらメールを拒否し、 もうひとつは、挨拶に無効な名前があれば警告する。 以前は、どちらの検査も [acl rcpt to] [32] で行なっていた — 今度はこれらを [acl helo] [61] ACLへ移動する:

acl_helo:

# 以降の遅延の継続期間を計算するために, 現在のタイムスタンプを記録する

warn

set acl_m2 = $tod_epoch

# ローカルの SMTP経由 (つまり TCP/IP経由ではない) で受信したメールを受け入れる.

# 空の送信側ホスト項目をテストすることでこれを行なう.

# また, メールをリレーするためのホストから受信したメールも受け入れる.

#

accept

hosts = : +relay_from_hosts

# リモートホストが IPアドレスで挨拶したら, $acl_c0 に拒否メッセージを,

# $acl_c1 に記録用メッセージを用意する. これらは後で "deny" 文の中で使う.

# しばらくの間, これらの存在で送信者を足止めしておかなければならないことを示す.

#

warn

condition = ${if isip {$sender_helo_name}{true}{false}}

set acl_c0 = Message was delivered by ratware

set acl_c1 = remote host used IP address in HELO/EHLO greeting

# HELOの確認が失敗したら, acl_c1 に警告メッセージを用意する.

# このメッセージは, 後でメールヘッダに追加する.

# しばらくの間, これの存在で送信者を足止めしておかなければならないことを示す.

#

warn

condition = ${if !def:acl_c1 {true}{false}}

!verify = helo

set acl_c1 = X-HELO-Warning: Remote host $sender_host_address \

39

Page 52: Spam Filtering for MX (ja) / メール交換機でのスパム排除

${if def:sender_host_name {($sender_host_name) }}\

incorrectly presented itself as $sender_helo_name

log_message = remote host presented unverifiable HELO/EHLO greeting.

#

# ... さらなる検査. この例では略す ...

#

# 接続を受け付ける. ただし, 前に $acl_c1 にメッセージを生成しているのなら,

# 20秒が経過するまで送信者を足止めする.

accept

set acl_m2 = ${if def:acl_c1 {${eval:20 + $acl_m2 - $tod_epoch}}{0}}

delay = ${if >{$acl_m2}{0}{$acl_m2}{0}}s

そして [acl mail from] [62] では、 $acl c{0,1} に入っているメッセージを $acl m{0,1} へ伝達する。また、 $acl c1 の内容をメッセージヘッダに追加する。

acl_mail_from:

# 以降の遅延の継続期間を計算するために, 現在のタイムスタンプを記録する

warn

set acl_m2 = $tod_epoch

# ローカルの SMTP経由 (つまり TCP/IP経由ではない) で受信したメールを受け入れる.

# 空の送信側ホスト項目をテストすることでこれを行なう.

# また, メールをリレーするためのホストから受信したメールも受け入れる.

#

accept

hosts = : +relay_from_hosts

# ACL 変数 $acl_c0 と $acl_c1 がもしあれば, 拒否や警告のメッセージを含んでいる

# ので, この SMTPトランザクションでの配送の試みひとつひとつにこれを適用する.

# これらの変数をメッセージごとの $acl_m{0,1} 変数に代入し, $acl_m1 の警告メッ

# セージをメッセージヘッダに追加する (拒否の場合は, $acl_m1 には記録用メッセージ

# が入っていることになるが, かまわない. ヘッダを追加するはずのメッセージはどうせ

# 破棄するのだから).

#

warn

set acl_m0 = $acl_c0

set acl_m1 = $acl_c1

message = $acl_c1

#

# ... さらなる検査. この例では略す ...

#

40

Page 53: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# 送信者を受け付ける. ただし, 前に $acl_c1 にメッセージを生成しているのなら,

# 20秒が経過するまで送信者を足止めする.

accept

set acl_m2 = ${if def:acl_c1 {${eval:20 + $acl_m2 - $tod_epoch}}{0}}

delay = ${if >{$acl_m2}{0}{$acl_m2}{0}}s

後の[できあがった ACL] [60]では、このような変更がすべてしてある。

A.6 グレーリスト法への対応を追加する

Exim でのグレーリスト法の実装にはいくつか選択肢がある。 ここでは、そのうちの 2つについて説明する。

A.6.1 greylistd

これは、著者が開発した Pythonでの実装である (そういうわけで、後の[できあがった ACL] [60]にはこの実装を含めてある)。 これは独立したデーモンとして動作し、外部データベースを用いない。 効率のために、グレーリストのデータを単純な 32ビットハッシュに蓄える。これは http://packages.debian.org/unstable/mail/greylistd にある。 Debian のユーザなら、

APT を通じて手に入る:

# apt-get install greylistd

greylistdを使うには、先ほど定義した [acl rcpt to] [64] ACLで、最後の accept 文の直前に、2つの文を入れる:

# "greylistd" を使って、この特定の相手/送信者/受信者の三つ組に対するグレーリス

# トの状態を得る.

#

# 送信者が空のメッセージはグレーリストしない. なぜなら送信者呼出し確認が失敗

# する (そのため, 呼出しを実施しているホストへメールを送れなくなりかねない) から

# だ.

#

defer

message = $sender_host_address is not yet authorized to deliver mail \

from <$sender_address> to <$local_part@$domain>. \

Please try later.

log_message = greylisted.

domains = +local_domains : +relay_to_domains

!senders = : postmaster@*

set acl_m9 = $sender_host_address $sender_address $local_part@$domain

set acl_m9 = ${readsocket{/var/run/greylistd/socket}{$acl_m9}{5s}{}{}}

condition = ${if eq {$acl_m9}{grey}{true}{false}}

いんちきな配送状況通知 [78]を阻止するためにエンヴェロープ送信者のシグネチャを組み込んでいるのでない限り、 [acl data] [69]にも同様の文を追加して、 送信者が空のメッセージもグレーリストしたほうがよいかもしれない。

acl dataでグレーリスト法のために使うデータは、上のものと少し異なる。ここでは $sender address

が空であり、そのうえ $local part や $domain を定義していない。かわりに、すべての受信者アドレス

41

Page 54: Spam Filtering for MX (ja) / メール交換機でのスパム排除

のカンマ区切りリストを 含む変数 $recipients がある。 真っ当な DSNでは、アドレスが一つだけでなければならない。

# ここでは, エンヴェロープ送信者のないメッセージにグレーリスト法を実施する.

# RCPT TO: の後ではこういったものをグレーリスト法にかけていない. なぜなら

# 送信者呼出しをしているリモートホストの邪魔になるからだ.

#

defer

message = $sender_host_address is not yet authorized to send \

delivery status reports to <$recipients>. \

Please try later.

log_message = greylisted.

senders = : postmaster@*

set acl_m9 = $sender_host_address $recipients

set acl_m9 = ${readsocket{/var/run/greylistd/socket}{$acl_m9}{5s}{}{}}

condition = ${if eq {$acl_m9}{grey}{true}{false}}

A.6.2 MySQLによる実装

以下の実装は、 Johannes Berg <johannes a©sipsolutions.net> から提供されたもので、一部は次の

ものに基づいている:

• Rick Stewart <rick.stewart a©theinternetco.net>による成果。 http://theinternetco.net/

projects/exim/greylist で公開されている。これはさらに、次のものに基づいている

• Tollef Fog Heen <tfheen a©raw.no>による、Postgresでの実装。http://raw.no/personal/blog/

tech/Debian/2004-03-14-15-55 greylisting で手に入る

これには、外部プログラムが要らない — 実装は、 以下の設定の断片と MySQLデータベースだけに基づいている。

設定の断片の最新版に加え READMEファイルも含むアーカイブが、次の場所で手に入る: http://johannes.sipsolutions.net/Projects/exim-greylist10。

システムに MySQLをインストールしてある必要がある。MySQLのプロンプトで、 exim4データベー

ス、そして 2つのテーブル exim greylist と exim greylist log を作成する。以下のようにする:

CREATE DATABASE exim4;

use exim4;

CREATE TABLE exim_greylist (

id bigint(20) NOT NULL auto_increment,

relay_ip varchar(80) default NULL,

sender varchar(255) default NULL,

recipient varchar(255) default NULL,

block_expires datetime NOT NULL default ’0000-00-00 00:00:00’,

record_expires datetime NOT NULL default ’9999-12-31 23:59:59’,

create_time datetime NOT NULL default ’0000-00-00 00:00:00’,

type enum(’AUTO’,’MANUAL’) NOT NULL default ’MANUAL’,

passcount bigint(20) NOT NULL default ’0’,

blockcount bigint(20) NOT NULL default ’0’,

10[訳注] 原文の URLはアクセスできなくなっていたので修正した。

42

Page 55: Spam Filtering for MX (ja) / メール交換機でのスパム排除

PRIMARY KEY (id)

);

CREATE TABLE exim_greylist_log (

id bigint(20) NOT NULL auto_increment,

listid bigint(20) NOT NULL,

timestamp datetime NOT NULL default ’0000-00-00 00:00:00’,

kind enum(’deferred’, ’accepted’) NOT NULL,

PRIMARY KEY (id)

);

Exim設定ファイルの首節で、以下のマクロを定義する。

# まだデータベースサーバの定義がなければ, ここで定義する

hide mysql_servers = localhost/exim4/ユーザ/パスワード

# オプション

# 次のものは, mysql で DATE_ADD(..,INTERVAL xxx) の xxx に書けるものである

# 必要がある. 例えば, 複数形は書けない: "2 HOURS" ではなく "2 HOUR"

GREYLIST_INITIAL_DELAY = 1 HOUR

GREYLIST_INITIAL_LIFETIME = 4 HOUR

GREYLIST_WHITE_LIFETIME = 36 DAY

GREYLIST_BOUNCE_LIFETIME = 0 HOUR

# テーブル名は変えてもよい

GREYLIST_TABLE=exim_greylist

GREYLIST_LOG_TABLE=exim_greylist_log

# 次の行をコメントアウトすれば, グレーリスト法を (一時的に) 無効にできる

GREYLIST_ENABLED=

# 次の行のコメントを外すと, 記録が有効になる

#GREYLIST_LOG_ENABLED=

# 通常, これ以降はなにも変更する必要がない

.ifdef GREYLIST_ENABLED

# データベースのためのマクロ

GREYLIST_TEST = SELECT CASE \

WHEN now() > block_expires THEN "accepted" \

ELSE "deferred" \

END AS result, id \

FROM GREYLIST_TABLE \

WHERE (now() < record_expires) \

AND (sender = ’${quote_mysql:$sender_address}’ \

OR (type=’MANUAL’ \

AND ( sender IS NULL \

OR sender = ’${quote_mysql:@$sender_address_domain}’ \

) \

43

Page 56: Spam Filtering for MX (ja) / メール交換機でのスパム排除

) \

) \

AND (recipient = ’${quote_mysql:$local_part@$domain}’ \

OR (type = ’MANUAL’ \

AND ( recipient IS NULL \

OR recipient = ’${quote_mysql:$local_part@}’ \

OR recipient = ’${quote_mysql:@$domain}’ \

) \

) \

) \

AND (relay_ip = ’${quote_mysql:$sender_host_address}’ \

OR (type=’MANUAL’ \

AND ( relay_ip IS NULL \

OR relay_ip = substring(’${quote_mysql:$sender_host_address}’, \

1,length(relay_ip)) \

) \

) \

) \

ORDER BY result DESC LIMIT 1

GREYLIST_ADD = INSERT INTO GREYLIST_TABLE \

(relay_ip, sender, recipient, block_expires, \

record_expires, create_time, type) \

VALUES ( ’${quote_mysql:$sender_host_address}’, \

’${quote_mysql:$sender_address}’, \

’${quote_mysql:$local_part@$domain}’, \

DATE_ADD(now(), INTERVAL GREYLIST_INITIAL_DELAY), \

DATE_ADD(now(), INTERVAL GREYLIST_INITIAL_LIFETIME), \

now(), \

’AUTO’ \

)

GREYLIST_DEFER_HIT = UPDATE GREYLIST_TABLE \

SET blockcount=blockcount+1 \

WHERE id = $acl_m9

GREYLIST_OK_COUNT = UPDATE GREYLIST_TABLE \

SET passcount=passcount+1 \

WHERE id = $acl_m9

GREYLIST_OK_NEWTIME = UPDATE GREYLIST_TABLE \

SET record_expires = DATE_ADD(now(), \

INTERVAL GREYLIST_WHITE_LIFETIME) \

WHERE id = $acl_m9 AND type=’AUTO’

GREYLIST_OK_BOUNCE = UPDATE GREYLIST_TABLE \

SET record_expires = DATE_ADD(now(), \

INTERVAL GREYLIST_BOUNCE_LIFETIME) \

44

Page 57: Spam Filtering for MX (ja) / メール交換機でのスパム排除

WHERE id = $acl_m9 AND type=’AUTO’

GREYLIST_LOG = INSERT INTO GREYLIST_LOG_TABLE \

(listid, timestamp, kind) \

VALUES ($acl_m9, now(), ’$acl_m8’)

.endif

そして、ACL 節 (begin acl の後) で、「greylist acl」という名の ACLを新たに作成する:

.ifdef GREYLIST_ENABLED

# この ACLは deny [拒否] か accept [受け入れ] を返す.

# defer [延期] 文の中で acl = greylist_acl として使う.

# 受け入れると条件が真となるので延期し, 拒否すると条件が偽となるので延期しない

greylist_acl:

# 通常の配送では, グレーリスト検査をする.

# グレーリストの三つ組を検査し, acl_m8 に "accepted", "deferred",

# "unknown" のいずれかを, また acl_m9 にレコード IDを返す.

warn set acl_m8 = ${lookup mysql{GREYLIST_TEST}{$value}{result=unknown}}

# acl_m8 = "result=x id=y" になる

set acl_m9 = ${extract{id}{$acl_m8}{$value}{-1}}

# ここで acl_m9 にはレコード ID (または -1) が入る

set acl_m8 = ${extract{result}{$acl_m8}{$value}{unknown}}

# ここで acl_m8 には unknown/deferred/accepted のいずれかが入る

# 既知の三つ組かどうか検査し, そうでなければメッセージを追加して延期する

accept

# 上の検査が unknown (レコードがまだない) を返したら

condition = ${if eq{$acl_m8}{unknown}{1}}

# レコードの追加もする

condition = ${lookup mysql{GREYLIST_ADD}{yes}{no}}

# ここで, 結果が何かにかかわらず記録する

# 三つ組が未知なら, 上記の作成時刻からわかるので, エントリを記録する必要はない

# (ので, エントリを取得しない).

.ifdef GREYLIST_LOG_ENABLED

warn condition = ${lookup mysql{GREYLIST_LOG}}

.endif

# 三つ組がまだ阻止中かどうか検査する

accept

# 上の検査が deferred を返したら延期し

condition = ${if eq{$acl_m8}{deferred}{1}}

# そのことを記録する

condition = ${lookup mysql{GREYLIST_DEFER_HIT}{yes}{yes}}

45

Page 58: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# 見つかったレコードの数を記録するのに warn 動作語を使う

warn condition = ${lookup mysql{GREYLIST_OK_COUNT}}

# warn 動作語を使い, メールがバウンスでなかったときに限り自動記録の新たな消去

# 期限をセットする. バウンスであったときは now() をセットする.

warn !senders = : postmaster@*

condition = ${lookup mysql{GREYLIST_OK_NEWTIME}}

warn senders = : postmaster@*

condition = ${lookup mysql{GREYLIST_OK_BOUNCE}}

deny

.endif

この ACLを [acl rcpt to] [64] に入れると、送信者アドレスが空でない三つ組をグレーリストする。 送信者呼出し確認法ができるようにするには、次のようにする:

.ifdef GREYLIST_ENABLED

defer !senders = : postmaster@*

acl = greylist_acl

message = greylisted - try again later

.endif

また、[acl data] [36] 部にもこれを入れるが、 今度は送信者アドレスが空のときだけ働く。 これは、スパム送信者が送信者アドレスを空にすることで グレーリスト法を回避するのを防ぐためだ。

.ifdef GREYLIST_ENABLED

defer senders = : postmaster@*

acl = greylist_acl

message = greylisted - try again later

.endif

A.7 SPFの検査を追加する

ここでは、Eximを使って[Sender Policy Framework] [17]レコードを検査する方法を 2つ説明する。ここで説明する機構のほかに、 SpamAssassin スイートには近いうちに (2.70版あたりで)、洗練された SPF検査がとりいれられるはずだ。これは、さまざまな SPFの結果に重みづけのある得点を割り振れる。この検査を、[acl mail from] [62] ACLのかなりはじめのほうで実施することもできたのだが この判断に影響を与える問題点がある: SPFは伝統的な電子メール転送と互換性がない。 転送元のホストが SRS11を

実装していないかぎり、転送されてきたメールでも エンヴェロープ送信者 [76]アドレスのドメインの SPF方針によって送信を認証されていないホストから届いたという理由で拒否してしまうだろう。

これを避けるために、転送されてきたメールを受け付けなければならないホストの一覧を、ユーザごと

に参照する必要がある (以下の[転送されてきたメールを通す] [58]で説明する)。これは、受信者のユーザ名がわかる RCPT TO: より後でのみ可能になる。

そこで、[acl rcpt to] [64] の中で、どのグレーリスト法や最後の accept 文よりも前に、この検査を追

加する。

A.7.1 Exiscan-ACLによる SPFの検査

11http://spf.pobox.com/srs.html

46

Page 59: Spam Filtering for MX (ja) / メール交換機でのスパム排除

Tom Kistner の Exiscan-ACL パッチ ([必須事項] [29]を見てほしい) の最近の版には、組み込みの SPF対応がある12。使いかたはとても簡単だ。 spf というACL条件が追加される。この条件の結果を pass、

fail、 softfail、 none、 neutral、 err perm、 err temp といったキーワードで調べる。

[acl rcpt to] [64] で、 すべてのグレーリスト法検査や最後の accept 文よりも前に、以下の断片を挿入

する:

# 送信者アドレスのドメインについての SPF情報を問い合わせ, もしあれば,

# 送信側のホストがそのメールの配送を認証されているか調べる.

# 認証されていなければ, そのメールは拒否する.

#

deny

message = [SPF] $sender_host_address is not allowed to send mail \

from $sender_address_domain

log_message = SPF check failed.

spf = fail

# メッセージに SPF-Received: ヘッダを追加する

warn

message = $spf_received

この文では、 送信者アドレスのドメインの持ち主が呼出し側のホストからの配送を認めていなければ、

そのメールを拒否する。ただこのやりかたは、ドメインの持ち主が公告する情報にいささか頼りすぎてい

るため、必要なメールまで拒否してしまう場合もあるかもしれない。お勧めの対案は、SPF検査を送信者呼出し確認法のような他の検査と組み合わせることだ (だがその前に注意しておいてほしいが、 外部へ行くメールをスマートホストを通じて送っているのなら、これはできない):

# 送信者アドレスを呼出し確認できず, 送信側ドメインの SPF情報が送信側

# のホストに明らかな権限を与えていなければ, メールを拒否する.

#

deny

message = The sender address does not seem to be valid, and SPF \

information does not grant $sender_host_address explicit \

authority to send メール from $sender_address_domain

log_message = SPF check failed.

!verify = sender/callout,random,postmaster

!spf = pass

# メッセージに SPF-Received: ヘッダを追加する

warn

message = $spf_received

A.7.2 Mail::SPF::Query による SPFの検査

Mail::SPF::Queryは、SPFの公式なテストスイートである。http://spf.pobox.com/downloads.html

で手に入る。 Debian ユーザなら、libmail-spf-query-perl をインストールする。

12Debian ユーザ: 2004 年 7 月 14 日の時点では、 exim4-daemon-heavy パッケージに入っている Exiscan-ACL の版にはまだSPF 対応がない。しばらくの間は、ほかの SPFの実装を使ってもいいだろう — libmail-spf-query-perl をインストールする。

47

Page 60: Spam Filtering for MX (ja) / メール交換機でのスパム排除

Mail::SPF::Query パッケージには、デーモン (spfd)がついてくる。これは UNIXドメインソケットで要求を listenする。残念ながら、このデーモンを自動的に開始させる「 init」スクリプトはついてこない。 そこで以下の例では、SPF要求をするのにスタンドアロンの spfquery ユーティリティを使う。

上のように、以下のものを、[acl rcpt to] [32]のどのグレーリスト法の検査よりも前、最後の accept 文

より前に挿入する:

# "spfquery" を使ってこの特定の送信者/ホストの SPF状況を得る.

# このコマンドが返すコードが 1なら, これは認証された送信者である.

#

deny

message = [SPF] $sender_host_address is not allowed to send mail \

from $sender_address_domain.

log_message = SPF check failed.

set acl_m9 = -ipv4=$sender_host_address \

-sender=$sender_address \

-helo=$sender_helo_name

set acl_m9 = ${run{/usr/bin/spfquery $acl_m9}}

condition = ${if eq {$runrc}{1}{true}{false}}

A.8 MIMEとファイル型の検査を追加する

ここでの検査は、Tom Kistner の Exiscan-ACL パッチにある仕様に依存している — 詳細は [必須事項][29] を見てほしい。

Exiscan-ACLには、MIMEのデコードとファイル名接尾辞の検査 (または、Windows界の誤用では「ファイル拡張子」の検査) への対応が含まれる。この検査だけでも Windows のウィルスのほとんどを阻止できる -しかし、 .ZIP 書庫で伝達されるものや、 Outlook/MSIEの HTMLレンダリングの脆弱性を突くものは阻止できない - [ウィルス検出ソフトウェア] [21]についての議論を見てほしい。これらの検査は、[acl data] [36]の中で 最後の accept 文の前に来なければならない:

# 重大な MIMEエラーがあるメッセージは拒否する.

#

deny

message = Serious MIME defect detected ($demime_reason)

demime = *

condition = ${if >{$demime_errorlevel}{2}{1}{0}}

# MIMEコンテナを解き、ワームが使うファイル拡張子は拒否する.

# これは demime 条件をもう一度呼び出すが、キャッシュした結果が返る.

# 拡張子の一覧は完全なものではないことに注意.

#

deny

message = We do not accept ".$found_extension" attachments here.

demime = bat:btm:cmd:com:cpl:dll:exe:lnk:msi:pif:prf:reg:scr:vbs:url

上の例では、demime 条件が 2度呼び出されることに気づいただろう。しかし、結果はキャッシュされるので、実際にはメッセージが 2度処理されることはない。

48

Page 61: Spam Filtering for MX (ja) / メール交換機でのスパム排除

A.9 ウィルス対策ソフトウェアを追加する

Exiscan-ACL は、さまざまに異なるウィルス検出ソフトウェアと直接結合できるし、 他の検出ソフトウェアでも cmdline バックエンドを通じてコマンドラインから実行できる。

この仕様を使うには、 Exim設定ファイルの首節に、使うウィルス検出ソフトウェアの種類をその検出ソフトウェアに渡したいオプションとともに 指定しなければならない. 基本の構文は:

av_scanner = 検出ソフトウェアの種類:オプション 1:オプション 2:...

例えば:

av_scanner = sophie:/var/run/sophie

av_scanner = kavdaemon:/opt/AVP/AvpCtl

av_scanner = clamd:127.0.0.1 1234

av_scanner = clamd:/opt/clamd/socket

av_scanner = cmdline:/path/to/sweep -all -rec -archive %s:found:’(.+)’

...

次に、DATA ACLで malware 条件を使って実際の検出を実施するとよいだろう:

deny

message = This message contains a virus ($malware_name)

demime = *

malware = */defer_ok

exiscan-acl-spec.txt ファイル [訳注: Exim 4.50版では spec.txt の 40節] に、使用法についての情報がすべてある。

A.10 SpamAssassinを追加する

Exim では、SMTPの時点で SpamAssassin を実行する方法が主に 2つある:

• Exiscan-ACLが提供する spam 条件によって。これが、ここで説明する機構である。

• SA-Exim によって。 これは、 Marc Merlins ( <marc a©merlins.org>) が書いた別のユーティリティで、 Exim で SpamAssassin を SMTPの時点で実行するためのものである。 このプログラムは Exim の local scan() インタフェースを通じて動作する。つまり、Exim のソースコードに直接パッチを当てるか、 Marc による dlopen()プラグインを介して動作させる (なお、これは Debianの exim4-daemon-light パッケージや exim4-daemon-heavy パッケージには入っている)。

SA-Exim はまた、ほかの仕様も提供する。つまり、グレーリスト法 と タール坑法 である。しかし

ながら、これらの仕様は 2つともメッセージデータを受け取った後に検出を行なうので、 SMTPトランザクションの初期に行なう場合ほどには有用でないだろう。

SA-Exim は、次の場所で見つかる: http://marc.merlins.org/linux/exim/sa.html。

A.10.1 Exiscanから SpamAssassinを呼び出す

Exiscan-ACLの「spam」条件では、メッセージを SpamAssassinか Brightmailのいずれかに渡し、メッセージにゴミの徴候があれば文を実行する。これは既定では、 localhostで実行している SpamAssassinデーモン (spamd) に接続する。 ホストとポートは、Exim設定ファイルの首節に spamd address 設定を

追加すれば変更できる。 さらなる情報は、パッチに入っている exiscan-acl-spec.txt ファイル [訳注:Exim 4.50版では spec.txt の 40節] を見てほしい。

49

Page 62: Spam Filtering for MX (ja) / メール交換機でのスパム排除

この実装では、スパムに選別されたメッセージを拒否している。しかし、このようなメッセージの写し

を、少なくともしばらくの間は、 別のメールフォルダに保存しておくとよい。これは、 偽陽性 [76]がないかをユーザがときどき調べられるようにするためだ。

Eximには、受け付けたメッセージに適用できる制御子がある。 freezeといったものだ。 Exiscan-ACLパッチでは、もうひとつ制御子が増える。 fakerejectだ。これは、以下のような SMTP 応答をさせる:

550-FAKEREJECT id=メッセージ ID

550-Your message has been rejected but is being kept for evaluation.

550 If it was a legit message, it may still be delivered to the target recipient(s).

以下の設定の断片を [acl data] [36]の中の最後の accept 文より前に挿入すれば、この仕様を採り入れら

れる:

# SpamAssassinを呼び出して, $spam_score と $spam_report を得る.

# 選別結果に応じて, $acl_m9 に "ham" か "spam" をセットする.

#

# メッセージが spam に選別されたら, 拒否したふりをする.

#

warn

set acl_m9 = ham

spam = mail

set acl_m9 = spam

control = fakereject

logwrite = :reject: Rejected spam (score $spam_score): $spam_report

# メッセージに適切な X-Spam-Status: ヘッダを追加する.

#

warn

message = X-Spam-Status: \

${if eq {$acl_m9}{spam}{Yes}{No}} (score $spam_score)\

${if def:spam_report {: $spam_report}}

logwrite = :main: Classified as $acl_m9 (score $spam_score)

この例では、はじめ $acl m9を「ham」にセットしてある。SpamAssassinを mailユーザで呼び出す。

メッセージがスパムに選別されたら $acl m9に「spam」をセットし、上記の FAKEREJECT 応答を発行す

る。 最後に、X-Spam-Status: ヘッダをメッセージに追加する。 これは何かというと、 メール配送エー

ジェント [79]や受信者のメール利用者エージェント [79]がこのヘッダを使って 不要メールを別のフォルダへ移動できるようにするためのものだ。

A.10.2 SpamAssassinの設定

既定では、SpamAssassin は詳細な表形式で報告を出す。 これはメッセージの本体に入れたり添付したりするのにはかなり向いている。ここでは、報告は上の例の X-Spam-Status: ヘッダに向くような簡潔な

ものであってほしい。このようにするには、サイト独自の設定ファイル (/etc/spamassassin/local.cf、/etc/mail/spamassassin/local.cf など) に、つぎの断片を追加する:

### 報告の雛型

clear_report_template

report "_TESTSSCORES(, )_"

50

Page 63: Spam Filtering for MX (ja) / メール交換機でのスパム排除

また、Bayes式得点づけの仕様があって、 既定では有効になっている。これは通常は無効にしたい。なぜなら、これにはユーザそれぞれに特化した学習が必要で、システム全体の SMTPの時点での排除には向かないからだ:

### Bayes式得点づけを無効にする

use_bayes 0

以上の変更が効くようにするには、 SpamAssassinデーモン (spamd) を再起動しなければならない。

A.10.3 ユーザごとの設定とデータ

SpamAssassin で個人的な設定 (スパム判定の閾値、受け入れる言語や文字集合、 送信者のホワイトリストやブラックリストなど)を指定したいというユーザも、若干はいるだろう。また、SpamAssassin 組み込みの Bayes式得点づけを わざわざ使いたいというユーザもいるかもしれない (私には理由がわからないが13)。この文書の前のほうの[ユーザごとの設定とデータ] [26]の節で述べたように、こうなるようにする方法はある。外部から来るメールの配送ごとに、受信者の数を 1件に限るのだ。発信者が発行する RCPT TO:

コマンドのうち最初のものだけを受け付け、以降のものは 451 SMTP応答を使って延期する。グレーリスト法と同じく、送り手が正しく動作するMTAならばこの応答の解釈のしかたはわかるから、後で再試行してくる。

A.10.3.1 Eximが配送ごとに一つの受信者しか受け付けないようにする

[acl rcpt to] [64] の、受信者アドレスの確認の後、 リモートホストからローカルユーザの認証されていない配送に関する文の前 (つまり、どのグレーリスト検査、エンヴェロープシグネチャ検査、などよりも前) に、以下の文を挿入する:

# 外部から来るメッセージごとの受信者の数を 1件に限って, ユーザごとの設定と

# データ (例えば SpamAssassin のための) に対応する.

#

# 注意: 自分のサイトの複数のユーザに送られるメールは, 受信者ごとに 30分ま

# たはそれ以上遅れていく. これは, 内部と外部の関係者にまたがるよう

# なやりとりのペースを著しく遅める.

#

defer

message = We only accept one recipient at a time - please try later.

condition = $recipients_count

A.10.3.2 SpamAssassinに受信者のユーザ名を渡す

[acl data] [69] で、 前節で追加した spam 条件を変更して、 受信者アドレスのローカル部で決まるユー

ザ名を SpamAssassin に渡すようにする。

# SpamAssassinを呼び出して, $spam_score と $spam_report を得る.

# 選別結果に応じて, $acl_m9 に "ham" か "spam" をセットする.

#

# 受信者アドレスが示すユーザ名を渡す, つまり, どの ’=’ 文字や ’@’

13Bayes 式学習が各々のユーザに特化したものになるのは確かだが、 SpamAssassin の Bayes 式選別機能は (これは私の意見だが)どんな場合でもそれほど有能ではないことに注意しなければならない。スパム送信者がでたらめな辞書単語や文章をメールの中に(例えば HTML メッセージのメタデータに) 入れ込んでこういうシステムを打ち破るテクニックを学んでしまっている場合は、特にそうなるようだ。

51

Page 64: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# 文字よりも前の部分を, 小文字に変換して渡す. 複数の受信者が現れて

# はいけない. さっき, 配送を一度に一受信者に限ったのだから.

#

# メッセージがスパムに選別されたら, 拒否したふりをする.

#

warn

set acl_m9 = ham

spam = ${lc:${extract{1}{=@}{$recipients}{$value}{mail}}}

set acl_m9 = spam

control = fakereject

logwrite = :reject: Rejected spam (score $spam_score): $spam_report

Exim の ${local part:...} 関数を使ってユーザ名を得るのではなく、 すべての 「@」 文字や 「=」文字よりも前の部分を展開するようにしていることに注意。 理由は、後のエンヴェロープシグネチャ方式

でこの「=」文字を利用するからだ。

A.10.3.3 SpamAssassinでユーザごとの設定を有効にする

では、再び SpamAssassinを見てみよう。最初に、サイト全体の設定ファイルで use bayes 0を削除す

ることにしたかもしれないが、今はどんな場合でも、この設定を上書きするかどうかを各々のユーザが自

分で決めることができる。

システムのメールボックスが ホームディレクトリのあるローカルの UNIXアカウントに直接対応しているのなら、 もうやることはない。既定では、 SpamAssassin デーモン (spamd) は 渡したユーザ名でsetuid() を実施し、ユーザのデータや設定をそのユーザのホームディレクトリの中に格納する。

そうでない場合 (例えば、メールアカウントを Cyrus SASLなどのサーバで管理している場合)、各ユーザの設定とデータファイルの場所の見つけかたを SpamAssassin に教えてやらなければならない。 また、存在しないユーザに対しては spamdが setuid()しようとするのではなく、特定のローカルユーザとし

て実行するようにする必要がある。

このようにするには、 spamd の起動の際に次のようなオプションを指定する:

• Debian システムでは、 /etc/default/spamassassin の OPTIONS= の設定を変更する。

• RedHat システムでは、 /etc/sysconfig/spamassassin の SPAMDOPTIONS= 設定を変更する。

• 他のシステムでも、推して知るべし、だ。

必要なオプションは:

• -u ユーザ名 — spamd を実行するユーザを指定する (例えば mail)

• -x — ユーザのホームディレクトリの設定ファイルを無効にする。

• --virtual-config-dir=/var/lib/spamassassin/%u — ユーザごとの設定とデータを格納する場

所を指定する。「%u」は呼び出したユーザ名に置き換わる。 spamd は、このディレクトリを作

成したり変更したりできなければならない:

# mkdir /var/lib/spamassassin

# chown -R mail:mail /var/lib/spamassassin

言うまでもなく、以上のような変更をした後は、 spamd を再起動する必要がある。

52

Page 65: Spam Filtering for MX (ja) / メール交換機でのスパム排除

A.11 エンヴェロープ送信者のシグネチャを追加する

ここでは、外部へ行くメールの[エンヴェロープ送信者のシグネチャ] [22]を実装し、外部からの「バウンス」 (つまりエンヴェロープ送信者のないメール) を受け付ける前にこのシグネチャを検査する。自ホストから外部へ行くメールのエンヴェロープ送信者アドレスを、以下のように変更する:

送信者=受信者=受信者の.ドメイン=ハッシュ@送信者の.ドメイン

ただし、この方式は好ましくない結果を生むことがあるので (例えばメーリングリストサーバの場合)、ユーザごとに選択できるようにする。送信者のホームディレクトリに「 .return-path-sign」という名前のファイルがあるときだけ、かつ送り先のドメインがそのファイルの内容と一致するときだけ、外部へ行く

メールのエンヴェロープ送信者アドレスにサインする。ファイルが存在しているが空ならば、どのドメイ

ンとも一致することにする。

同様に、このファイルが受信者のホームディレクトリにあるときは、外部からの「バウンス」メッセー

ジ (つまり エンヴェロープ送信者のないメッセージ) にだけ受信者アドレスのサインが要る。 ユーザは特定のホワイトリストを使って特定のホストがこの検査をうけないようにできる。 [転送されてきたメールを通す] [58] で述べるようにすればできる。なお、この方式には ACLに加えてルータやトランスポートの変更も伴うので、後の[できあがった ACL]

[60]には含めていない。 これらの節に関する説明のとおりにやるのなら、ここで述べる ACL節も追加しなければならない。

A.11.1 送信者アドレスに署名するためのトランスポートを作成する

まず、Eximのトランスポートをひとつ作成する。これは、リモート配送でエンヴェロープ送信者にサインするのに使う:

remote_smtp_signed:

debug_print = "T: remote_smtp_signed for $local_part@$domain"

driver = smtp

max_rcpt = 1

return_path = $sender_address_local_part=$local_part=$domain=\

${hash_8:${hmac{md5}{SECRET}{${lc:\

$sender_address_local_part=$local_part=$domain}}}}\

@$sender_address_domain

送信者アドレスの「ローカル部」は、つぎの部品を等号 (「=」) で区切ったものになる:

• 送信者のユーザ名、つまり元のローカル部と、

• 受信者アドレスのローカル部と、

• 受信者アドレスのドメイン部と、

• この送信者/受信者の組合せに特有の文字列。次のもので生成する:

– 先に書き換えた送信者アドレスの 3つの部分を、Eximの ${hmac{md5}...}関数を使って、首節で定義した SECRET とともに暗号化し14、

14これはこりすぎだと思う人もいるかもしれないし、 見かけの上では私も賛成だ。この文書の前の版では、 シグネチャの最後の部分を生成するのに ${hash 8:SECRET=....} を使っていた。しかしこれでは、いくらか Exim の ${hash...} 関数を分析し、別々の受信者に送られた外部へ行くメールのサンプルを手に入れれば、 シグネチャを偽造することが技術的には可能になり得る。Matthew Byng-Maddic <mbm a©colondot.net> の注: 書いた文書は、多くの人々に複写されて送られることがあり得る。 そうなると、 Kerckhoffの原則 [訳注: 暗号化に使用するアルゴリズムは 解読を試みる者にとっては既知のものであると仮定しなければならない、 という原則] が適用されることになり、守秘性は鍵のみに依存してしまう。 鍵が復元できれば、 スパム送信者は そのドメインからの有効な返送経路にメールを送り込むことができるようになる。 [...] 最初から強力なものにしておくのがいいと思う。

53

Page 66: Spam Filtering for MX (ja) / メール交換機でのスパム排除

– Eximの ${hash...} 関数を使って、結果を小文字 8文字のハッシュにする。

「スマートホスト」への配送を認証する必要があるときは、ここで適切な hosts try auth 行も追加する

(すでにあるスマートホストのトランスポートから取ってくる)。

A.11.2 リモート配送のためのルータを新たに作成する

現在外部へ行くメールを扱っているルータ (複数あるかもしれない) の前に、新たにルータを追加する。このルータは、リモート配送には上記のトランスポートを使うが、送信者のホームディレクトリにファイ

ル「 .return-path-sign」が存在し、かつ、受信者のドメインがこのファイルの内容に一致するときだけである。 例えばメールをインターネットを通じて最終目的地に送っているのなら:

# 送信者のホームディレクトリにファイル ".return-path-sign" があり, さらに

# リモートのドメインがそのファイルの内容と一致すれば, エンヴェロープ送信者のアド

# レス (返送経路) にリモートのドメイン向けのサインをする. ファイルが存在している

# が空なら, 必ずエンヴェロープ送信者にサインする.

#

dnslookup_signed:

debug_print = "R: dnslookup_signed for $local_part@$domain"

driver = dnslookup

transport = remote_smtp_signed

senders = ! : *

domains = ! +local_domains : !+relay_to_domains : \

${if exists {/home/$sender_address_local_part/.return-path-sign}\

{/home/$sender_address_local_part/.return-path-sign}\

{!*}}

no_more

あるいは、スマートホストを使っているのなら:

# 送信者のホームディレクトリにファイル ".return-path-sign" があり, さらに

# リモートのドメインがそのファイルの内容と一致すれば, エンヴェロープ送信者のアド

# レス (返送経路) にリモートのドメインへの配送のためのサインをする. ファイルが存

# 在しているが空なら, 必ずエンヴェロープ送信者にサインする.

#

smarthost_signed:

debug_print = "R: smarthost_signed for $local_part@$domain"

driver = manualroute

transport = remote_smtp_signed

senders = ! : *

route_list = * スマートホストのアドレス

host_find_failed = defer

domains = ! +local_domains : !+relay_to_domains : \

${if exists {/home/$sender_address_local_part/.return-path-sign}\

{/home/$sender_address_local_part/.return-path-sign}\

{!*}}

no_more

その他、適当なオプションを追加する (例えば same domain copy routing = yes)。たぶんすでに存在するルータの後にある。

54

Page 67: Spam Filtering for MX (ja) / メール交換機でのスパム排除

エンヴェロープ送信者アドレスのないメールには、このルータを使わないことに注意 —これらのものは

改竄しない15!

A.11.3 ローカル配送のための転向ルータを新たに作成する

次に、上の形式に一致する外部からの受信者アドレスを、最初の等号 (「=」) より前の部分で特定されるメールボックスに配送するよう、 Eximに教える必要がある。 この目的のためには、 設定ファイルのrouters 節の最初のほう — ローカル配送 (システム エイリアス ルータのような) に関するどのルータよりも前 — に、redirect [転向] ルータを挿入するといい:

hashed_local:

debug_print = "R: hashed_local for $local_part@$domain"

driver = redirect

domains = +local_domains

local_part_suffix = =*

data = $local_part@$domain

等号を含む受信者アドレスを書き換えて、ローカル部の等号に続く部分を取り去る。それから、再び全

てのルータで処理する。

A.11.4 ACLシグネチャの検査

この方式の最後の部分では、有効な受信者アドレスに配送するメールはシグネチャが 必ず受け付けられ

るものでなければならないこと、いっぽうエンヴェロープ送信者が空のメッセージは 受信者がこの方式に

自分で加入していれば拒否しなければならないことを、 Eximに教える。どちらの場合にも、グレーリスト法を行なってはならない。

以下の断片は、[acl rcpt to] [64] で、どの SPF検査やグレーリスト法よりも前、最後の accept 文より

も前に置かなければならない:

# 受信者アドレスに自分自身のシグネチャが入っていれば, 受け付ける.

# このことは, 以前にここから送ったこれがメッセージへの応答 (DSN,

# 送信者呼出し確認法...) であるという意味である.

#

accept

domains = +local_domains

condition = ${if and {{match{${lc:$local_part}}{^(.*)=(.*)}}\

{eq{${hash_8:${hmac{md5}{SECRET}{$1}}}}{$2}}}\

{true}{false}}

# そうでないとき, メッセージがバウンスとみなされる (つまりエンヴェロープ送信者

# がない) のに受け手がエンヴェロープ送信者のシグネチャを使って検査すると決めて

# いるのなら, 拒否する.

#

deny

message = This adress does not match a valid, signed \

return path from here.\n\

You are responding to a forged sender address.

log_message = bogus bounce.15上記の例では、 senders 条件が実際には重複している。 ファイル /home//.return-path-sign は存在しないかもしれないためだ。しかし、明確化のために強いてこの条件を作った。

55

Page 68: Spam Filtering for MX (ja) / メール交換機でのスパム排除

senders = : postmaster@*

domains = +local_domains

set acl_m9 = /home/${extract{1}{=}{${lc:$local_part}}}/.return-path-sign

condition = ${if exists {$acl_m9}{true}}

メッセージのヘッダのアドレス (自ホストから外部へ行くメールの From: にあるもののような) に対して呼出し確認法を実施しているホストへメールを送るときには、問題がある。 deny [拒絶] 文が、このような確認の試みに対して否定的な応答をしてしまう。

このため、最後の deny 文を warn 文に変更し、拒否メッセージを $acl m0に保管しておき、実際の拒

否は DATA コマンドの後で実施する、というようにしたほうがよいかもしれない。これは、先に説明し

たのと似たやりかただ:

# そうでないとき, メッセージがバウンスとみなされる (つまりエンヴェロープ送信者

# がない) のに受け手がエンヴェロープ送信者のシグネチャを使って検査すると決めて

# いるのなら, 拒否メッセージを $acl_m0 に, 記録メッセージを $acl_m1 に入れる.

# これは, 後でメールを拒否するのに使う. しばらくの間, これらの存在によって, 送

# 信者を足止めしておかなければならないことを示す.

#

warn

senders = : postmaster@*

domains = +local_domains

set acl_m9 = /home/${extract{1}{=}{${lc:$local_part}}}/.return-path-sign

condition = ${if exists {$acl_m9}{true}}

set acl_m0 = The recipient address <$local_part@$domain> does not \

match a valid, signed return path from here.\n\

You are responding to a forged sender address.

set acl_m1 = bogus bounce for <$local_part@$domain>.

なお、受信者は、エンヴェロープ送信者のシグネチャを外部へ行くメールで使うことにしているときで

も、特定のホストを外部から来るメールにこのシグネチャをつけることから除きたがるかもしれない。こ

れは、特殊なメーリングリストサーバで必要になるかもしれない。詳しくは、[エンヴェロープ送信者のシグネチャ] [22]の議論を見てほしい。

A.12 実在するユーザへのバウンスだけを受け付ける

[実在するユーザへのバウンスだけを受け付ける] [24]で述べたように、エンヴェロープ送信者のシグネチャ検査にはまだ抜け穴がある。システムユーザや (postmaster のような) エイリアスにいんちきな配送状況通知 [78]が届くのを防がなければならない。ここでは、外部へ行くメールを実際に送信するユーザへのバウンスだけを受け付けるようにするための方法を、 2通り説明する。

A.12.1 受信者のメールボックスの検査

最初の方式は、 [acl rcpt to] [64] ACL で実施するものだ。この方法では、 受信者アドレスがローカルのメールボックスに対応づけられるかどうかを検査する:

# 送信者アドレスが与えられなければ, メールボックスのないユーザ (つまり postmaster,

# webmaster...) へのメールを拒絶する. こういったユーザは外部へ行くメールを送ること

# はないので, 返送されてくるメールを受け取るはずがない.

#

deny

56

Page 69: Spam Filtering for MX (ja) / メール交換機でのスパム排除

message = This address never sends outgoing mail. \

You are responding to a forged sender address.

log_message = bogus bounce for system user <$local_part@$domain>

senders = : postmaster@*

domains = +local_domains

!mailbox check

困ったことに、mailbox checkの箇所を実際にどう実施するかは、メールをどう配送しているかに依存

してしまう (なおその前に、受信者アドレスの最初の「=」記号より前の部分を展開して、エンヴェロープ送信者のシグネチャに役立つようにしておく):

• メールボックスが自サーバのローカルのユーザアカウントに対応しているのなら、 受信者名がシステムの「通常の」ユーザにあたるユーザ IDに対応している (例えば 500から 60000 の範囲にある)かどうかを検査すればいい:

set acl_m9 = ${extract{1}{=}{${lc:$local_part}}}

set acl_m9 = ${extract{2}{:}{${lookup passwd {$acl_m9}{$value}}}{0}}

condition = ${if and {{>={$acl_m9}{500}} {<${acl_m9}{60000}}} {true}}

• メールを Cyrus16 IMAP スイートへ配送しているのなら、それに入っている mbpathコマンドライ

ン ユーティリティを使って メールボックスの存在を検査することができる。 Exim ユーザがメールボックスを検査できる権限をもつようにしたほうがいいだろう (例えば、このユーザを cyrusグルー

プに入れる: # adduser exim4 cyrus)。

set acl_m9 = ${extract{1}{=}{${lc:$local_part}}}

condition = ${run {/usr/sbin/mbpath -q -s user.$acl_m9} {true}}

• メールをすべてリモートの計算機へ転送してそこで配送しているのなら、 [受信者呼出し確認法] [14]を実施して、 その計算機がメールを受け付けるかどうか判断する必要があるかもしれない。 呼出

し17の際は、元のエンヴェロープ送信者を手付かずにしておく必要がある:

verify = recipient/callout=use_sender

このメールボックス検査は、 メールを内部的に配送している場合にはルータで実施する処理の一部と重複

するし、サイトのメール配送機構によっても違ってくるので、完全主義者の皆さんにはぶざまに見えるか

もしれない。 そこで、別の方法も紹介しておこう。

A.12.2 エイリアスルータでの空送信者の検査

たぶん、 system aliases というような名前のルータがあるだろう。これは メールを postmaster や

mailer-demon のようなユーザに転向させる。 一般に、こういうエイリアスは外部へ行くメールの送信者

アドレスには使わない。だから、外部から来た配送状況通知 [78]がこのルータを通らないようにできる。ルータに以下の条件を追加する:

!senders = : postmaster@*

エイリアスルータは、たとえばこんなふうになる:

16http://asg.web.cmu.edu/cyrus/17[訳注] callout。

57

Page 70: Spam Filtering for MX (ja) / メール交換機でのスパム排除

system_aliases:

driver = redirect

domains = +local_domains

!senders = : postmaster@*

allow_fail

allow_defer

data = ${lookup{$local_part}lsearch{/etc/aliases}}

user = mail

group = mail

file_transport = address_file

pipe_transport = address_pipe

これで、システムエイリアスの一部へ行くバウンスは阻止できるが、他のエイリアスでは実在するシス

テムユーザ (「root」、「daemon」などのような) が隠れてしまう。 accept driverを通じてローカルでメールを配送し、 check local user で受信者アドレスを確認しているときは、こういったシステムアカ

ウントへはメールを直接ルーティングしたいだろう。

この問題を直すために、ローカルのメールを扱うルータ (例えば local user) にさらに条件を追加して、受信者が存在するだけでなく「普通の」ユーザでもあるようにしたい。 例えば、上で述べたのと同じよ

うに、ユーザ IDが 500 から 60000 の範囲にあるかどうかを検査する:

condition = ${if and {{>={$local_user_uid}{500}}\

{<{$local_user_uid}{60000}}}\

{true}}

ローカル配送のルータは、たとえばこんなふうになる:

local_user:

driver = accept

domains = +local_domains

check_local_user

condition = ${if and {{>={$local_user_uid}{500}}\

{<{$local_user_uid}{60000}}}\

{true}}

transport = transport

この方式を実装するときは、システムユーザ宛のいんちきバウンスメールへのサーバからの拒否応答が

受信者が不明のとき (ここでは 550 Unknown User) と同じになるよう気をつけよう。

A.13 転送されてきたメールを通す

これで SMTPトランザクションでの検査はすべて追加したが、ここでひとつ気づいたことがある。メーリングリストや他のサイトのメールアカウントのような信頼できる出所 から転送されてきたメールを拒否

しているために、間接的に巻き添えスパムを発生させているのだ (詳しくは、[転送されてきたメール] [25]についての議論を見てほしい)。こういうホストはホワイトリストに入れて、SMTPでの拒否 — 少なくと

も、スパムやウィルスの排除によって起こる拒否だけでも — から除外する必要がある

以下の例では、RCPT TO: コマンド ごとに応答する際に、 2つのファイルを参照することにする:

• サイト全体のホワイトリスト /etc/mail/whitelist-hosts。 これには、バックアップ MXホストと、その他ホワイトリストに入れる送信者?を記述する。それと、

58

Page 71: Spam Filtering for MX (ja) / メール交換機でのスパム排除

• ユーザ固有のリスト /home/ユーザ/.forwarders。 これには、それぞれのユーザが転送されてきた

メールを受け取るホスト (例えばメーリングリストサーバ、よそのアカウントの送出用メールサーバ...)を記述する。

メールユーザにローカルのユーザアカウントもホームディレクトリもなければ、ファイルのパスや検索機

構をなにかもっと自分のシステムにあうもの (例えばデータベース検索や LDAP 問合せ) に変えるとよいかもしれない。

送信者ホストがこれらのホワイトリストのどれかに見つかったら、 先の[選択的な遅延] [38]の節で説明したように、 $acl m0に「accept」という語を保存し、 $acl m1 の内容を消去する。これによって、引

き続く文でメールを拒否してはいけないことを示す。

[acl rcpt to] [64] で、受信者アドレスの確認の後、ただしリモートホストからローカルユーザへの認証されていない配送に関する accept 文より前に (つまりグレーリストの検査、エンヴェロープシグネチャの検査、などより前に)、以下の文を挿入する:

# 送信側のホストが全体のホワイトリストファイルの内容と一致すれば, 受け

# 入れる. 一時的に $acl_m9 をセットして, このファイルを指すようにす

# る. ホストが見つかったら, $acl_m0 のフラグをセットして $acl_m1

# を消し, このメールは今後拒否してはいけないということを示す.

#

accept

set acl_m9 = /etc/mail/whitelist-hosts

hosts = ${if exists {$acl_m9}{$acl_m9}}

set acl_m0 = accept

set acl_m1 =

# 送信側のホストが受信者のホームディレクトリの ".forwarders" ファイルの内容

# と一致すれば, 受け入れる. 一時的に $acl_m9 をセットして, このファイルを指

# すようにする. ホストが見つかったら, $acl_m0 のフラグをセットして $acl_m1

# を消し, このメールは今後拒否してはいけないということを示す.

#

accept

domains = +local_domains

set acl_m9 = /home/${extract{1}{=}{${lc:$local_part}}}/.forwarders

hosts = ${if exists {$acl_m9}{$acl_m9}}

set acl_m0 = accept

set acl_m1 =

[acl data] [69] ACLにあるさまざまな文では、 $acl m0 の内容を検査して、上のようにセットしてあれ

ば、 メールを拒否しないようにする。例えば、 RFC2822 ヘッダがないメールがホワイトリストにあるホストから来たら、拒否しないようにする:

deny

message = Your message does not conform to RFC2822 standard

log_message = missing header lines

!hosts = +relay_from_hosts

!senders = : postmaster@*

condition = ${if !eq {$acl_m0}{accept}{true}}

condition = ${if or {{!def:h_Message-ID:}\

{!def:h_Date:}\

{!def:h_Subject:}} {true}{false}}

59

Page 72: Spam Filtering for MX (ja) / メール交換機でのスパム排除

書き換えた検査は、次節の[できあがった ACL] [60]に入れてある。

A.14 できあがったACL

よーし、起きる時間だよ。ずいぶん長い読み物になってしまったが、とうとう出来上がりだ!以下の ACL には、この実装で説明してきた検査がすべて入っている。しかし、コメントアウトしてあ

るものもいくつかある。次のような理由からだ:

• グレーリスト法。これには、追加のソフトウェアのインストールか、 Eximの設定ファイルへのかなり複雑な設定や ACLの追加が要る。だが、これは強くお勧めする。

• ウィルス検出。スパムの同定に使われている SpamAssassinのような、だれでもがほぼ普遍的に使っている検出ソフトウェアがない。 いっぼう、Exiscan-ACL についてくる文書を見れば簡単に実施で

きる。

• SpamAssassinのユーザごとの設定。これは、どれくらい多くのひとにとって受け入れられるかとのトレードオフになる。 最初の受信者以外は次第にメールが遅れていくためだ。

• エンヴェロープ送信者のシグネチャ。 例えば、ローミングをするユーザには悪影響がある。 また、ACLだけでなくルータとトランスポートの設定も必要になってくる。 詳細は上節を見てほしい。

• 実ユーザ宛のバウンスのみの受け入れ。これをする方法はいくつかあり、ユーザが実在かどうか決定する方法は メールの配送のしかたによって違ってくる。

問題になるのはこれだけだ。さて、待ちに待った最終結果を披露しよう。

A.14.1 acl connect

# このアクセス制御リストは, 外部からの接続の開始の際に使う.

# 検査は順に実行され, 接続を受け付けるか拒否するまで続く.

acl_connect:

# 以降の遅延の継続期間を計算するために, 現在のタイムスタンプを記録する

warn

set acl_m2 = $tod_epoch

# ローカルの SMTP経由 (つまり TCP/IP経由ではない) で受信したメールを受け入れる.

# 空の送信側ホスト項目をテストすることでこれを行なう.

# また, メールをリレーするためのホストから受信したメールも受け入れる.

accept

hosts = : +relay_from_hosts

# 接続してきているホストが DNSbl のどれかに登録されていれば,

# $acl_c1 に警告メッセージを用意する. このメッセージは, 後でメールヘッダに

# 追加する. 送信者を足止めしなければいけないことを, しばらくの間これの存在で

# 示す.

#

60

Page 73: Spam Filtering for MX (ja) / メール交換機でのスパム排除

warn

!hosts = ${if exists {/etc/mail/whitelist-hosts} \

{/etc/mail/whitelist-hosts}}

dnslists = list.dsbl.org : \

dnsbl.sorbs.net : \

dnsbl.njabl.org : \

bl.spamcop.net : \

dsn.rfc-ignorant.org : \

sbl-xbl.spamhaus.org : \

l1.spews.dnsbl.sorbs.net

set acl_c1 = X-DNSbl-Warning: \

$sender_host_address is listed in $dnslist_domain\

${if def:dnslist_text { ($dnslist_text)}}

# 同様に, 送信者のホストの DNS 逆引きが失敗したら (つまり, DNS逆引きエントリ

# がないか, ホスト名の正引きの結果が元の IPアドレスに一致しなければ), $acl_c1

# に警告メッセージを生成する. このメッセージは, 後でメールヘッダに追加する.

warn

condition = ${if !def:acl_c1 {true}{false}}

!verify = reverse_host_lookup

set acl_m9 = Reverse DNS lookup failed for host $sender_host_address

set acl_c1 = X-DNS-Warning: $acl_m9

# 送信者を受け付ける. ただし, 前に $acl_c1 にメッセージを生成しているのなら,

# 20秒が経過するまで送信者を足止めする.

accept

set acl_m2 = ${if def:acl_c1 {${eval:20 + $acl_m2 - $tod_epoch}}{0}}

delay = ${if >{$acl_m2}{0}{$acl_m2}{0}}s

A.14.2 acl helo

# このアクセス制御リストは, 外部から来る SMTPトランザクションの MAIL FROM:

# コマンドに使う. テストは順に実行され, 送信者アドレスが受け付けられるか拒否

# されるかすると, そこで終る.

acl_helo:

# 以降の遅延の継続期間を計算するために, 現在のタイムスタンプを記録する

warn

set acl_m2 = $tod_epoch

# ローカルの SMTP経由 (つまり TCP/IP経由ではない) で受信したメールを受け入れる.

# 空の送信側ホスト項目をテストすることでこれを行なう.

# また, メールをリレーするためのホストから受信したメールも受け入れる.

61

Page 74: Spam Filtering for MX (ja) / メール交換機でのスパム排除

#

accept

hosts = : +relay_from_hosts

# リモートホストが IPアドレスで挨拶したら, $acl_c0 に拒否メッセージを,

# $acl_c1 に記録用メッセージを用意する. これらは後で "deny" 文の中で使う.

# しばらくの間, これらの存在で送信者を足止めしておかなければならないことを示す.

#

warn

condition = ${if isip {$sender_helo_name}{true}{false}}

set acl_c0 = Message was delivered by ratware

set acl_c1 = remote host used IP address in HELO/EHLO greeting

# サーバ自身の名前のどれかで相手が挨拶したときも同様

#

warn

condition = ${if match_domain{$sender_helo_name}\

{$primary_hostname:+local_domains:+relay_to_domains}\

{true}{false}}

set acl_c0 = Message was delivered by ratware

set acl_c1 = remote host used our name in HELO/EHLO greeting.

# HELOの確認が失敗したら, acl_c1 に警告メッセージを用意する.

# このメッセージは, 後でメールヘッダに追加する.

# 送信者を足止めしておかなければならないことを, しばらくの間これの存在で示す.

#

warn

condition = ${if !def:acl_c1 {true}{false}}

!verify = helo

set acl_c1 = X-HELO-Warning: Remote host $sender_host_address \

${if def:sender_host_name {($sender_host_name) }}\

incorrectly presented itself as $sender_helo_name

log_message = remote host presented unverifiable HELO/EHLO greeting.

# 接続を受け付ける. ただし, 前に $acl_c1 にメッセージを生成しているのなら,

# 20秒が経過するまで送信者を足止めする.

accept

set acl_m2 = ${if def:acl_c1 {${eval:20 + $acl_m2 - $tod_epoch}}{0}}

delay = ${if >{$acl_m2}{0}{$acl_m2}{0}}s

A.14.3 acl mail from

# このアクセス制御リストは, 外部から来る SMTPトランザクションの MAIL FROM:

62

Page 75: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# コマンドに使う. テストは順に実行され, 送信者アドレスが受け付けられるか拒否

# されるかすると, そこで終る.

#

acl_mail_from:

# 以降の遅延の継続期間を計算するために, 現在のタイムスタンプを記録する

warn

set acl_m2 = $tod_epoch

# ローカルの SMTP経由 (つまり TCP/IP経由ではない) で受信したメールを受け入れる.

# 空の送信側ホスト項目をテストすることでこれを行なう.

# また, メールをリレーするためのホストから受信したメールも受け入れる.

#

# 送信者確認はここではしない. しばしば, クライアントが低能な MUA で,

# こういったものは SMTPエラー応答にうまく対応できないためだ.

#

accept

hosts = : +relay_from_hosts

# メッセージが認証された接続を通じて届いたら, どのホストからでも受け付ける.

# ここでも, こういったメッセージは普通は MUA からのものだ.

#

accept

authenticated = *

# ACL 変数 $acl_c0 と $acl_c1 がもしあれば, 拒否や警告のメッセージを含んでいる

# ので, この SMTPトランザクションでの配送の試みひとつひとつにこれを適用する.

# これらの変数をメッセージごとの $acl_m{0,1} 変数に代入し, $acl_m1 の警告メッ

# セージをメッセージヘッダに追加する (拒否の場合は, $acl_m1 には記録用メッセージ

# が入っていることになるが, かまわない. ヘッダを追加するはずのメッセージはどうせ

# 破棄するのだから).

#

warn

set acl_m0 = $acl_c0

set acl_m1 = $acl_c1

message = $acl_c1

# 送信者が HELO/EHLO 挨拶をまったくしなければ, $acl_m0 に拒否メッセージを,

# $acl_m1 に記録メッセージを用意する. これらは後で "deny" 文で使う.

# 送信者を足止めしておかなければならないことを, しばらくの間これらの存在で示す.

#

warn

condition = ${if def:sender_helo_name {0}{1}}

set acl_m0 = Message was delivered by ratware

63

Page 76: Spam Filtering for MX (ja) / メール交換機でのスパム排除

set acl_m1 = remote host did not present HELO/EHLO greeting.

# 送信者アドレスが確認できなければ, $acl_m1 に警告メッセージを作成して,

# メールヘッダに追加する.

# 送信者を足止めしておかなければならないことを, しばらくの間これの存在で示す.

#

# "callout" [呼出し] オプションを省くことにしてもよい. 特に, 外部へ行くメー

# ルをスマートホストを通じて送っているときは, これは有用な情報をなにも与えて

# くれない.

#

warn

condition = ${if !def:acl_m1 {true}{false}}

!verify = sender/callout

set acl_m1 = Invalid sender <$sender_address>

メッセージ = X-Sender-Verify-Failed: $acl_m1

log_message = $acl_m1

# 送信者を受け付ける. ただし, 前に $acl_c1 にメッセージを生成しているのなら,

# 20秒が経過するまで送信者を足止めする.

accept

set acl_m2 = ${if def:acl_c1 {${eval:20 + $acl_m2 - $tod_epoch}}{0}}

delay = ${if >{$acl_m2}{0}{$acl_m2}{0}}s

A.14.4 acl rcpt to

# このアクセス制御リストは, 外部からの SMTP メッセージの RCPT コマンドごと

# に使う. テストは順に実行され, 受信者アドレスが受け付けられるか拒否される

# かすると, そこで終る.

acl_rcpt_to:

# ローカルの SMTP経由 (つまり TCP/IP 経由でない) で受け取ったメールを受

# け付ける. 空の送信側ホスト項目でこれをテストする.

# また, メールのリレーのためのホストからのメールも受け付ける.

#

# 受信者確認はここではしない. しばしば, クライアントが低能な MUA で,

# こういったものは SMTPエラー応答にうまく対応できないためだ.

#

accept

hosts = : +relay_from_hosts

# メッセージが認証された接続を通じて届いたら, どのホストからでも受け付ける.

# ここでも, こういったメッセージは普通は MUA からなので, 受信者確認はしない.

#

64

Page 77: Spam Filtering for MX (ja) / メール交換機でのスパム排除

accept

authenticated = *

# ローカル部が @ や % や / や | や ! を含んでいれば拒絶.

# こういったものは, 本物のローカル部にはまず現れないが, リレー制限の抜け穴

# を探す輩がよく試すものだ.

#

# ドットで始まるローカル部なら, これも拒絶. 空のコンポーネントは厳密には

# RFC 2822 違反だが, これはよくあるので Exim では受け入れる. しかし,

# ドットで始まっているものは, ローカル部がファイル名として使われる場合

# (例えばメーリングリストのために) にトラブルを起こすかもしれない.

#

deny

local_parts = ^.*[@%!/|] : ^\\.

# 以前に $acl_m0 に拒絶する理由を入れてあれば拒絶. また, 送信者をさらに 20秒

# 足止めする.

#

deny

message = $acl_m0

log_message = $acl_m1

condition = ${if and {{def:acl_m0}{def:acl_m1}} {true}}

delay = 20s

# 受信者アドレスが我々の扱うドメインのものでなければ, 送信者を足止めしてから

# 拒否.

#

deny

message = relay not permitted

!domains = +local_domains : +relay_to_domains

delay = 20s

# アドレスがローカルのドメインのものかリレーするドメインのものであるのに

# 無効なものなら, 足止めして拒否.

#

deny

message = unknown user

!verify = recipient/callout=20s,defer_ok,use_sender

delay = ${if def:sender_address {1m}{0s}}

# エンヴェロープ送信者が空なのに受信者アドレスが複数あれば, 接続を切る.

# 真っ当な DSN は, 1つより多くのアドレスに送ったりしない.

65

Page 78: Spam Filtering for MX (ja) / メール交換機でのスパム排除

#

drop

message = Legitimate bounces are never sent to more than one \

recipient.

senders = : postmaster@*

condition = $recipients_count

delay = 5m

# --------------------------------------------------------------------

# 外部から来るメッセージごとの受信者の数を 1件に限って, ユーザごとの設定と

# データ (例えば SpamAssassin のための) に対応する.

#

# 注意: 自分のサイトの複数のユーザに送られるメールは, 受信者ごとに 30分ま

# たはそれ以上遅れていく. これは, 内部と外部の関係者にまたがるよう

# なやりとりのペースを著しく遅める.

#

#defer

# message = We only accept one recipient at a time - please try later.

# condition = $recipients_count

# --------------------------------------------------------------------

# 送信側のホストが受信者のホームディレクトリの ".forwarders" ファイルの内容

# と一致すれば, 受け入れる. 一時的に $acl_m9 をセットして, このファイルを指

# すようにする. ホストが見つかったら, $acl_m0 のフラグをセットして $acl_m1

# を消し, このメールは今後拒否してはいけないということを示す.

#

accept

domains = +local_domains

set acl_m9 = /home/${extract{1}{=}{${lc:$local_part}}}/.forwarders

hosts = ${if exists {$acl_m9}{$acl_m9}}

set acl_m0 = accept

set acl_m1 =

# 送信側のホストが全体のホワイトリストファイルの内容と一致すれば, 受け

# 入れる. 一時的に $acl_m9 をセットして, このファイルを指すようにす

# る. ホストが見つかったら, $acl_m0 のフラグをセットして $acl_m1

# を消し, このメールは今後拒否してはいけないということを示す.

#

accept

set acl_m9 = /etc/mail/whitelist-hosts

hosts = ${if exists {$acl_m9}{$acl_m9}}

set acl_m0 = accept

set acl_m1 =

66

Page 79: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# --------------------------------------------------------------------

# エンヴェロープ送信者のシグネチャの検査.

# これは既定ではコメントアウトしてある. なぜなら設定に ’transports’ 節と

# ’routers’ 節の追加が必要だからだ.

#

# 受信者アドレスに自分自身のシグネチャが入っていれば, 受け付ける.

# このことは, 以前にここから送ったこれがメッセージへの応答 (DSN,

# 送信者呼出し確認法...) であるという意味である.

#

#accept

# domains = +local_domains

# condition = ${if and {{match{${lc:$local_part}}{^(.*)=(.*)}}\

# {eq{${hash_8:${hmac{md5}{SECRET}{$1}}}}{$2}}}\

# {true}{false}}

#

# そうでないとき, メッセージがバウンスとみなされる (つまりエンヴェロープ送信者

# がない) のに受け手がエンヴェロープ送信者のシグネチャを使って検査すると決めて

# いるのなら, 拒否する.

#

#deny

# message = This address does not match a valid, signed \

# return path from here.\n\

# You are responding to a forged sender address.

# log_message = bogus bounce.

# senders = : postmaster@*

# domains = +local_domains

# set acl_m9 = /home/${extract{1}{=}{${lc:$local_part}}}/.return-path-sign

# condition = ${if exists {$acl_m9}{true}}

# --------------------------------------------------------------------

# --------------------------------------------------------------------

# 送信者アドレスが与えられなければ, メールボックスのないユーザ (つまり postmaster,

# webmaster...) へのメールを拒絶する. こういったユーザは外部へ行くメールを送ること

# はないので, 返送されてくるメールを受け取るはずがない.

#

# 注意: これは既定ではコメントアウトしてある. なぜなら, メールをどう配送する

# かによって条件が変わってくるからだ. この検査を有効にしたいときは, 下

# 記の条件のどれかひとつだけ, コメントをはずすこと.

#

#deny

# message = This address never sends outgoing mail. \

# You are responding to a forged sender address.

# log_message = bogus bounce for system user <$local_part@$domain>

# senders = : postmaster@*

# domains = +local_domains

# set acl_m9 = ${extract{1}{=}{${lc:$local_part}}}

#

67

Page 80: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# --- 受信者にローカルのアカウントがあるのなら, 以下の 2行のコメントをはずす:

# set acl_m9 = ${extract{2}{:}{${lookup passwd {$acl_m9}{$value}}}{0}}

# !condition = ${if and {{>={$acl_m9}{500}} {<${acl_m9}{60000}}} {true}}

#

# --- メールを Cyrus に配送しているのなら, 以下の行のコメントをはずす:

# condition = ${run {/usr/sbin/mbpath -q -s user.$acl_m9} {true}}

# --------------------------------------------------------------------

# 送信者アドレスのドメインについての SPF情報を問合わせ, もしあれば,

# 送信側のホストがそのメールの配送を認証されているか調べる.

# されていなければ, そのメールは拒否する.

#

deny

message = [SPF] $sender_host_address is not allowed to send mail \

from $sender_address_domain

log_message = SPF check failed.

spf = fail

# メッセージに SPF-Received: ヘッダを追加する

warn

message = $spf_received

# --------------------------------------------------------------------

# この特定の相手/送信者/受信者の三つ組に対するグレーリストの状態を検査する.

# この文のコメントをはずす前に, "greylistd" をインストールする必要がある.

# http://packages.debian.org/unstable/main/greylistd を見てほしい.

#

# 送信者が空のメッセージはグレーリストしないことに注意. なぜなら送信者

# 呼出し確認が失敗する (そのため, 呼出しを実施しているホストへメールを送れ

# なくなりかねない) からだ.

#

#defer

# message = $sender_host_address is not yet authorized to deliver mail \

# from <$sender_address> to <$local_part@$domain>. \

# Please try later.

# log_message = greylisted.

# domains = +local_domains : +relay_to_domains

# !senders = : postmaster@*

# set acl_m9 = $sender_host_address $sender_address $local_part@$domain

# set acl_m9 = ${readsocket{/var/run/greylistd/socket}{$acl_m9}{5s}{}{}}

# condition = ${if eq {$acl_m9}{grey}{true}{false}}

# delay = 20s

# --------------------------------------------------------------------

68

Page 81: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# 受信者を受け付ける.

accept

A.14.5 acl data

# このアクセス制御リストは, SMTPを通じて受け取るメッセージデータに使う.

# テストは順に実行され, 受信者アドレスが受け付けられるか拒絶されたところ

# で終る.

acl_data:

# 一部のヘッダ行を記録する

warn

logwrite = Subject: $h_Subject:

# 自ホストから届いたメッセージに Message-ID がなければ追加する.

warn

condition = ${if !def:h_Message-ID: {1}}

hosts = +relay_from_hosts

message = Message-ID: <E$message_id@$primary_hostname>

# ローカルの SMTP経由 (つまり TCP/IP 経由でない) で受け取ったメールを受け付ける.

# 空の送信側のホスト項目をテストすることで, それを調べる.

# また, メールのリレーに使うホストから受け取ったメールも受け付ける.

#

accept

hosts = : +relay_from_hosts

# メッセージが認証された接続を通じて届いたら, どんなホストでも受け付ける.

#

accept

authenticated = *

# 以前に $acl_m0 に拒絶する理由を入れてあれば拒絶. また, 送信者をさらに 20秒

# 足止めする.

#

deny

message = $acl_m0

log_message = $acl_m1

condition = ${if and {{def:acl_m0}{def:acl_m1}} {true}{false}}

delay = 20s

# メッセージサイズの限度を課す

#

69

Page 82: Spam Filtering for MX (ja) / メール交換機でのスパム排除

deny

message = Message size $message_size is larger than limit of \

MESSAGE_SIZE_LIMIT

condition = ${if >{$message_size}{MESSAGE_SIZE_LIMIT}{yes}{no}}

# アドレスリストのヘッダが構文的に正しくなければ拒絶する.

#

deny

message = Your message does not conform to RFC2822 standard

log_message = message header fail syntax check

!verify = header_syntax

# Message-ID:, Date:, Subject: のない非ローカルメッセージを拒絶するには,

# 以下のもののコメントをはずす.

#

# 一部の特殊化された MTA (ある種のメーリングリストサーバのような) は,

# バウンスの Message-ID を自動的に生成しないことに注意.

# そのため, 空でない送信者の検査も追加する.

#

#deny

# message = Your message does not conform to RFC2822 standard

# log_message = missing header lines

# !hosts = +relay_from_hosts

# !senders = : postmaster@*

# condition = ${if !eq {$acl_m0}{accept}{true}}

# condition = ${if or {{!def:h_Message-ID:}\

# {!def:h_Date:}\

# {!def:h_Subject:}} {true}{false}}

# 少なくとも "Sender:", "Reply-To:", "From:" のヘッダのいずれかに

# 確認できる送信者アドレスがなければ, 警告する.

#

warn

message = X-Sender-Verify-Failed: No valid sender in message header

log_message = No valid sender in message header

!verify = header_sender

# --------------------------------------------------------------------

# ここでは, エンヴェロープ送信者のないメッセージにグレーリスト法を実施する.

# RCPT TO: の後ではこういったものをグレーリスト法にかけていない. なぜなら

# 送信者呼出しをしているリモートホストの邪魔になるからだ.

# 送信者アドレスが空であることに注意. そのため送信者アドレスは使わない.

#

70

Page 83: Spam Filtering for MX (ja) / メール交換機でのスパム排除

# この文のコメントをはずす前に, "greylistd" をインストールする必要がある.

# http://packages.debian.org/unstable/main/greylistd を見てほしい.

#

#defer

# message = $sender_host_address is not yet authorized to send \

# delivery status reports to <$recipients>. \

# Please try later.

# log_message = greylisted.

# senders = : postmaster@*

# condition = ${if !eq {$acl_m0}{accept}{true}}

# set acl_m9 = $sender_host_address $recipients

# set acl_m9 = ${readsocket{/var/run/greylistd/socket}{$acl_m9}{5s}{}{}}

# condition = ${if eq {$acl_m9}{grey}{true}{false}}

# delay = 20s

# --------------------------------------------------------------------

# --- ここから EXISCAN 設定 ---

# 重大な MIMEエラーがあるメッセージは拒否する.

#

deny

message = Serious MIME defect detected ($demime_reason)

demime = *

condition = ${if >{$demime_errorlevel}{2}{1}{0}}

# MIMEコンテナを解き、ワームが使うファイル拡張子は拒否する.

# これは demime 条件をもう一度呼び出すが、キャッシュした結果が返る.

# 拡張子の一覧は完全なものではないことに注意.

#

deny

message = We do not accept ".$found_extension" attachments here.

demime = bat:btm:cmd:com:cpl:dll:exe:lnk:msi:pif:prf:reg:scr:vbs:url

# MESSAGE_SIZE_SPAM_MAX より大きいメッセージは, スパムやウィルスの検出を

# せず受け付ける

accept

condition = ${if >{$message_size}{MESSAGE_SIZE_SPAM_MAX} {true}}

logwrite = :main: Not classified \

(message size larger than MESSAGE_SIZE_SPAM_MAX)

# --------------------------------------------------------------------

# ウィルス検出

# これには, 首節で ’av_scanner’ の設定が要る.

71

Page 84: Spam Filtering for MX (ja) / メール交換機でのスパム排除

#

#deny

# message = This message contains a virus ($malware_name)

# demime = *

# malware = */defer_ok

# --------------------------------------------------------------------

# SpamAssassinを呼び出して, $spam_score と $spam_report を得る.

# 選別結果に応じて, $acl_m9 に "ham" か "spam" をセットする.

#

# メッセージが spam に選別され, 以前に $acl_m0 をセットして必ず受け付けるこ

# ことを示していなければ, 拒否したふりをする.

#

warn

set acl_m9 = ham

# ------------------------------------------------------------------

# SpamAssassin でユーザごとの設定をさせたければ, 以下の行のコメントを

# はずし, "spam = mail" をコメントアウトする.

# ユーザ名として, 受信者アドレスで指定されたもの, つまり どの ’=’ 文字や

# ’@’ 文字 よりも前のものを, 小文字に変換して使う, 受信者は複数現れるは

# ずがない. なぜなら以前に, 配送を一度にひとつの受信者に限っているから.

#

# spam = ${lc:${extract{1}{=@}{$recipients}{$value}{mail}}}

# ------------------------------------------------------------------

spam = mail

set acl_m9 = spam

condition = ${if !eq {$acl_m0}{accept}{true}}

control = fakereject

logwrite = :reject: Rejected spam (score $spam_score): $spam_report

# メッセージに適切な X-Spam-Status: ヘッダを追加する.

#

warn

message = X-Spam-Status: \

${if eq {$acl_m9}{spam}{Yes}{No}} (score $spam_score)\

${if def:spam_report {: $spam_report}}

logwrite = :main: Classified as $acl_m9 (score $spam_score)

# --- ここまで EXISCAN 設定 ---

# メッセージを受け付ける.

#

72

Page 85: Spam Filtering for MX (ja) / メール交換機でのスパム排除

accept

73

Page 86: Spam Filtering for MX (ja) / メール交換機でのスパム排除
Page 87: Spam Filtering for MX (ja) / メール交換機でのスパム排除

用語集

概要ここでは、この文書全体で使う単語や用語の定義を述べる。

ラテン字

Bayes式フィルタ [Bayesian Filters] 18 メッセージ間の語 (最近では語の組合せや句のこともある) の再現性に基づいて、 メッセージがスパムである確率を決定するフィルタ。

最初に、不要メール (スパム) と分かっているメッセージと真っ当なメール (非スパム) と分かっているメッセージを与えて、フィルタを鍛える。各メッセージの語 (または句)ごとに、特定の語句が非スパムとスパムのどちらにより多く現れるかを示す Bayes式得点が決まる。語は得点とともに Bayes式インデクスに蓄えられる。

このようなフィルタは、人間のプログラマが手作業で作成した キーワードに基づくフィルタでは見落

とされてしまうようなスパムのしるしを 見つけ出すこともある。すくなくとも、そういう作業を自動

化できる。

Bayes式語句インデクスは、明らかに、鍛えるときに使ったメッセージの言語に特化してしまう。さらに、ユーザ個々人にも特化してしまう。したがっておそらく、システム全体の SMTPの時点での排除よりも、個人用のコンテンツフィルタ (例えばメール利用者エージェント [79]での) に適しているであろう。

そのうえ、スパム送信者は 簡易な Bayes式フィルタを打ち破るテクニックを開発してきている。でたらめな辞書単語や短いストーリーをメッセージに入れておくのである。これは、Bayes式フィルタで決定されるスパム確率を下げるし、長い目で見れば Bayes式インデクスの質を落すことになる。

http://www.everything2.com/index.pl?node=Bayesian も見よ。

Request for Comments (略称: RFC) http://www.rfc-editor.org/ より: 「Request for Comments(RFC) 文書集は、インターネットについての技術面や組織面の記述の集合である [...]。 RFC集の覚書では、コンピュータネットワーキングのさまざまな側面 (プロトコル、手続き、プログラム、概念などを含む) について論じられており、さらに会議の記録、意見、あとたまに冗談などもある。」

これらの文書が、プロトコルやデータ形式の記述も含めたインターネット運営上の「掟」となって

いる。 メール配送に関わるものとしては、つぎのものがある:

• RFC 282119 ”簡易メール転送プロトコル” [Simple Mail transfer Protocol] と、

• RFC 282220 ”インターネットメッセージの形式” [Internet Message Format]。

エンヴェロープ受信者 [Envelope Recipient] メッセージが送られる先の電子メールアドレス。 SMTPトランザクションの間に、RCPT TO: コマンドを使って与えられる。 これは、メッセージそのものの

「To:」ヘッダや「Cc:」ヘッダにあるアドレスとは違うこともある。18[訳注] 事後確率に関する「Bayesの定理」 (1764) の応用であるため、こう呼ばれる。19http://www.ietf.org/rfc/rfc282120http://www.ietf.org/rfc/rfc2822

75

Page 88: Spam Filtering for MX (ja) / メール交換機でのスパム排除

[SMTPトランザクション] [4]も見よ。

エンヴェロープ送信者 [Envelope Sender] メッセージの送信者である電子メールアドレス。 SMTPトランザクションの間に、MAIL FROM:コマンドを使って与えられる。これは、メッセージそのものの

「From:」ヘッダにあるアドレスとは違うこともある。

特殊な場合として、配送状況通知 [78] (バウンスしたメッセージ、受け取り通知、不在メッセージ...)がある。このようなメールでは、エンヴェロープ送信者 [76]は空である。これはメールループ [79]を防止するためであり、また一般にこういったものを「通常の」 メールと区別できるようにするた

めである。

[SMTPトランザクション] [4] も見よ。

開放型プロキシ [Open Proxy]どこからの TCP/IP接続でも受け付け、それをどこへでも転送できるプロキシ [78]。

スパム送信者やウィルスが悪用する。自分の IPアドレスを隠すのに使ったり、複数のホストやネットワークを通じて転送負荷を分散させるのである。

ゾンビホスト [77]も見よ。

開放型リレー [Open Relay]どこからのメールでも受け付け、それをどこへでも転送できるリレー [79]。

1980年代には、公開されている SMTPサーバは、 実質的にはどれもが開放型リレー [76]だった。メッセージはしばしば、複数の第三者の計算機を渡り歩いてから目指す受信者にたどり着いていた。

今日では、真っ当なメールはほぼ例外なく、送信者の側の送出用メール転送エージェント [79]から受信者のドメインの側の受入用メール交換機 [79]へ 直接送られている。

逆に、いまだにインターネット上に存在する開放型リレー [76]サーバは ほぼ例外なく、スパム送信者が自分の身許を隠したり 何万というメッセージを送る作業で負荷分散を実行したりするために悪

用されている。おそらくこれは、 DNSブロックリストがこういった計算機をすべて登録してしまうまでは続くであろう。

[開放型リレーの防止] [13]についての議論も見よ。

完全修飾ドメイン名 [Fully Qualified Domain Name] (別名「FQDN」) 完全で、全地球的に一意な、DNSドメインを含むインターネットでの名前。例えば: 「www.yahoo.com」。

FQDNがかならず単一のホストを指しているとは限らない。例えば、「www」のような一般的なサービスの名前はしばしば 複数の IPアドレスを指している。これはサーバ間での負荷分散のためである。とはいえ、どの計算機ではプライマリホスト名は かならずその計算機に固有のものである — 例えば:「p16.www.scd.yahoo.com」。

FQDNはかならずピリオド (”.”) を含む。 最初のピリオドよりも前の部分が非修飾名で、これは全地球的に一意ではない。

偽陰性 [False Negative] 不要メール (スパム、ウィルス、マルウェア)が、誤って真っ当なメールに選別されてしまった (そしてそのために、排除されなかった) もの。

偽陽性 [False Positive] 真っ当なメールが、誤って不要メールに選別されてしまった (そしてそのために、阻止されてしまった) もの。

巻き添え被害 [78]も見よ。

76

Page 89: Spam Filtering for MX (ja) / メール交換機でのスパム排除

小額課金方式 [Micropayment Schemes] (別名 元払い方式 [sender pay schemes])。メッセージの送信者は、メッセージの受信者各々について、いくらか計算機の資源を費やして仮想的な切手を作成する — 通

常は、大量のメモリ読み書きを要するが CPU速度は相対的に速いような 数学的な問題を解くことになる。そして、この切手をメッセージのヘッダに付加する。受信者のほうでは、この切手をより簡単

なデコード操作で検証できるようになっている。

このアイディアではメッセージのすべての受信者アドレスごとに切手が必要になるので、 何千もの

ユーザに一度に送ろうとすると途方もなく ”高くつく” ことになる。

このようなシステムが 2つある:

• Camram21

• Microsoft’s Penny Black Project22

スパムトラップ [Spam Trap] 公開の場でアドレスを収集しているロボットをおびき寄せて [DNSによるブラックリスト] [9]や[不要メールシグネチャ集積システム] [19]のような 協調型ツールで捕らえるための、撒き餌にする電子メールアドレス。

このアドレスに送られてくるメールは通常、スパムかマルウェアである。しかし、そのうちのある

ものは巻き添えスパム — つまり偽装された送信者アドレスに送られる配送状況通知 [78] —である。したがって、 スパムトラップがこのようなメッセージを無視する安全装置を具えていなければ、結

果としてツールは完全に信頼できるものではなくなるであろう。

ゾンビホスト [Zombie Host] インターネット接続している計算機で、大量メール送信型のウィルスやワームに感染しているもの。 このような計算機は、かならずと言っていいほど Microsoft r© Windows r©オペレーティングシステムの類を実行しているし、ほぼかならず「常時接続」 IPアドレスブロックにある。 持ち主は、計算機が感染していることに気づいていないか、そもそもそんなことは気にし

ていないし、しばしば ISPの側も、それをシャットダウンさせるための行動を起こさない。

幸いなことに、「dul.dnsbl.sorbs.net」 のようなさまざまな DNSブロックリストがあって、 このような ”常時接続” アドレスブロックを収集している。こういうブロックリストを使うと外部から来るメールを拒否することができる。常時接続ユーザからの真っ当なメールは、通常、 ISPの「スマートホスト」を通じてやって来るものである。

ドメインネームシステム [Domain Name System] (略称: DNS) インターネットのドメイン名についての情報を取得するための、事実上の標準。このような情報の例としては、サーバの IPアドレス (いわゆる Aレコード )、 受入用メール交換機の割り当て (MXレコード )、一般的なサーバの情報 (SRVレコード )、その他のテキスト情報 (TXTレコード )がある。

DNSは、階層型で分散型のシステムである — 各々のドメイン名は、 一つまたはその以上の DNSサーバの組と関連づけられており、この DNSサーバがドメインについての情報 (自身のサブドメインについてのネームサービスの委任状況も含む) を提供する

例えば、最上位ドメイン「org」は The Public Interest Registryが運用している —このドメインのDNS サーバはドメイン名「tldp.org」についての問い合わせを The Linux Documentation Project

21http://www.camram.org/22http://research.microsoft.com/research/sv/PennyBlack/

77

Page 90: Spam Filtering for MX (ja) / メール交換機でのスパム排除

の特定のネームサーバに委任する。そして、TLDPのネームサーバ (実は UNCが運用している)は第 3階層のドメイン名 (「www.tldp.org」のような)についての問い合わせを、委任したりしなかったりする。

DNS検索は普通、転送ネームサーバを使って行なう。このようなものはインターネットサービスプロヴァイダが (例えば DHCPによって) 提供する。

なりすましメール [Joe Job]別人の有効なアドレスから来たかのように見えるように作ってあるスパム。これはしばしば、苦情の行き先を第三者に逸らしたり そのアドレスの持ち主にほかにも損害を与えよ

うとする、悪質な企みによるものである。

http://www.everything2.com/index.pl?node=Joe%20Job も見よ。

配送状況通知 [Delivery Status Notification] (略称: DSN) 送信者に送信したメッセージの状況について知らせるために MTAや MDAが自動的に作成するメッセージ (普通は、DSNの中に元のメッセージが含まれている)。 DSNでは例えば、 元メッセージが一時的あるいは恒久的な問題のために配送できなかったことや、配送の試行がどのくらいの間続くのか、あるいは続かないのかを 送信者に知らせ

ることができる。

配送状況通知は空のエンヴェロープ送信者 [76]アドレスから送られる。

プロキシ [Proxy]他の計算機に代わって働く計算機。通常は、インターネットに向けて、あるいはインターネットから、 HTTP要求や TCP/IP接続などを転送したりする。例としては、よく企業 — ときに

は国家全体 — で「Webプロキシ サーバ」を使って、内部のネットワークから外部へ行く HTTP要求を、通したり通さなかったりしている。これは、エンドユーザから見て透過的なこともそうでな

いこともある。

開放型プロキシ [76]、リレー [79] も見よ。

巻き添えスパム [Collateral Spam] 23 送信者アドレスが偽装されているメッセージ (多くがスパムやマルウェア) に対して、自動的に応答して送られるメッセージ。 巻き添えスパムの典型的な例としては、ウィルス検出報告 (「You have a virus」) やその他の配送状況通知 [78]がある。

巻き添え被害 [Collateral Damage]真っ当な送信者ホストが、DNSブロックリストへ登録されたために メッセージが阻止されてしまうこと。

一部のブロックリスト (SPEWS のような) は、 ISPが苦情に反応しないようだと その ISPの IPアドレス空間全体を機械的に登録してしまうので、その ISPの顧客全員が影響を被ることになる。

偽陽性 [76]も見よ。

23[訳注] backscatter mail (後方散乱メール — とばっちりメール) とも言う。

78

Page 91: Spam Filtering for MX (ja) / メール交換機でのスパム排除

メール交換機 [Mail Exchanger] (略称: MX) インターネットドメインのメールを (送ったり) 受け取ったりするための専用の計算機。

通常、インターネットドメインの DNSゾーン情報には そのドメインの受入用メール交換機として働く完全修飾ドメイン名 [76]の一覧が含まれている。このような一覧の各々を「MXレコード」と呼ぶ。 各々のレコードは、複数の「MXレコード」の間での「優先度」を示す数値を含む。最小の数値のものが最優先となり、そのドメインの「プライマリのメール交換機」とみなされる。

メール転送エージェント [Mail Transport Agent] (略称: MTA) インターネットドメインのメール交換機などのように、 メールサーバで動作しているソフトウェア。 メールを他のホストへ送信したり、他の

ホストから受信したりする。 よく普及しているMTAとしては、Sendmail, Postfix, Exim, Smailがある。

メール配送エージェント [Mail Delivery Agent] (略称: MDA)ユーザのメールボックスが置かれている計算機で動作するソフトウェアで、メールをそのメールボックスへ配送するもの。MTA メール転送エージェント [79]が配送を直接実行していることもよくあるが、そういうMTAはMDAの役割も兼ね具えていることになる。独立したメール配送エージェントの例としては、Deliver, Procmail, Cyrmasterおよび Cyrdeliver (Cyrus IMAP スイートに入っている)がある。

メール利用者エージェント [Mail User Agent] (略称: MUA; 別名 メールリーダ [Mail Reader]) メールにアクセスし、ダウンロードし、読み、送るためのユーザソフトウェア。 例としては Microsoft Out-look/Outlook Express, Apple Mail.app, Mozilla Thunderbird, Ximian Evolutionがある。

メールループ [Mail Loop] 自動的に送られたあるメッセージが他のメッセージを発生させ、そうした他のメッセージが直接あるいは間接に最初のメッセージを再び発生させ、ということが続く状況。

メーリングリストで、購読者のひとつがそのリストそのもののアドレスである場合を考えてみるとよ

い。リストサーバはこのような状況に陥らないようにするため、よく メッセージヘッダに「X-Loop:」といったヘッダをつけ加えて すでにこのヘッダがあるメールは処理しないようにする。

同義語はリンギング [Ringing] である。

ラットウェア [Ratware] スパム送信者が使っている大量メール送信型のウィルスや電子メールソフトウェア。 大量のメールを極めて短時間で送るれるように特別に作ってある。

多くのラットウェアの実装には、最良の筋書きにそってメールを配送できるだけの SMTPクライアントのコードしか入っていない。 SMTP通信の中で、受信側ホストに偽の、あるいは不正確な情報を与えようとする。コマンドを発行する前に受け手からの応答を待とうとしないし、何秒か応答を受

信できないと接続を切る。 一時的なエラーの場合に、通常の再送機構にのっとった振舞いをしない。

リレー [Relay] 電子メールをインターネットから、あるいはインターネットへ転送する計算機。 リレーの例のひとつに「スマートホスト」がある。これは、ISPが顧客に、外部へ行くメールを送信するために提供するものである。

開放型リレー [76]、プロキシ [78]も見よ。

79

Page 92: Spam Filtering for MX (ja) / メール交換機でのスパム排除
Page 93: Spam Filtering for MX (ja) / メール交換機でのスパム排除

付録B GNU General Public License

[訳注: 本付録は訳さない。]

B.1 Preamble

The licenses for most software are designed to take away your freedom to share and change it. Bycontrast, the GNU General Public License is intended to guarantee your freedom to share and changefree software - to make sure the software is free for all its users. This General Public License appliesto most of the Free Software Foundation’s software and to any other program whose authors commit tousing it. (Some other Free Software Foundation software is covered by the GNU Library General PublicLicense instead.) You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licensesare designed to make sure that you have the freedom to distribute copies of free software (and charge forthis service if you wish), that you receive source code or can get it if you want it, that you can changethe software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights orto ask you to surrender the rights. These restrictions translate to certain responsibilities for you if youdistribute copies of the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must give therecipients all the rights that you have. You must make sure that they, too, receive or can get the sourcecode. And you must show them these terms so they know their rights.

We protect your rights with two steps:

1. copyright the software, and

2. offer you this license which gives you legal permission to copy, distribute and/or modify the software.

Also, for each author’s protection and ours, we want to make certain that everyone understands thatthere is no warranty for this free software. If the software is modified by someone else and passed on, wewant its recipients to know that what they have is not the original, so that any problems introduced byothers will not reflect on the original authors’ reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the dangerthat redistributors of a free program will individually obtain patent licenses, in effect making the programproprietary. To prevent this, we have made it clear that any patent must be licensed for everyone’s freeuse or not licensed at all.

The precise terms and conditions for copying, distribution and modification follow.

B.2 TERMS AND CONDITIONS FOR COPYING, DISTRI-

BUTION AND MODIFICATION

81

Page 94: Spam Filtering for MX (ja) / メール交換機でのスパム排除

B.2.1 Section 0

This License applies to any program or other work which contains a notice placed by the copyrightholder saying it may be distributed under the terms of this General Public License. The ”Program”,below, refers to any such program or work, and a 「work based on the Program」 means either theProgram or any derivative work under copyright law: that is to say, a work containing the Program or aportion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter,translation is included without limitation in the term 「modification」.) Each licensee is addressed as「you」.

Activities other than copying, distribution and modification are not covered by this License; they areoutside its scope. The act of running the Program is not restricted, and the output from the Program iscovered only if its contents constitute a work based on the Program (independent of having been madeby running the Program). Whether that is true depends on what the Program does.

B.2.2 Section 1

You may copy and distribute verbatim copies of the Program’s source code as you receive it, in anymedium, provided that you conspicuously and appropriately publish on each copy an appropriate copy-right notice and disclaimer of warranty; keep intact all the notices that refer to this License and to theabsence of any warranty; and give any other recipients of the Program a copy of this License along withthe Program.

You may charge a fee for the physical act of transferring a copy, and you may at your option offerwarranty protection in exchange for a fee.

B.2.3 Section 2

You may modify your copy or copies of the Program or any portion of it, thus forming a work basedon the Program, and copy and distribute such modifications or work under the terms of Section 1 above,provided that you also meet all of these conditions:

1. You must cause the modified files to carry prominent notices stating that you changed the files andthe date of any change.

2. You must cause any work that you distribute or publish, that in whole or in part contains or isderived from the Program or any part thereof, to be licensed as a whole at no charge to all thirdparties under the terms of this License.

3. If the modified program normally reads commands interactively when run, you must cause it,when started running for such interactive use in the most ordinary way, to print or display anannouncement including an appropriate copyright notice and a notice that there is no warranty (orelse, saying that you provide a warranty) and that users may redistribute the program under theseconditions, and telling the user how to view a copy of this License.

Exception:

If the Program itself is interactive but does not normally print such an an-

nouncement, your work based on the Program is not required to print an an-

nouncement.)

82

Page 95: Spam Filtering for MX (ja) / メール交換機でのスパム排除

These requirements apply to the modified work as a whole. If identifiable sections of that work arenot derived from the Program, and can be reasonably considered independent and separate works inthemselves, then this License, and its terms, do not apply to those sections when you distribute them asseparate works. But when you distribute the same sections as part of a whole which is a work based onthe Program, the distribution of the whole must be on the terms of this License, whose permissions forother licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written entirelyby you; rather, the intent is to exercise the right to control the distribution of derivative or collectiveworks based on the Program.

In addition, mere aggregation of another work not based on the Program with the Program (or with awork based on the Program) on a volume of a storage or distribution medium does not bring the otherwork under the scope of this License.

B.2.4 Section 3

You may copy and distribute the Program (or a work based on it, under Section 2 in object code orexecutable form under the terms of Sections 1 and 2 above provided that you also do one of the following:

1. Accompany it with the complete corresponding machine-readable source code, which must be dis-tributed under the terms of Sections 1 and 2 above on a medium customarily used for softwareinterchange; or,

2. Accompany it with a written offer, valid for at least three years, to give any third party, for a chargeno more than your cost of physically performing source distribution, a complete machine-readablecopy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 aboveon a medium customarily used for software interchange; or,

3. Accompany it with the information you received as to the offer to distribute corresponding sourcecode. (This alternative is allowed only for noncommercial distribution and only if you received theprogram in object code or executable form with such an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for making modifications to it. Foran executable work, complete source code means all the source code for all modules it contains, plus anyassociated interface definition files, plus the scripts used to control compilation and installation of theexecutable. However, as a special exception, the source code distributed need not include anything that isnormally distributed (in either source or binary form) with the major components (compiler, kernel, andso on) of the operating system on which the executable runs, unless that component itself accompaniesthe executable.

If distribution of executable or object code is made by offering access to copy from a designated place,then offering equivalent access to copy the source code from the same place counts as distribution of thesource code, even though third parties are not compelled to copy the source along with the object code.

B.2.5 Section 4

You may not copy, modify, sublicense, or distribute the Program except as expressly provided underthis License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, andwill automatically terminate your rights under this License. However, parties who have received copies,or rights, from you under this License will not have their licenses terminated so long as such partiesremain in full compliance.

83

Page 96: Spam Filtering for MX (ja) / メール交換機でのスパム排除

B.2.6 Section 5

You are not required to accept this License, since you have not signed it. However, nothing else grantsyou permission to modify or distribute the Program or its derivative works. These actions are prohibitedby law if you do not accept this License. Therefore, by modifying or distributing the Program (or anywork based on the Program), you indicate your acceptance of this License to do so, and all its terms andconditions for copying, distributing or modifying the Program or works based on it.

B.2.7 Section 6

Each time you redistribute the Program (or any work based on the Program), the recipient automat-ically receives a license from the original licensor to copy, distribute or modify the Program subject tothese terms and conditions. You may not impose any further restrictions on the recipients’ exercise of therights granted herein. You are not responsible for enforcing compliance by third parties to this License.

B.2.8 Section 7

If, as a consequence of a court judgment or allegation of patent infringement or for any other reason(not limited to patent issues), conditions are imposed on you (whether by court order, agreement orotherwise) that contradict the conditions of this License, they do not excuse you from the conditions ofthis License. If you cannot distribute so as to satisfy simultaneously your obligations under this Licenseand any other pertinent obligations, then as a consequence you may not distribute the Program at all.For example, if a patent license would not permit royalty-free redistribution of the Program by all thosewho receive copies directly or indirectly through you, then the only way you could satisfy both it andthis License would be to refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under any particular circumstance, thebalance of the section is intended to apply and the section as a whole is intended to apply in othercircumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claimsor to contest validity of any such claims; this section has the sole purpose of protecting the integrity of thefree software distribution system, which is implemented by public license practices. Many people havemade generous contributions to the wide range of software distributed through that system in relianceon consistent application of that system; it is up to the author/donor to decide if he or she is willing todistribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest ofthis License.

B.2.9 Section 8

If the distribution and/or use of the Program is restricted in certain countries either by patents or bycopyrighted interfaces, the original copyright holder who places the Program under this License may addan explicit geographical distribution limitation excluding those countries, so that distribution is permittedonly in or among countries not thus excluded. In such case, this License incorporates the limitation as ifwritten in the body of this License.

B.2.10 Section 9

The Free Software Foundation may publish revised and/or new versions of the General Public License

84

Page 97: Spam Filtering for MX (ja) / メール交換機でのスパム排除

from time to time. Such new versions will be similar in spirit to the present version, but may differ indetail to address new problems or concerns.

Each version is given a distinguishing version number. If the Program specifies a version number ofthis License which applies to it and ”any later version”, you have the option of following the terms andconditions either of that version or of any later version published by the Free Software Foundation. If theProgram does not specify a version number of this License, you may choose any version ever publishedby the Free Software Foundation.

B.2.11 Section 10

If you wish to incorporate parts of the Program into other free programs whose distribution conditionsare different, write to the author to ask for permission. For software which is copyrighted by the FreeSoftware Foundation, write to the Free Software Foundation; we sometimes make exceptions for this.Our decision will be guided by the two goals of preserving the free status of all derivatives of our freesoftware and of promoting the sharing and reuse of software generally.

B.2.12 NO WARRANTY Section 11

BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FORTHE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTH-ERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PRO-VIDE THE PROGRAM ”AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSEDOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THEQUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAMPROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR ORCORRECTION.

B.2.13 Section 12

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITINGWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR RE-DISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARIS-ING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIM-ITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINEDBY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANYOTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OFTHE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS

B.3 How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the bestway to achieve this is to make it free software which everyone can redistribute and change under theseterms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each

85

Page 98: Spam Filtering for MX (ja) / メール交換機でのスパム排除

source file to most effectively convey the exclusion of warranty; and each file should have at least the”copyright” line and a pointer to where the full notice is found.

<one line to give the program’s name and a brief idea of what it does.> Copyright (C) <year> <nameof author>

This program is free software; you can redistribute it and/or modify it under the terms of the GNUGeneral Public License as published by the Free Software Foundation; either version 2 of the License, or(at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PUR-POSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not,write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Also add information on how to contact you by electronic and paper mail.If the program is interactive, make it output a short notice like this when it starts in an interactive

mode:Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY

NO WARRANTY; for details type ‘show w’. This is free software, and you are welcome to redistributeit under certain conditions; type ‘show c’ for details.

The hypothetical commands ‘show w’ and ‘show c’ should show the appropriate parts of the GeneralPublic License. Of course, the commands you use may be called something other than ‘show w’ and‘show c’; they could even be mouse-clicks or menu items–whatever suits your program.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a”copyright disclaimer” for the program, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in the program ‘Gnomovision’ (which makespasses at compilers) written by James Hacker.

<signature of Ty Coon>, 1 April 1989 Ty Coon, President of ViceThis General Public License does not permit incorporating your program into proprietary programs.

If your program is a subroutine library, you may consider it more useful to permit linking proprietaryapplications with the library. If this is what you want to do, use the GNU Library General Public Licenseinstead of this License.

86