Postgrey はこんな感じ

まぁ、私があれこれ書かなくても、参考になる情報は多いので、そちらをどうぞ。

...なんだけど、自分でいじってみて気が付いた点などを。

インストール

オリジナルをソースを持ってきてても良いけど、やっぱりパッケージで入れた方が圧倒的に楽。

  • 起動時に daemon として起動させるスクリプトが付いてくる。
  • yum や apt でインストールすれば、必要な Perl モジュールを一緒にインストールされる。

CentOS の場合だと、CentOSリポジトリには無いので、rpmforge のリポジトリを追加すれば、「yum install postgrey」で必要なインストールは完了。

ポイントは、postfix 側の設定。

通常は、SMTP の RCPT TO を受け取った時に判断するので、smtpd_recipient_restrictions でチェックをかけるのだが、ここで「S25R に引っかかった場合に Greylisting」とするには、ちょっと工夫が必要。

まず、S25R のパターンに引っかけるために、main.cf 上で、こんな風に書く。

smtpd_recipient_restrictions = permit_mynetworks,
                               check_client_access regexp:/etc/postfix/s25r,
                               reject_noauth_destination

これで、接続してきた相手をチェックするのに、/etc/postfix/s25r 中に記述された正規表現を使いますよ、ということになる。で、/etc/postfix/s25r 側はこんな風に書く。

/^unknown$/                                     check_greylist
/^[^.]*[0-9][^0-9.]+[0-9].*\./                  check_greylist
/^[^.]*[0-9]{5}/                                check_greylist
/^([^.]+\.)?[0-9][^.]*\.[^.]+\..+\.[a-z]/       check_greylist
/^[^.]*[0-9]\.[^.]*[0-9]-[0-9]/                 check_greylist
/^[^.]*[0-9]\.[^.]*[0-9]\.[^.]+\..+\./          check_greylist
/^(dhcp|dialup|ppp|[achrsvx]?dsl)[^.]*[0-9]/    check_greylist

通常なら左の条件に引っかかったら、右側に REJECT とか書いて、拒否するところに、謎の「check_greylist」などという物を書く。で、この「check_greylist」なるものを、また、postfix の main.cf で定義しておく。

smtpd_restriction_classes = check_greylist
check_greylist = check_policy_service unix:/usr/spool/posfix/postgrey

smtpd_restriction_class で、いわば、オリジナルの処理名(check_greylist)を定義しておき、その処理名に対して、処理内容を記述しているのが2行目になる。で、この check_policy_service は別のプログラムに結果を判断してもらう、というもので、指定先に接続して判断を仰ぐ。その接続先で Postgrey が待ち受けている、という寸法になっている*1

後は、check_policy_service で指定先で Postgrey が待ち受けするように動作していれば良い。rpmforge からのパッケージに含まれる起動スクリプトでは、UNIX ドメインソケットで Postgrey が待ち受けるようになっているので、check_policy_service の指定先は、そのパスを指定することになるが、IP ベースで待ち受けるようにするのであれば、「inet:localhost:10023」といった具合になる。

これを応用すれば、

といった事が可能になる。

Postgrey は必要なパラメータをコマンドラインから指定するため、設定ファイルが無い。rpmforge からのパッケージに含まれる起動スクリプト(/etc/rc.d/init.d/postgrey)の場合、最終的には OPTIONS というシェル変数を postgrey に渡す。/etc/sysconfig/postgrey というファイルを作って、「OPTIONS=なんちゃら」と書けば、それがコマンドラインに渡る。

とはいえ、デフォルトをいじらないと、という感じはあまりない。強いて言うと、retry-window の2日間というのは長い感じがする。あと、max-age の 35 日間は、ホワイトリストを Postgrey の自動ホワイトリスト機能に任せて、自分で状況を見てホワイトリストを追加するので無ければ、この期間でも良いと思うが、積極的に状況を観察して、必要なホワイトリストは自分たちで追加するのであれば、max-age は短くした方が良いかなぁ。

*1:改めて、S25R で Postgrey の組み合わせに関して調べてみたら、check_client_access で指定したファイルで、「S25R に引っかからなかったら OK にする」という記述にして、check_client_access の次で check_policy_service を使って Postgrey に渡しているケースが多かった。つまり、Postgrey に処理をさせるのは、他の条件で拒否でも許可でもなく、残った物を Postgrey に渡す、という方法。微妙な違いだが、「このときに Greylisting」というのなら、上記の記述方法になる。

