1つ上へ
  ヘルプの目次
 印刷
  rules.Mailrules ホワイトペーパー  
        

※このドキュメントは、開発元であるOpen Text社のテクニカルサポート情報を翻訳したものです。現在のバージョンと整合性の取れていない場合がございますので、十分ご検証いただいた上でご適用くださいますようお願いいたします。



IS 7.1では、サーバ管理者が反社会的な電子メール(SPAM)を処理するのに役立ついくつかの新機能が導入されています。これらの機能と使用方法については、Tech Noteの Securing Internet Services 7.1にて概要が紹介されています。サーバ管理者は、新機能のひとつである rules.MailRules を利用して、ISが内向きSMTPメッセージをどのように処理するかをカスタマイズするようなスクリプトを組むことができます。このドキュメントでは、普段スクリプトを組んだことのない、多数のサーバ管理者向けに対して、 rules.MailRules を説明することを意図しています。

SMTP メールは、レイアウトなどが定義されているRFC-822と呼ばれるフォーマットに変換されます(現在では実質RFC-2822)。RFC-822メッセージには、ヘッダフィールド(略してヘッダとも呼ばれます)に関連する行がいくつか通常含まれており、空白行をはさんで、本文が続きます。RFC-822ヘッダは以下のような形式で表記されます。
Subject: Gone fishin'
  ^        ^            ^--このヘッダのデータ部です。例では"Gone fishin'"と設定されています。
  |         |--: - ヘッダの後には常にコロン(:)が存在します。
   --RFC-822 ヘッダ名です。例ではSubject(件名)です。

RFC-822がToやFrom、Subject、Dateなど多くのヘッダを定義している一方で、X-で始まる拡張ヘッダも利用できるよう定義していることは重要です。
例:
X-OriginalArrivalTime: 11 Feb 2003 00:38:15.0656 (UTC) FILETIME=[DD6C4E80:01C2D165]

正しいRFC-822ヘッダの全リストに興味があれば、いつでも仕様書を読むことができます(たとえば http://www.faqs.org/rfcs/rfc822.htmlのように、多くの場所で参照することができます)。実際のアプリケーションでこれらヘッダがどのように扱われているか確認したい場合には、FirstClassクライアントでインターネットから受信したメールの「メニュー>表示>インターネットヘッダの表示」にて確認することができます。

では、 rules.MailRules に対して何を設定すればよいのでしょうか。簡単に言えば、 rules.MailRules には、検証対象のRFC-822ヘッダ、そのヘッダへの検証内容、検証が成功した際の動作などが定義されています。 rules.MailRules に対して何を設定すればいいのか説明する前に、 rules.MailRules ではできないことを見てみましょう。
- NDNメッセージを送信する以外には、SMTPサーバ同士の会話(RFC-822/2821)をコントロールするような記述はできません。
- MIME(RFC-2045+)をデコードしたり、MIMEパートをコントロールするような記述はできません(rules.AttachmentBlockでは、MIMEの添付ファイルをブロックすることは可能です)。
- RFC-822メッセージの本文を検証することはできません。

ですので、rules.MailRules に含まれるスクリプトは、RFC-822ヘッダの検証とそれらに対する動作を定義することになります。ここで、実際にどのようにルールが定義されているのか見て、記述方法について深く掘り下げていくことにしましょう。rules.MailRules は、3種類の行で構成されています。
1) 空白行 - 空白行には特に意味がありません。単にファイルを読みやすくしているだけです。
2) コメント行 - コメント行は「#」文字から始まっています。これも読みやすくするために使用します。
3) ルール行 - ファイルの中心です。システムのSMTPルールを定義します。

各ルール行は同じような形式で記述されており、テスト対象となるヘッダ、テスト内容、取るべき動作が記述されています。
X-Mailer: "Millennium Mailer" SET $spamlevel += 75
   ^        ^             ^                               ^-- 取るべき「動作」です。この例では変数spamlevelに75を追加しています。
   |         |              |-- 「テスト」です。この例では、X-Mailer ヘッダに"Millennium Mailer"が含まれているかを確認します。
   |         |-- ヘッダ部とテスト部は常にコロン(:)で分けられています。
   |-- このルールを実行するヘッダです。

各ルール行を詳しく見ていき、各パートに何が記述されているのかを確認していくことにしましょう。

ヘッダ部

ヘッダ部の主な目的は、どのRFC-822ヘッダ上でこのルールは実行されるのかを定義することです。ヘッダ部には、内向きのSMTPメールに含まれるRFC-822ヘッダやX-headerのどれでも記述できます。通常はTo、From、Subject、Date、Return-Pathなどのヘッダを記述します。ただし、ヘッダ部には以下のような特殊文字を記述することも可能です。
^ - ヘッダ部を判断する前にルールを実行する、という意味です。スクリプト変数を初期化するのに役立ちます。
* - すべてのRFC-822ヘッダに実行する、という意味です。ある特定の値が存在しないか、すべてのヘッダについて調べるときに役立ちます。
''(空文字) - 最後のヘッダが処理されてからこのルールを実行する、という意味です。他のルールによって処理されたデータに対して動作させる際役立ちます。

