milter-greylistでS25R + greylisting

PostfixでS25R + greylisting(Rgrey)を実現する方法は、smtpd_recipient_restrictionsとPostgreyを組み合わせる方法やmilter managerとmilter-greylistを組み合わせる方法などがあります。実は、milter-greylist単体でも実現できます。Web上にはその方法がみつからないので紹介します。

milter-greylist単体で実現する場合の利点はmilter-greylistの設定だけで完結することです。また、milterの仕組みだけで実現できるのでPostfixだけではなくSendmailでも実現できます。(これはmilter managerとmilter-greylistの組み合わせでも同様)

S25Rの設定

milter-greylistは非常に多くの条件でgreylistingするかどうかを設定できます。S25Rでは接続してきたSMTPクライアントのホスト名を利用しますが、もちろんホスト名も条件として利用できます。設定ファイルgreylist.confの中で使えるdomainがホスト名を使った条件になります。

S25Rを実現するためには、正規表現でホスト名マッチができなければいけません。milter-greylistはregex(3)を利用していて、設定ファイル内で正規表現が使えます。

domainにも正規表現が使えるのですが、greylist.conf(5)にはそのことは書かれていません。milter-greylistでS25Rも利用している人がいないのはそのためかもしれません。domainでもauthなどと同じように/.../と「/」で囲むことにより正規表現が使えます。

ただし、1つハマりポイントがあります。milter-greylistはregex(3)を使っているので、デフォルトでは伝統的な UNIX の正規表現になっています。伝統的な正規表現では「+」などが使えないため、S25Rの正規表現をそのまま利用することができません。extendedregexオプションを指定することによりPosix の拡張正規表現を使えるようになります。S25Rを利用する場合はこのオプションを忘れないようにしましょう。

上記をふまえるとS25Rを利用したgreylist.confは以下のようになります。

extendedregex

racl greylist domain /^\[.+\]$/ msg "S25R rule 0"
racl greylist domain /^[^.]*[0-9][^0-9.]+[0-9].*\./ msg "S25R rule 1"
racl greylist domain /^[^.]*[0-9][0-9][0-9][0-9][0-9]/ msg "S25R rule 2"
racl greylist domain /^([^.]+\.)?[0-9][^.]*\.[^.]+\..+\.[a-z]/ msg "S25R rule 3"
racl greylist domain /^[^.]*[0-9]\.[^.]*[0-9]-[0-9]/ msg "S25R rule 4"
racl greylist domain /^[^.]*[0-9]\.[^.]*[0-9]\.[^.]+\..+\./ msg "S25R rule 5"
racl greylist domain /^(dhcp|dialup|ppp|[achrsvx]?dsl)[^.]*[0-9]/ msg "S25R rule 6"

racl whitelist default

「S25R rule 2」で「[0-9]{5}」を「[0-9][0-9][0-9][0-9][0-9]」に展開しているのは、Posix拡張正規表現では「{繰り返し回数}」という記法をサポートしていないからです。

設定を変更してmilter-greylistを再起動すればS25R + greylistingが実現できます。

(S25R || SpamAssassin) + greylisting

現在の開発版のmilter-greylist(4.3.x)では、DKIMやSpamAssassinのスコアなどメール本体の情報を条件としてgreylistingするかどうかを設定することもできます。ついでなので、「S25Rで引っかかった場合またはSpamAssassinのスコアが5より大きい場合だけgreylistingする」設定も紹介します。

まず、上述の通りS25Rの設定をしているものとします。SpamAssassinなどメール本体の情報も利用する場合はaclのデフォルトをwhitelistにすることを忘れないでください。

racl whitelist default

デフォルトがgreylistなどになっていると本文を用いた条件判断を行いません。

本文を用いた条件判断にはdaclを用います。

spamdsock inet "localhost:783"
dacl greylist spamd > 5 msg "SpamAssasin"

SpamAssassinを利用する場合は「–enable-spamassassin」オプション付きでconfigureを実行している必要があります。デフォルトではSpamAssassinサポートは有効にならないので注意してください。

まとめ

milter-greylistを使って怪しそうなメールだけgreylistingする方法を紹介しました。怪しそうなメールの判断にはS25RとSpamAssassinを利用しました。

greylistingは手軽でスパム排除率が高いのですが、メールの遅延が問題になります。他の手法と協調して怪しそうなメールだけgreylistingすることにより非スパムメールが遅延してしまう可能性を減少させています。また、S25RにSpamAssassinを組み合わせることにより、S25Rをパスしたメールでもメール本体が怪しそうなメールはgreylistingを行うようになっています。S25Rをパスしてしまうスパムメールもいくつかあるのですが、そのようなメールもgreylistingの対象にして排除できる可能性があります。

ここで紹介した方法は「複数の迷惑メール対策のよいところを活かしつつ問題点を軽減させる」という使い方になっています。これはmilter managerのポリシーと同じです。

問題点

最後に問題点を書いておきます。

milter-greylistからSpamAssassinの機能を利用できますが、milter-greylistはSpamAssassinの適用結果をヘッダに追加してくれたりはしません。そのため、milter-greylistだけを利用した場合、受信側で「SpamAssassinは怪しいと判断したけどgreylistingをパスしたスパム」を判断することができません。受信側で「greylistingをパスしたけどSpamAssassinは怪しいといっているからスパムとして扱う」ためにはmilter-greylistとは別にspamass-milterを利用する必要があります。

milter-greylistとspamass-milterはそれぞれ別々にspamdと通信するので、spamdが同じメールを2回処理することもあります。DNSを参照したりするとspamdはそこそこ処理時間がかかるので、環境によってはこの状況が問題になるかもしれません。

milter managerを用いることにより、この状況を回避しながらSpamAssassinとmilter-greylistを連携させることができるのではないかと考えています。

milter-greylistにはsm_macroというMTAから送られてきたマクロの値をもとにgreylistingするかどうかなどを設定することができます。milter managerはマクロの値を変更することができ、そのときに他のmilterの情報やヘッダの値などを利用することができます。これらの機能を組み合わせることにより、それぞれのmilterで重複した処理を行わずにそれぞれの結果を活かすことができると考えています。

これについてはまた別の機会に書くことにします。