Postgrey vs milter-greylist

Greylisting 自体は、Postfixsendmail の機能として持っている訳ではない。なので、連携させる別のソフトが必要になる。

で、代表的な Greylisting 用ソフトを比較してみる。

概要

Postgrey
milter-greylist
  • C で書かれている。
  • sendmail 発祥の milter の仕組みを使っている。
  • milter 自体は他の MTA でも使える(Postfix なら 2.3 以降)ので、原理的には MTA を選ばない。
  • milter-greylist 用の設定ファイル(ディストリビューション用のパッケージでインストールすると、たぶん、/etc/mail/greylist.conf)の中で、Greylisting する場合の条件を記述できる。
  • Greylisting 用のプログラムなのに、DNSBLSPF を使っていきなり拒否、とかできてしまう。
  • Greylisting 中のリストはオンメモリで保持。更新されたタイミングなどで、テキストファイルで出力。
  • 起動時にそれを読み直すことで、起動前の状態を復元する。

主なパラメータ

再送禁止期間

最初に届いてから、一時エラーで拒否し続ける期間。立て続けに送ってくるケースをブロックする。

パラメータ名 単位 デフォルト値
Postfix delay --delay=300(5 分)
milter-greylist delay 秒、分、時、日、週 delay 45m(45 分)
Greylist 保持期間

最初に届いて Greylist にエントリを追加し、その後、再送がない場合に Greylist のエントリを破棄するまでの期間。

パラメータ名 単位 デフォルト値
Postfix retry-window 時、日 --retry-window=2(2 日)
milter-greylist timeout 秒、分、時、日、週 timeout 5d(5 日)
許可情報保持期間

Greylisting 後の再送により許可された場合、同一条件のメールが届かなくなってから、許可状態が取り消されるまでの期間。

パラメータ名 単位 デフォルト値
Postfix max-age --max-age=35(35 日)
milter-greylist autowhite 秒、分、時、日、週 autowhite 3d(3 日)

自動ホワイトリストの違い

milter-greylist の場合、Greylisting されたものが再送によって許可されたものを自動ホワイトリストと呼んでいる。

それに対し、Postgrey の場合は、同一条件(IP アドレス、送受信者のメールアドレス)のメールが、一定回数、繰り返して成功した場合、以降、送受信者のメールアドレスを無視して、IP アドレスだけで許可するようになる。この「IP アドレスだけで許可する」ものを自動ホワイトリストと呼ぶ。自動ホワイトリスト入りするための成功回数は「--auto-whitelist-clients」で指定する。デフォルトは5回。

milter-greylist でも Postgrey の自動ホワイトリストのような、「IP アドレスだけで許可」は可能だが*2、Postgrey のように「何回成功したら」ということはなく、再送成功後は必ず IP アドレスのみで許可されることになる。

IP アドレスの評価の違い

ISP のような大規模なメールサーバを持っている場合、再送時に必ず同じ IP アドレスから送信してくるとは限らない。そのため、実際にはまっとうな再送処理なのに、別のメールと判断され、再び一時エラーを返してしまう。

Postgrey ではデフォルトで、Class C 相当のネットワークアドレス(24 bit)が一致すれば、同一の送信元として扱う*3。但し、DNS の逆引きで得られた FQDN に IP アドレスの下位 16 bit を表す数字が含まれている場合は、IP アドレス全体が一致している必要がある。

milter-greylist の場合、デフォルトでは IP アドレス全体が一致している必要があるが、subnetmatch を指定することで、任意のビット長のネットワークアドレスで評価することができる。

個人的見解

すでに Postfix で「smtpd_なんちゃら_restrictions」でいろんな制限を設けている場合だと、Postgrey が導入しやすいと思う。基本的には「smtpd_なんちゃら_restrictions」で使えるものがひとつ増えた感じで設定できる。

Postfix 以外の MTA の場合、そもそも、Postgrey はスコープ外だが、Postfix でも、「smtpd_なんちゃら_restrictions」に詳しくなければ、milter-greylist の方が機能は豊富。milter-greylist の設定ファイル中で、様々なルールを記述できるので、これ一つでカバー出来る範囲が広い。