ヘッダ部には、値、条件、関数などを記述することができません。RFC-822のヘッダ名か、上記の3つの文字のみ記述可能です。

コロン部

ヘッダ部の後には常にコロンがくっつきます。他の言葉で言うと(モンティパイソンからの引用)、「ヘッダ部と動作部を分ける一個のコロンが存在する。それ以上でも以下でもいけない。1は汝が数えるべき数で、数えるべき数は1でなければならない。4は数えてはならず、次に3へ進むのでなくば2を数えてもならん。5は即刻。ひとたび第1の数である1に至るならば、そのとき、テスト部は実行されるであろう。」

テスト部

ルール中の条件を記述する部分は、3つの基本カテゴリに落とし込むことができます。

1) 単純式:単純式とは、引用符の中に「RFC-822ヘッダ中に大文字小文字問わず存在しているか」知りたい文字列を記述する方法です。この文字列中には、単純なワイルドカード文字を含めることができます。「?」は任意の1文字を表し、「*」は任意の文字列を表しています。引用符の前に、テストを反対の意味にする「NOT」を置くことも可能です。
例:
もし次のRFC-822ヘッダrules に処理されたら、何が起こるでしょうか?

Date: Tue, 11 Feb 2003 16:27:41 -0500

Date: "Feb 2003" SPAM                                   # 「真」なので、このメッセージはSPAMとしてマークされます。
Date: "*viagra*" SPAM                                   # 「偽」なので(viagraは含まれていません)、このメッセージはSPAMとしてマークされません
Date: "Tue, 11 Feb 2003 16:27:41 -0500" SPAM    # 「真」なので、このメッセージはSPAMとしてマークされます。
Date: NOT "200?" SPAM                                   # 「偽」なので(NOTで否定されています)、このメッセージはSPAMとしてマークされません
Date: "*Feb*" SPAM                                      # 「真」なので、このメッセージはSPAMとしてマークされます。
Date: "July 2003" SPAM                                  # 「偽」なので(Julyではありません)、このメッセージはSPAMとしてマークされません

2)正規表現(regexp):正規表現はUNIXの世界でよく知られている、文字列をパターンマッチさせる方法です。UNIXコマンドプロンプト上で「man grep」と入力したり、 http://netbsd.gw.com/cgi-bin/man-cgi?egrep+1+NetBSD-currentをWebで参照すれば、より不愉快な詳細説明を確認することができます。ここで言いたいのは、正規表現は単純式よりも素晴らしいレベルでマッチングさせることができるということであり、マッチさせた文字列を後で使用するために変数へ格納しておくことができるということです。
例:

# 後で参照するためにX-Mailerの文字列を格納しておく場合の記述です。「(○○○○・・・)」をマッチさせます。
X-Mailer: regexp:"\\(.+\\)" SET $xmailerstring = "\\1"
# ()は後方参照に必要です。\ は ( をエスケープしており、もうひとつの¥は最初の¥をエスケープしています。
# .+ は1文字以上の任意の文字で、()内に存在しているので、動作部分で¥1(¥でエスケープしています)で利用することができます。

# Received: ヘッダでSPAM業者をチェックします。「(○.○.○.○)」をマッチさせます。
Received: regexp:"\\([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\\)" SET $IP = "\\1"
# 後方参照したいので、\\() が必要になります。パターンは何桁かの数字です。 \\. は数字の後に続くピリオドです。
# その後ヒットしたIPアドレスを$IP変数へ格納します。
Received: IF (@isspamip($IP)) NDN 550 "Sorry, your message has triggered a SPAM block, please contact the postmaster"
# IP blocking list中に$IPが存在するか確認しています。

# ドメイン名の最初の部分がすべて数字かどうかチェックします。
From: regexp:".*@[0-9]+\\..*" SPAM
# @まではどんな文字でもよいですが、最初のピリオドより前の部分がすべて数字であればSPAMと判断します。

# 件名がすべて大文字(数字や?!など含む)であるかチェックします。
Subject: regexp:"[A-Z\\?\\!\\.\\,0-9]+" SPAM
# もし件名が「大文字、!、?、数字、ピリオド、カンマ」のみだった場合、SPAMと判断します。

3)条件式:文字列のパターンマッチングは素晴らしい機能ですが、スクリプト言語においては、条件式が変数の値や組込み関数をテストするのにたいへん便利な場合というのはよくあります。条件式とはまさにそのために使用すべきものなのです。条件式はたいてい「IF (条件式)」という形式で記述されます。この(条件式)には、変数のテストや関数を呼び出すための式が入ります。ここで、rules.MailRules からいくつか条件式のサンプルを抜粋します。
例:
# もしIP が信頼済みIPリストに存在していたら、以降の処理をスキップさせるサンプル。
^: IF (@istrustedip($senderip)) DONE
# (^記号により)すべてのヘッダが処理される前に、送信者のIP(組み込み変数senderipで取得できます)が信頼済みIPリストに存在していれば、DONE(以降の処理を省略)というアクションを行います。

# 送信者名がSPAMアドレスリストに存在するかチェックするサンプル。
From: if (@isspamaddress($from)) SET $spamlevel += 101 AND $spamtests += "FROM_IN_SPAM_FILTERS;"
# Fromヘッダが処理される際、SPAMアドレスリストに送信者アドレスが存在していれば、SPAMレベルを「最高」に設定し、spamtests変数に理由を追加します。

# 後のテストのために、クロススクリプト数を設定しています。ここでは、条件式へ「常に実行」という意味の(1)が設定されています。
: IF (1) SET $xpost = $#BCC + $#To + $#Cc
# (:の前に何もないので)すべてのヘッダ処理が終了した後、組み込み変数#To、#Cc、#Bccの値の合計をxpost変数に格納します。

# もしadminが「スパムスコアが「高」を超えたら拒否」オプションを選択していた場合の処理です。
: IF ($spamlevel > $HighSpamMax && $XtremeCausesNDN == 1) NDN 550 "Sorry, your message has triggered a SPAM block, please contact the postmaster"
# (:の前に何もないので) すべてのヘッダ処理が終了した後、SPAMレベルが高のしきい値を超えていて、adminが「スパムスコアが「高」を超えたら拒否」オプションを選択していたら、
# SMTP 550 エラーとNDNを送信します。

動作部

動作部は、ルールシステムに執行手段をもたらします。RFC-822ヘッダとルールがマッチし条件部をパスした時点で、動作部が実行され、ISによるこのヘッダの処理を何らかの方法で変更します。ルールシステムの振舞う動作は、受信メッセージを変更する動作(4種類)・メッセージを完全に拒否する動作(2種類)・ルール処理を変更する動作(2種類)の、計8種類存在します。ここでは、8つの動作を種類ごとに細かく見ていきます。

1) 受信したメッセージを変更する動作
SPAM - この動作では、メッセージをJUNKとして識別し、自動生成されたメッセージであるフラグを立てます。
DISCARDHEADER - この動作では、現在のヘッダ情報を破棄します。この動作により、クライアントで「インターネットヘッダの表示」を選択しても表示されなくなります。
INJECT - この動作では、FirstClassで配信された際RFC-822ヘッダをメッセージに挿入します。この動作により、クライアントで「インターネットヘッダの表示」を選択するとヘッダが表示されます。
REPLACE - この動作では、FirstClassで配信された際RFC-822ヘッダを差し替えます。この動作により、クライアントで「インターネットヘッダの表示」を選択するとヘッダが表示されます。

2) メッセージを拒否する動作
DISCARDMESSAGE - 受信者へ配信することなく、不達メッセージを返信せずにメッセージを削除します。
NDN - SMTPエラーを生成し、送信元サーバへ不達メッセージを送信します。

3) 以降の処理を変更する動作
SET - 以降の処理で使用される変数を設定します。
DONE - 当該メッセージに対するルール処理をこれ以上行わないようにします。

前章では、動作部のいくつかの使用例を示していますが、さらにいくつかの例をお見せします。

# SPAMレベル「低」のメッセージのアイコンを設定します。
: IF ($LowSpamMin <= $spamlevel && $spamlevel <= $LowSpamMax)  INJECT "X-FC-Icon-ID: 23050"
# すべてのヘッダ処理が終了した後、spamlevel変数がLOW(低)であれば、X-FC-Icon-IDヘッダを追加します(このヘッダにてFCアイコンの指定が可能です)。
# 注意:メッセージの属性に影響を及ぼすX-FCヘッダは、formID、IconID、forms dataなど数多く存在します。
#SMTPでメッセージを送信する際、ISがレンダリングするものを見ることでこの動作を参照することが可能です。

# 管理者が設定可能な変数をここで定義します。
^: IF (1) SET $CrosspostLimit=15 AND $CrosspostIncr=5 AND $XpostSpamLevel=5 AND $XpostSpamIncrVal=5 AND $XtremeCausesNDN=0
# (^が与えられているので)すべてのヘッダが処理される前に、以降の処理に影響を与えるさまざまな変数を設定します。
# 多くの場合、管理者はこれらの値を単純に変更することで、初期状態のrules.MailRulesとは異なった動作をさせることができます。

# 件名ブロックリストを下品な言葉集として利用する場合、このルールは不適切な内容のメッセージを不達メッセージ無しに削除します。
Subject: IF (@inblocklist($subject)) DISCARDMESSAGE
# Subjectヘッダに到達した際、文字列が件名ブロックリストに存在するか確認し、存在していれば不達メッセージを送信せずそのまま削除します。

rules.MailRules ファイルを理解するのに重要なのは、メッセージ配信時のSMTPサーバ同士の会話を理解することで、会話の際のさまざまなルールを理解することです。以下は、SMTPを通してISへシンプルなRFC-822メッセージを受信する際の重要なイベントを時間軸で並べたものです。

インターネットサービス                                          データの流れる方向              他のSMTPサーバ
SMTPポートのリスニング
                                                                <-------------------------              ISへ接続
接続の受け入れ (相手のIPアドレス判明)           ------------------------->
"220 is.com FirstClass vX.X..."と送信                   ------------------------->                                                                              
                                                                <-------------------------              SMTPコマンドを送信 "HELO I am server.com"
"250 HELO"を送信 (相手のサーバ名判明)           ------------------------->              正しいサーバに接続できたことが判明
                                                                <-------------------------              SMTPコマンドを送信 "MAIL FROM: <user@server.com>"