ただ、Postfix と milter-greylist の間、というか、Milter プログラム全般に言えるんだけど、あまり相性は良くない*4。ので、Postfix と組み合わせるのなら、間に Milter Manager( http://milter-manager.sourceforge.net/index.html.ja )を挟んだ方が良さそう。


... で、実践編じゃなくて、比較編になっちゃった(^^;。どっちもドキュメントが豊富とは言えず、結局、ソースを見ないと分からないことがいくつか...。ソースを見るのだと、Postgrey は Perl スクリプト一本なので、情報は見つけやすい。でも、「FQDN に IP アドレスの下位 16 bit が含まれると」というのは、本当にソースを見るまで分からなかった。

*1:一応、exim からも使えるらしい。exim との互換性のための --exim というオプションがある。

*2:lazyaw を指定

*3:--lookup-by-host を指定すると、IP アドレスが一致していることが必要になる。

*4:milter-greylist の場合、動作はするんだけど、ログの出力結果でちょっと問題。Postfix が、SMTP の MAIL FROM が許可された段階でキュー ID を割り当てるので、milter-greylist に渡ってきたときにはキュー ID が不明になる。そのため、後でログを解析しようとすると、IP アドレスや送受信者のアドレスを組み合わせて、同一メールに対する処理なのかを判断してやる必要がある。sendmail の場合はキュー ID が渡ってくるので、キュー ID で結びつけてやれば良い。

本当は、お金かけると良い製品やサービスがあるんだけどね。

序論

企業や組織のメールサーバで spam 対策をしようと思うと、False Positive(誤検知)をどうするか、が重要。24 時間、管理体制が取れるような大企業や、アウトソーシングしてしまっているようなところだと、「こんなメールが届いているはずだけど、どうなってるんだ! 急いでいるんだ!」となっても大丈夫だろうけど、地方の中小企業ではそうはいかない。なので、可能な限り、誤検知は避けたい。

False Positive 対策として、ISPspam 対策サービスで行われている「留め置き」の処理が理想。なんかおかしいな、と思ったら、spam 扱いされたメールを自分で確認して、間違って spam 扱いされていたら、自分で再配送する。だけど、貧乏会社にはそういった製品を入れる余裕などない。社長が「なんとかならんか! でも金は無い」って言うんだよなぁ...

で、Greylisting

通常のメールサーバから送られたメールであれば、SMTP のレベルで一時エラーになった場合、一定時間の間を置いて、再配送してくる。逆に、近頃の spamボットネットを使って、普通のクライアント PC からダイレクトに送り先のメールサーバへ接続してくるものが多い。日本国内の ISP で実施された OP25B は、まさに、このタイプの spam 送信をブロックしようとしたもの。ISP のメールサーバ経由からしかメールが送られないのなら、送信者アドレスに勝手なドメイン名を使うのを抑止できたり、流量の制限をかけたりできる。

Greylisting は「まっとうなメールサーバなら再送する」というところに着目して、わざと一時エラーを起こす、というものなんだけど、こうすると、相手のメールサーバが再送してくるまでメールが届かない、ということになる。仕事で「今メール送ったんだけど、この2つめの項目の書き方って...」という電話は珍しくない。

False Positive がほとんど無いのは良いのだが、メールが遅延するのは、仕事で使うのにはちょっと困る。

で、S25R

本家のサイト(http://www.gabacho-net.jp/anti-spam/paper.html)には、誇らしげに「阻止率99%*1」などと書かれているが、IP アドレスの逆引きの結果で「怪しい FQDN ならブロック」というのが、原理的に考えて、False Positive の可能性が高い。それを回避するためにホワイトリストを用意して、などといっても、そのホワイトリストをメンテナンスするのが面倒だし、それこそ、休みの日や深夜に大事なお客さんからの急ぎのメールがブロックされたら大変。

で、DNSBL

これも、False Positive に話には事欠かない。ただ、False Positive にされるものの傾向はちょっと違う。S25R が、ホスティングのサービスを使っているような、中小企業からのメールが引っかかりやすい*2のに比べ、DNSBL の場合はニュースレターなど、もともと大量にメールを送信するものが引っかかりやすい*3

で、組み合わせれば...

  • S25RDNSBL は、常に False Positive の危険と隣り合わせ。
  • Greylisting ではメールの遅延が問題。

と思っていたら、

という話があって、なるほど、と。これなら、

  • まっとうなメールは遅延が発生しない。
  • S25RDNSBL に引っかかっても、Greylisting なら再送で救われて、False Positive になるのを防げる。

となり、管理の手間も少ない。

ということで、実践に移る話は次回へ。

*1:実は、実際に試験中なのだが、S25R だけで防げているのは 90% 強。99% は大げさでしょう。

*2:実際に引っかかった。

*3:最近、ライフマイルからのメールが spamhaus に登録されていたのを発見した。ライフマイル側にその旨と、「SPF レコード書いておいた方が良いんじゃない?」という話を書いて連絡済み。受け付けましたの返事は届いたけど、その後、どうなったかは未確認。

SBS by Linux

Microsoft の製品で、SBS(Small Business Server)というのがあったけど、それと同じ発想で、SBS by Linux というのがあってもよいのかな、と。

UNIX の流儀としては、各機能ごとにプログラムが分かれていて、それらを駆使して、ひとつのシステムとして動かすのはユーザ側の作業、といった雰囲気があるけど、正直、通常の Linxu のディストリビューションで、SBS がターゲットになるようなレベルのサーバを構築しようとすると、運用側のスキルが必要となって、「だったら Windows で商用ソフト買った方が分かりやすい」といった感じになりがち。

各ソフトを統合して管理・運用できるインタフェースが必要になってくると思うんだけど、オープンソースでそういったソフトはなかなか見つからない。強いて言うと Webmin が近いんだけど、Webmin はあくまでも個々のソフトの設定・管理が楽になるだけで、ソフト間の連携に関しては、個別に設定する必要があり、素人が普段の運用に使えるものか、というとちょっと方向性が違う。

かつての Cobalt の方向性も悪くないけど、今ひとつ...。

既存ディストリビューションの上に乗せて、

  • POP3、IMAP4、Webmail 対応のメールサーバ
  • LDAP のアドレス帳が使える

といったレベルのことが、Web ベースで一括管理できるようなものがあると良いのだが...。作るしかない(^^?

IMAP ってマイナー?

10 年ほど前に、当時務めていた会社のメールサーバのリプレースで、UW 版の IMAP をソースからビルドして、HP-UX 上で動かして運用したのが最初だったんだけど、それ以降、いまだに IMAP ってマイナーというか....。

商用、オープンソースに限らず、Web ベースのグループウェアを調べていて、中小規模の企業内で使うのには、サイボウズ や desknet's といった、国産の老舗商品が、機能的にも使い勝手の面でも良く出来ていると思うんだけど、これらのソフトでは E-mail の扱いが弱い。単に Web メールのインタフェースを提供するだけで、メールサーバ自体は包含しておらず、IMAP もサポートしていない。

一方、海外製だと近頃の注目株としては Scalix や Zimbra といった辺りになるけど、こちらは確かにメール周りは充実しているんだけど、日本のオフィス環境で「欲しい」と思わせる機能(掲示板やスケジュール、施設予約)がもう一つ。

なんとなくこの辺りに、日本と海外でのビジネス環境の違いを感じてしまう。

Scalix は惜しいんだけどなぁ。メールサーバも含めたオールインワンで、IMAP にも対応できていて、ちゃんと IMAP の共有フォルダにも対応していて、メールサーバとしては、動作が重い点を除けば、ほぼパーフェクトなんだけど、スケジュールの見え方や施設予約との連携とかが見劣りして...。う〜ん。

uw-imap のソースを眺めてみると...

uw-imap の設定ファイル c-client.cf に設定できるオプションは、imaprc.txt というファイルに記述されているのだが、ソースを見ると、実に様々なオプションがある。

かねてから、uw-imap がドット・ファイルをメールボックスとして表示しないようにパッチを当てていたのだが、このパッチが修正している部分のソースを見ると、そもそも c-client.cf の設定で、ドット・ファイルの表示・非表示が制御できそうな記述があるのは気づいていた。

それらしいキーワードを見つけて


set hide-dot-files yes
などと書いて試してみても、ドット・ファイルが表示されるので、あきらめてパッチを当てて使うこと半年...。

imap-2004 がリリースされたので、自分の Vine 用に rpm を作っていたとき、この設定ファイルの値を保存する所(src/osdep/unix/env/unix.c:1524)で、


hideDotFiles = atoi (k);
という記述を発見。そこで

set hide-dot-files 1
とすると、見事にドット・ファイルは非表示となったのであった。

余計なパッチが一つ減ったのはうれしい(^^)v