正しい差出人なら "250 OK"                               ------------------------->              「宛先」の送信へ
不正な差出人なら "501 bad sender"               ------------------------->              再試行または処理中止
                                                                <-------------------------              SMTPコマンドを送信 "RCPT TO: <user@is.com>"
正しい宛先なら "250 OK"                         ------------------------->              RFC-822メッセージの配信へ
不正な宛先なら  "501 bad recipient"            ------------------------->              他の宛先を試行するか処理中止
                                                                <-------------------------              SMTPコマンドを送信 "DATA"
この時点で、^ ルールが実行される
"354 Send message"の送信                                ------------------------->              RFC-822ヘッダの送信開始
                                                                <-------------------------              "To: user@is.com"を送信
この時点で、* ルールが実行される
                                                                <-------------------------              "From: user@server.com"を送信
この時点で、Fromと* のルールが実行される
                                                                <-------------------------              "Subject: Hello world"を送信
この時点で、Subjectと* のルールが実行される
                                                                <-------------------------              "<CRLF>"を送信 (ヘッダ領域の終わりを示す空白行)
この時点で、"" のルールが実行される
                                                                                                                        本文領域の送信を開始
                                                                <-------------------------              "Hi User"
                                                                <-------------------------              "How are you?"
                                                                <-------------------------              "Love, User."
                                                                <-------------------------              "<CRLF>.<CRLF>"
"250 Message Accepted"の送信                    ------------------------->              コネクションの切断へ


SMTPサーバ同士の通信で何が起こっているか確認できましたので、このサンプルメッセージがどのように処理されているか例を確認しましょう。以下のようなrules.MailRulesファイルを例とします。

# メッセージが信頼済みIPアドレスから送信されていれば、以降の処理を中止
^: IF (@istrustedip($senderip)) DONE

# 管理者が設定可能な値をここで定義
^: IF (1) SET $SpamMax=50

# Receivedヘッダでスパム業者かチェック
Received: regexp:"\\([0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][0-9]*\\)" SET $IP = "\\1"
Received: IF (@isspamip($IP)) NDN

# 件名のチェック
Subject: IF (@inblocklist($subject)) SET $spamlevel += 50
Subject: "     " SET $spamlevel += 25
Subject: IF (@allcaps($subject)) SET $spamlevel += 25

# errors-to が存在していればスパムである可能性が低い
Errors-To: "*@*" SET $spamlevel -= 20 AND $spamtests += "-ERRORS_TO;"

# どのヘッダでも「Viagra」という単語があれば、ジャンクとして扱う
*: "Viagra" SET $spamlevel += 25

# ヘッダの最後で処理される、スパムと判断されたメッセージをどう処理するかに関するルール
: IF ($spamlevel >= $SpamMax) NDN 550 "Sorry, your message has triggered a SPAM block, please contact the postmaster"

以下のようなメッセージ(青字)を受信したとき、次(赤字)のように処理されます、

他のメールサーバがISへ接続し、SMTP同士の挨拶が交換された後の場面です。
DATAコマンドが実行され、^ルールが実行され、SpamMaxは現在50のしきい値に設定されています。
このメールサーバが信頼済みIPに含まれているのであれば、すべてのルール処理が終了します。

To: user@is.com                    * rulesが実行され、「user@is.com」と「Viagra」が比較されるが、一致しないので何も起こらない。
From: user@is.com                  * rulesが実行され、「user@is.com」と「Viagra」が比較されるが、一致しないので何も起こらない。
Subject: HI           THERE!!   "Subject: IF (@inblocklist($subject)) SET $spamlevel += 50" が実行されるが、何も起こらない。
                                        "Subject: "     " SET $spamlevel += 25" が実行され、$spamlevel に 25加算される。
                                        "Subject: IF (@allcaps($subject)) SET $spamlevel += 25" が実行され、$spamlevel に25加算され、50となる。
                                        * rulesが実行され、「 HI           THERE!!」と「Viagra」が比較されるが、一致しないので何も起こらない。
"<CRLF>"                                空白行に到達したので、""rulesが実行される。
                                        ": IF ($spamlevel >= $SpamMax) NDN 550 "Sorry, your message has triggered a SPAM block, please contact the postmaster"" が実行され、
                                        $spamlevelが50なので、NDNメッセージは不達となる。
相手メールサーバには "550 Sorry, your..."が出力され、送信が停止される
別のメッセージを受信する場合には、設定値がクリアされ再度プロセスがスタートする

ルールの設定値と機能の理解

ISとともに動作するrules.MailRulesファイルは、その機能を実装する変数を利用していますので、その値が何でどのように利用されているかを把握することが重要です。変数は、単一のメッセージを処理する間だけデータを保持することができる、置き場所のようなものです。条件式やSET動作を割り当てなどを使用することで変数をテストすることが可能です。ルールシステムでは2種類の変数が有ります。

ビルトイン変数はルールシステムによって定義されており、処理されるメッセージに関するデータが含まれています。それらのいくつかはメッセージの属性を変更するためにSETされます。
ユーザ定義変数はルール作成者によって、ルール内に$<変数名>と記述することで定義されています。

変数がどちらの種類であるかについて覚えておくことは重要です。というのは、変数を使用する前になんらかの値が設定される必要があるからです。たとえば、以下のようなルールを記述したとします。
:IF ($myvar > 50) NDN 550 "Bad doggie"

しかも以下のルールを記述せずに使用します。
^: IF (1) SET $myvar = 51

このとき、上記のルールは決して実行されることが有りません。なぜなら値が設定されていないからです。

ビルトイン変数についても同様で、Toヘッダの処理前に $#Toを使用しても、ゼロが戻ってくることになります。

ルール作成者には、filtersrリストにアドレスが存在するか確認するといった、ISのビルトイン機能にアクセスできる権限が与えられています。これを実現するのが関数です。条件式で利用可能で、TRUEまたはFALSEを戻します。これを利用して、ルール作成者は関数の結果に応じた「動作」を定義することが可能です。ルール作成者はユーザ関数を定義することも可能です。以下は、ビルトイン変数と関数のリストと簡単な説明です。

@inblocklist(<string> or <variable>[, <case>])  // <case> には "yes", "no", "true", "false"が入ります。
                                                                // 省略すると "yes" になります。
@seenheader(<string> or <variable>)
@istrustedip(<string> or <variable>)
@istrustedaddress(<string> or <variable>)
@isspamip(<string> or <variable>)
@isspamaddress(<string> or <variable>)
@islocaladdress(<string> or <variable>)

// 以下は ISスクリプトと同様に動作します。
@split(...)
@substr(...)
@length(...)
@indexof(...)
@upper(...)
@lower(...)
@rand()

// ビルトイン変数
// 名前                 値                                      参照のみ/読み書き可
$MachineGenerated       "1", "0"                                        読み書き可
$Priority                       "Normal", "Urgent", "Bulk", "Junk"      読み書き可
$IsNewsArticle          "1", "0"                                        参照のみ
$IsSpammer                      "1", "0"                                        読み書き可
$MessageID                      <contents of Message-ID header> 参照のみ
$Subject                        <contents of subject header>            読み書き可
$From                   <contents of From: header>              参照のみ
$Sender                 <contents of MAIL FROM:>                参照のみ
$#To                            <number of To: recipients>              参照のみ
$#Cc                            <number of Cc: recipients>              参照のみ
$#BCC                   <number of BCC recipients>              参照のみ
$HaveReplyTo            "1", "0"                                        参照のみ
$HaveResentReplyTo      "1", "0"                                        参照のみ
$SenderIP                       <IP address of sending SMTP host>       参照のみ
$MyIP                   <IP address of this host>               参照のみ
$Authenticated          "1", "0"                                        参照のみ
$AuthCanRelay           "1", "0"                                        参照のみ

rules.MailRulesのデフォルト動作

管理者の多くはrules.MailRulesをデフォルトで実行するか、必要に応じて少しだけ変更することを選択するかもしれません。これらの人々が、デフォルトのルールについて理解すること、それぞれ何を行うか、どこ簡単に変更することができるのかを理解することは非常に重要です。理解を助けるために、以下のとおり青字で初期状態のrules.MailRulesをすべて掲載しました。追加のコメントや説明は赤字で記載しています。

最初の2つのルールはRFC-822ヘッダを処理する前に適用されます。これらのルールは、信頼されたサイトとIPアドレスについてはルールプロセスを省略させるよう処理します。省略させたくない場合には、単純にこれらの行の先頭に#記号を挿入し、コメントアウトしてください。

# 信頼されているアドレスまたはサイトからのメッセージであれば、処理を終了します。        <====   コメント行
^: IF (@istrustedaddress($sender)) DONE                         <====   ヘッダが処理される以前の処理です。$Senderが信頼されたメールアドレスなら、以降の処理をスキップします。
                                                                                $SenderはSMTPサーバの「Mail From」コマンドの結果が格納されている、定義済みの変数です。
^: IF (@istrustedip($senderip)) DONE                            <====   ヘッダが処理される以前の処理です。 $SenderIPが信頼されたIPアドレスなら、以降の処理をスキップします。
                                                                                $SenderIPは送信元SMTPサーバのIPアドレスが格納されている、定義済みの変数です。

次の2行は、実際にはコメントアウトされています。このルールがもし有効ならば、RFC-822ヘッダの「From」を読み込んだ際に実行されるもので、Fromのアドレスが信頼されたメールアドレスかどうかを検証するルールです。コメントアウトされているのは、このヘッダにローカルアドレスを設定することで、信頼された送信者からのメールであるとスパム業者がの装することは、珍しくないからです。管理者が、このルールを有効にしたほうがよいと感じるのであれば、#記号を取り去って有効にすることができます。
# From アドレスは簡単に偽装できますので、信頼できません。       <====   コメント行
#From: if (@istrustedaddress($from)) DONE                       <====   コメント行。#が削除されなければ、無効の状態です。

以下の7行は、管理者がいくつかのルールをコントロールするのに必要な、変数の設定です。管理者はしきい値や制限値を変更するだけで、ルールの実行される条件やスパムスコアをどのように計算するか変更することが可能です。
# 管理者の設定可能な値は、ここで定義します。                            <====   コメント行
^: IF (1) SET $CrosspostLimit=15 AND $CrosspostIncr=5   <====   これらはクロスポストのルールに関する2つの変数です。受信者が多ければ多いほど、よりスパムである可能性が高いからです。
                                                                                CrosspostLimitでは、受信者合計が15より多いとスパムの疑いがあると定義します。
                                                                                CrosspostIncrでは、受信者5人ごとに、よりスパムの疑いがあると定義しています。
                                                                                管理者は、これらの値を増加させることで、メッセージがクロスポストによりスパム認定される機会を減らすことが可能です。
                                                                                重要:クロスポストをスパムの目安として利用する場合、信頼するメールアドレスリストに受信したいメーリングリストを追加する
                                                                                必要があります。通常メーリングリストには大量の受信者が含まれるからです。
^: IF (1) SET $XpostSpamLevel=5 AND $XpostSpamIncrVal=5 <====   これらの2つの変数もまたクロスポストに関するルールですが、これらはスパムスコアを追加するルールに関するものです。
                                                                                XpostSpamLevelは、クロスポストの上限(CrosspostLimit)を超過した場合にスパムスコアに最初に追加される点数です。
                                                                                XpostSpamIncrValは、受信者の合計数がCrosspostIncrを超えるごとにスパムスコアに追加される点数です。
                                                                                これらの変数を使った例を挙げると、
                                                                                受信者数12:スパムスコアへの加算なし
                                                                                受信者数16:スパムスコアへ5点加算
                                                                                受信者数22:スパムスコアへ10点加算
                                                                                受信者数100:スパムスコアへ90点加算
                                                                                となります。
^: IF (1) SET $XtremeCausesNDN=0                                        <====   メッセージのスパムスコアがHighSpamMax(以下で定義)を超過したとき、
                                                                                メッセージのスパム警告レベルはExtremeと呼ばれるレベルになります。
                                                                                この変数は、管理者がExtremeレベルのメッセージをどのように処理するか、定義するものです。
                                                                                デフォルト(0)のまま設定されている場合、ルールシステムはExtremeレベルのスパムメッセージを
                                                                                スパムレベル「高」のメッセージと同様にユーザへ配信します。
                                                                                もしこの値が1に設定されていれば、ExtremeレベルのスパムメッセージはNDNとして扱われ
                                                                                ユーザへ配信されません。
# これらの変数を変更する場合、個々のスパム検証についても考慮する必要が有ります。        <====   コメント行
^: IF (1) SET $LowSpamMin=10 AND $LowSpamMax=25         <==== これらの変数はスパムレベル「低」のスパムスコアの範囲を定義します。
                                                                                デフォルトでは、スパムスコア10以下をスパムとしては扱わず、10~25をスパムレベル「低」と認識します。
                                                                                「低」のメッセージには、「低」のアイコンとX-SPAM-Warningヘッダ、X-SPAM-Levelヘッダを追加します。
^: IF (1) SET $MedSpamMax=50 AND $HighSpamMax=100       <==== これらの変数はスパムレベル「中」と「高」のスパムスコア範囲を定義します。
                                                                                デフォルトでは、25~50を「中」、50~100の範囲を「高」と認識します。
                                                                                これらの範囲のメールは、「ジャンク」と判定され、機械的に生成されたメッセージとして、適切な
                                                                                アイコンと X-SPAM-Warningヘッダ、X-SPAM-Levelヘッダが追加されます。

以下の2行は、Receivedヘッダ中のIPアドレスをスキャンし、スパムIPリストに存在しないかをチェックします。このメッセージをルーティングしたホストにリストにスパム業者が存在していれば、スパムメッセージである可能性が高いからです。
#                                                                       <====   コメント行
# スパムレベルを設定するルール                          <====   コメント行
#                                                                       <====   コメント行
# スパム業者かどうかReceivedヘッダをチェック                    <====   コメント行
Received: regexp:"\\([0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][0-9]*\\)" SET $IP = "\\1"  <====   正規表現を使って、 ReceivedヘッダのIPアドレスをスキャンし、$IPに格納します。
                                                                                                                                「\\」はエスケ ープされた\記号を表しています。「\(」は、丸括弧を適正にエスケープしたものです
                                                                                                                                (丸括弧は後方 参照時に使用される文字ですので、丸括弧自体を表すにはエスケープします)。
                                                                                                                                このパターンは 、「数字の後にピリオド、その後に数字・・・」を表しています。
                                                                                                                                「\\1」は後方参 照で、()中の抽出されたパターンを「動作」部から参照可能です。
                                                                                                                                この場合は、$IP 変数を利用して参照することができます。

Received: IF (@isspamip($IP)) NDN                               <====   このルールは$IPのIPアドレスがスパムリストに存在するかどうかを確認し、存在していればNDNメッセージを送信します。

以下の3行は、疑わしいメッセージを探すための、件名の内容についてのかなり簡単なテストです。
Subject: IF (@inblocklist($subject)) SET $spamlevel += 100 AND $spamtests += "SUBJECTBLOCK;"    <====件名ブロックリストで禁止された言葉が、件名に含まれていた場合
                                                                                                                        スパムスコアを「高」(100追加)に設定し、SUBJECTBLOCKの文字列を ヘッダに追加して、
                                                                                                                        このテストをパスできなかった旨を記録します。

Subject: "     " SET $spamlevel += 50 AND $spamtests += "SUBJ_HAS_SPACES;"                              <====   件名に6以上連続した空白が存在すれば、スパムスコア50を追加し、
                                                                                                                        SUBJ_HAS_SPACESの文字列をヘッダに追加して、このテストをパスでき なかった旨を記録します。

Subject: IF (@allcaps($subject)) SET $spamlevel += 25 AND $spamtests += "SUBJ_ALL_CAPS;"        <====   件名が大文字だけならスパムスコアに25追加し、    SUBJ_ALL_CAPSの文字列を
                                                                                                                        ヘッダに追加して、このテストをパスできなかった旨を記録します。

次のテストは、Errors-Toヘッダに何らかの正しい値が設定されていれば、そのメッセージはスパムでないことを示している、という考え方に基づいています。「動作」部でスパムスコアを20減らし、「-ERRORS_TO」ヘッダにfailedを追加します。(この場合のfailed=不合格は反対の意味です)
Errors-To: "*@*" SET $spamlevel -= 20 AND $spamtests += "-ERRORS_TO;"

次のテスト群は、Fromヘッダについてスパムでないか検証します。
From: regexp:".*[A-Za-z]+[0-9]+[A-Za-z]+[0-9]+@.+" SET $spamlevel += 25 AND $spamtests += "FROM_SUSPICIOUS;"    <====Fromヘッダにアルファベットや数字の羅列があれば疑わしい
                                                                                        メッセージとみなし、スパムスコアに25加算し、FROM_SUSPICIOUSの文字列を追加します。
.
#From: if (@isspamaddress($from)) SET $isspammer = 1            <====これは、すでに知られているスパム業者からのメールをNDNなど送信せずに削除していた、以前のビルトインルールです。
                                                                                        このルールは、次行のルールでスパムスコアをセットする際にこの情報を使うものとして、コメントアウトされています。しかし
                                                                                        isspammerを有効にすると、メッセージの廃棄とDATAコマンドが完了したという偽レスポンスを送信できるようになります。
                                                                                        $isspammerを設定すれば、DISCARDMESSAGE動作と同じような結果となります。

From: if (@isspamaddress($from)) SET $spamlevel += 101 AND $spamtests += "FROM_IN_SPAM_FILTERS;"        <====   Fromアドレスがフィルタリストに存在すれば、
                                                                                                                                        スパムスコア「高」(100追加)とし、FROM_IN_SPAM_FILTERSの文字列を追加します。

次の2行はMessage-IDヘッダに疑わしい内容がないかテストし、疑わしければスパムスコアを追加します。
Message-ID: not "@" SET $spamlevel += 51 AND $spamtests += "INVALID_MSGID;"                     <====   Message-IDに@記号がなければ疑わしいと判断します。
Message-ID: regexp:"^<.+\@>$" SET $spamlevel += 51 AND $spamtests += "INVALID_MSGID_2;" <====   Message-IDが<文字列@>という形なら疑わしいと判断します。

次の3行は、ルールファイルの先頭付近で定義された変数を使用した、クロスポストの制限に関する記述です。ここでは、宛先が多すぎる場合はたいていスパムであるという想定で既定しています。先頭付近の変数を調整することで、管理者はこのルールの「感度」を調整することができます。
#                                                               <====   コメント行
# crosspost limiting rules                                      <====   コメント行
#                                                               <====   コメント行
: IF (1) SET $xpost = $#BCC + $#To + $#Cc               <====   このメッセージがクロスポストされているか確認するため、To、CC、BCCの受信者合計を計算します。
: IF ($xpost >= $CrosspostLimit) SET $spamlevel += $XpostSpamLevel AND $spamtests += "CROSSPOST_EXCEEDED;"      <====クロスポストの制限を超過した場合、
                                                                                                                                                         スパムスコアと文字列を追加します。
        
: IF ($xpost >= $CrosspostLimit) SET $spamlevel += (($xpost-$CrosspostLimit)/$CrosspostIncr)*$XpostSpamIncrVal  <====クロスポストの制限を超過した場合、
                                                                                                                                                         どれだけ超過しているかに比例してスパムスコアを加算します。

次のルール群は、以前のバージョンでISのコード内に組み込まれていた、スパム検出ルールです。以前はスパムスコア方式では有りませんでしたので、 現在はスパムスコアとスパムテスト変数を追加している箇所について、これらのルールはメッセージをジャンク判定するのに単純な方法で利用されていました。
#                                                                                                                       <====コメント行
# 以前の組み込みルールです。現在はスパムレベルも設定します。                                    <====コメント行
#                                                                                                                       <====   コメント行
X-Mailer: "Extractor" SET $spamlevel += 75 AND $spamtests += "X-MAILER;"                                        <====   メーラーがExtractor?
X-Mailer: "Floodgate" SET $spamlevel += 75 AND $spamtests += "X-MAILER;"                                        <====   メーラーがFloodgate?
X-Mailer: "Group Mail" SET $spamlevel += 75 AND $spamtests += "X-MAILER;"                               <====   メーラーがGroup Mail?
X-Mailer: "Millennium Mailer" SET $spamlevel += 75 AND $spamtests += "X-MAILER;"                        <====   メーラーがMillennium Mailer?
X-Mailer: "AutoMail" SET $spamlevel += 75 AND $spamtests += "X-MAILER;"                                 <====   メーラーがAutoMail?
: IF ($#BCC > 0 && ($#To + $#Cc) == 0) SET $spamlevel += 75 AND $spamtests += "NO_RECIPIENTS;"  <====このメッセージにはBCC受信者のみ?
                                                                                                                                BCCは、RFC-822 の「To」というよりもSMTP「RCPT TO」コマンドとは異なったアドレス指定
                                                                                                                                方法によりイン ターネット上で生成されます。多くの場合、BCCだけのメッセージは
                                                                                                                                設定ミスか、だ いたいはスパムです。


#: IF (NOT @seenheader("Date")) SET $spamlevel += 26 AND $spamtests += "NO_DATE;"                       <====   このルールはコメントアウトされています。
                                                                                                                                有効にした場合 、このルールはDateヘッダがないメッセージを疑わしいものとして扱います。
                                                                                                                                これはスパム業 者というよりも低品質のメールを抽出しているようでしたので、削除されました。

: IF (NOT @seenheader("Message-ID")) SET $spamlevel += 51 AND $spamtests += "NO_MESSAGE_ID;"    <====   メッセージにMessage-IDがなければRFC-822違反です。このルールは、正しく
                                                                                                                                メールクライア ントを利用している場合はほとんど抽出せず、多くのスパム業者を抽出します。

最後のルール群は、スパムスコアに基づいて動作します。それらのしきい値は、このルールファイルの先頭付近で定義されています。これらのルールはスパム判定されたメッセージに対してどう処理するかを定義します。たいていの場合、疑わしいメッセージはシステム内に受信され、いくつかの属性がセットされます。アイコン(緑やオレンジ、あるいは危険なレベルのスパムであることを示す赤の禁止マーク)、機械生成のタグ(スパム業者への自動返信を避ける)、ジャンクタグ(メールボックスの一覧に「ジャンク」と表示)、X-SPAM-Warningヘッダ(Extreme、高、中、低)、X-SPAM-Levelヘッダ(スパムスコア)、X-SPAM-Testsヘッダ(どのスパムテストに不合格だったか)、などの属性が追加されます。
#                                                                                                                       <====   コメント行
# ヘッダの最後で処理される、スパムレベルを処置するルール                                        <====コメント行
#                                                                                                                       <====   コメント行
: IF ($spamlevel > $HighSpamMax && $XtremeCausesNDN == 1) NDN 550 "Sorry, your message has triggered a SPAM block, please contact the postmaster"<= スパムレベルがExtremeで
                                                                                                                                                                         管理者がNDNを送信するよう設定していれば、
                                                                                                                                                                         NDNを送信します。
# 次のルールはNDNを送信しない場合のルールです。                                                                 <====   コメント行
: IF ($spamlevel > $HighSpamMax) INJECT "X-SPAM-Warning: EXTREME"                                       <====上記のルールExtremeでNDNを送信しない場合は、警告ヘッダを挿入します。
: IF ($MedSpamMax < $spamlevel  && $spamlevel <= $HighSpamMax) INJECT "X-SPAM-Warning: HIGH"    <====   スパムスコア「高」の場合、警告ヘッダを挿入します。
: IF ($LowSpamMax < $spamlevel  && $spamlevel <= $MedSpamMax)  INJECT "X-SPAM-Warning: MEDIUM"  <====   スパムスコア「中」の場合、警告ヘッダを挿入します。
: IF ($LowSpamMin <= $spamlevel && $spamlevel <= $LowSpamMax)  INJECT "X-SPAM-Warning: LOW"     <====   スパムスコア「低」の場合、警告ヘッダを挿入します。

: IF ($MedSpamMax < $spamlevel) SPAM                                                                            <====   スパムスコアが高以上の場合、SPAM動作を実行します。すなわち、
                                                                                                                                ジャンクとして判断し、マシン生成メッセージ であることを知らせるフラグを立てます。
: IF ($spamlevel >= $LowSpamMin) INJECT "X-SPAM-Level: $spamlevel"                                      <====スパムスコアが低より多ければ、スパムレベルヘッダを挿入します。
: IF ($spamlevel >= $LowSpamMin) INJECT "X-SPAM-Tests: $spamtests"                                      <====   スパムスコアが低より多ければ、スパムテストヘッダを挿入します。

: IF ($MedSpamMax < $spamlevel) INJECT "X-FC-Icon-ID: 23048"                                            <====   スパムスコアが「高」または「Extreme」であれば、アイコンを赤い丸にします。
: IF ($LowSpamMax < $spamlevel  && $spamlevel <= $MedSpamMax)  INJECT "X-FC-Icon-ID: 23049"     <====   スパムスコアが「中」であれば、アイコンをオレンジの丸にします。
: IF ($LowSpamMin <= $spamlevel && $spamlevel <= $LowSpamMax)  INJECT "X-FC-Icon-ID: 23050"     <====   スパムスコアが「低」であれば、アイコンを緑の丸にします。