株式会社クリアコード > ククログ

ククログ


milter managerによる柔軟なメールフィルタリング: milterとは?

先日、milter managerを用いたメールフィルタリングについて話してきました。milter managerというより、milter managerがベースにしているmilterという技術についての説明の方に重点をおいています。これは、日本でのmilter情報が不足しているのを少しでも解消したいということからです。

milterはPostfixも積極的にサポートを強化している有用な技術の1つです。メールに関わっている方はその仕組みや動作について把握しておいて損はないはずです。

milter managerによる柔軟なメールフィルタリング

それでは、コメント付きでとばしとばし資料の内容を紹介します。完全版はリンク先を見てください。資料のPDF・ソースもリンク先にあります。

内容

話すこと

milterについて説明する前に、まず、より一般的なメールフィルタについてまとめておきます。その後、メールフィルタの仕組みの1つであるmilterについて説明し、最後にmilter managerも利用したmilterの使い方について説明します。

メールシステム

メールシステム

外部から届いたメールをユーザに配信するのがメールシステムです。メールシステム内部では単純に届いたメールをそのままユーザに配信するのではなく、なんらかの処理をしてから配信します。そのため、ユーザには加工されたメールが配信されます。例えば、Receivedというメールヘッダを追加したりします。

メールフィルタ

メールフィルタ

つまり、メールシステムの中にはメールフィルタの機能が内臓されています。それでは、メールフィルタについてもう少し詳しくみていきます。

メールフィルタの仕組みの種類

フィルタの仕組み

メールフィルタの実現方法にはいくつかありますが、大きく以下の3種類に分けられます。

  • MTAに組み込む方法
  • MTAのプラグインとする方法
  • フィルタMTAを挿入する方法

それぞれの方法について図で説明します。

MTAに組み込む方法

MTA組み込み

MTAに組み込む方法では、MTA内にメールフィルタの機能を内蔵させます。MTA単体で実現できます。

例えば、Postfixではaccess(5)やcidr_table(5)を用いてフィルタを適用することができます。

MTAのプラグインとする方法

MTAにプラグイン

MTAのプラグインとしてフィルタを実現する方法では、MTAと別のプロセスにメールを通すことによりフィルタリングします。この別のプロセスがフィルタプラグインです。milterもこのタイプのメールフィルタの仕組みです。

MTAとプラグインのやりとり方法はMTA独自のことがほとんどです。SendmailやPostfixなど複数のMTAで動くmilterの方が珍しいといえます。milterが複数のMTAでサポートされているのは、既に多くの有用なmilterが存在しているからと思われます。

フィルタMTAを挿入する方法

フィルタMTAを挿入する方法

複数のMTAでメールシステムを構築することもできます。フィルタMTAを挿入する方法では、外部からのメールをユーザに配信するまでの間に、フィルタリングをするMTAにメールをリレーすることで、メールフィルタリングを実現します。MTA間のやりとりにはSMTPを使うので、どのMTAでも実現できる方法です。

アプライアンス製品などはこの方法でメールフィルタ機能を提供することが多いです。

実現方法の違い

違いは?

それでは、それぞれのメールフィルタの実現方法による違いです。それぞれ特徴があるので、必要とされている機能や導入した後のメンテナンスなども考慮して、メールシステム毎に適した方法を選択することが重要です。

MTAに組み込む方法の利点はお手軽であるということです。組み込まれている機能はMTA毎に違いますが、組み込まれた機能で十分な場合はこの方法を利用するとよいでしょう。機能を追加する場合は、パッチを当てたり、バージョンアップをしたりすることになります。機能を追加する場合はメンテナンスのことをよく考えてください。

MTAのプラグインとしてメールフィルタを利用する方法の利点は、柔軟性です。多くの場合、プラグインではMTA本体が実現していることのほとんどすべてを実現できます。そのため、必要な機能をMTA本体を変更せずに追加することができます。MTA組み込み方法よりは導入が面倒ですが、システムや世間の変化にあわせたメールシステムを構築する場合は、機能追加や複数の機能を組み合わせられるこの方法を利用するとよいでしょう。

フィルタMTAを挿入する方法の利点は、どのMTAでも利用できることです。フィルタMTAを挿入する場合は、MTAが数珠つなぎになります。そのため、MTAを挿入・削除するたびに複数のMTAのリレー設定を変更する必要があり、面倒です。もし、必要な機能をすべて満たしたフィルタMTAを1つ導入するのであれば、この方法がよいでしょう。複数のフィルタMTAを導入する場合は導入・メンテナンスのことをよく考えてください。

メールフィルタの実現方法の選び方

選び方

以上のことをふまえると、以下のポイントをメールフィルタの実現方法を選択するために使えます。

  • MTAに組み込みの機能で十分な場合: MTAに組み込む方法
  • 複数の機能を組み合わせる場合: MTAのプラグインとする方法
  • 必要な機能を持ったフィルタMTAを1つだけ使う場合: フィルタMTAを挿入する方法

これからの迷惑メール対策

迷惑メール対策

メールフィルタは迷惑メール対策に利用されることが多いです。その観点から考えるとどの方法がよいでしょうか。

迷惑メールの配信方法は多様化しているため、1つの対策で完璧に防ぐことはできません。複数の手法を組み合わせて対応する必要があります。

また、これからも新しい手法で迷惑メールは送られ続けるでしょう。そうなった場合でも新しい対策を適用できることが求められます。

よって、迷惑メール対策には、複数の機能を組み合わせることが容易で、新しく機能を追加できるプラグインタイプの方法が適しているといえます。プラグインタイプの中でも、複数のMTAで利用でき、すでに多くの実装が存在するmilterがオススメです。ということで、milterの説明に入ります。

milterとは何か

milter?

「milter」といっても文脈によっては微妙に異なるものを指すことがあります。「広義の○○」「狭義の○○」といわれたりするものと同じようなものです。

「milter」はメールフィルタの仕組み全体のことを指す場合と、フィルタプログラムのことを指す場合が多いです。「milterに対応したMTA」という場合は「メールフィルタの仕組み」を指していますし、「このmilterを使う」という場合は「フィルタプログラム」のことを指しています。

milterの説明に入る前に、混乱しないように別々の名前をつけておきます。ただし、正式な名前ではないことに注意してください。あくまで、わかりやすさのためにつけた名前です。

メールフィルタの仕組み
milterシステム
MTAとフィルタプログラムが使うプロトコル
milterプロトコル
↑に準拠したフィルタプログラム
milter

それぞれの関係を図示するとこうなります。

milterシステム

milterプロトコル

SMTPとmilterプロトコル

MTAとmilter間でやりとりするmilterプロトコルはSMTPと密接に関わっています。milterプロトコルでのコマンドのほとんどはSMTPでのコマンドに由来しています。

例えば、MTAがSMTPで「EHLO」コマンドを受け取ったらmilterにも対応する「helo」コマンドが送られます。その時、EHLOで受け取ったFQDNも一緒に送られます。

また、milterプロトコルはSMTPと平行して動作するのも重要なポイントです。MTAがメッセージすべてを受信してからmilterにコマンドを送るのではないので、「helo」コマンドのときにmilter側でrejectすれば、MTAも「EHLO」コマンドのときにrejectし、「MAIL FROM」や「RCPT TO」などそれ以降のコマンドを受けとりません。

複数のmilterを使用する場合

複数のmilter利用時の動作

milterシステムでは複数のmilterを同時に利用することができます。複数のmilterを利用する場合もSMTPと平行して動作する点は変わりません。

複数のmilterを利用する場合に注意することは、それぞれのmilterはコマンド毎に順番に動くということです。1つめのmilterの処理が終わってからはじめて2つめのmilterにコマンドが送られます。

1つめのmilterの処理結果が2つめのmilterに影響を与えます。例えば、1つめのmilterで本文を変更したら、2つめのmilterには元の本文ではなく1つめのmilterが変更した本文が渡されます。DKIMなどメッセージが変更されると問題があるような処理をする場合はmilterの順序に気をつけてください。

例えば、DKIMの場合は、送信するメールの署名も受信したメールの署名の検証も一番外部に近い部分で行います。署名を行うmilterは、他のすべてのmilterが処理を終わった後に適用しなければ署名が壊れてしまうため、一番最後のmilterにします。署名を検証するmilterは、他のmilterがメッセージを変更する前に適用しなければ検証に失敗してしまうため、一番最初のmilterにします。

以上がmilterの動作です。それでは、milterの使い方について進みます。

milterシステムの気になるところ

気になるところ

milterシステムを使い込んでいくといくつか気になるところがでてきます。milterシステムはプラグインタイプなので他の方法に比べて機能の追加は容易ですが、さすがにmilterの数が増えてくると面倒になります。

milterはすべてのセッションに対して適用されます。ホワイトリストの管理は各milterの役割になります。しかし、複数のmilterを利用している場合は、複数の形式でホワイトリストを管理することになりメンテナンスが面倒になります。

これらの問題点を解決するソフトウェアがmilter managerです。

milter managerとは

milter manager

milter managerはMTA側に足りない機能を補って、milterをより使いやすくするソフトウェアです。MTA・milterどちらにも変更を加えずに導入することができるため、既存の環境を壊すことなく導入できます。

クリアコードの他のソフトウェアと同様、milter managerもオープンソースソフトウェアとして公開しているので自由に利用することができます。

milter manager導入時の構成

milter manager: 構成

milter managerはMTAとmilterの間で動作します。MTAからのmilterプロトコルのコマンドをmilterに転送し、milterからのレスポンスをMTAに転送します。MTAとmilterの間でやりとりを制御することができます。

milter managerはmilterとして実装されているため、MTAには1つのmilterとしてみえます。また、milter managerはMTA側のmilterプロトコルも実装していて、その機能を使ってmilterへコマンドを転送しています。よって、milterからはmilter managerがMTAのようにみえます。このため、MTAもmilterも変更なしでそのまま動作することができるのです。

milterシステム管理の負担を減らす

milter管理

milterシステムの設定・管理にいくつか作業が必要になります。

milterを追加する場合は、milter本体を設定した後にMTAにmilterを登録する必要があります。複数のmilterを同時に利用している場合はmilter本体の設定のみをして、MTA側に登録することを忘れてしまうこともあります。

milter managerはそのような部分を自動化し、単純なミスを防ぎます。/etc/以下を走査し、インストールされているmilterを検出したら自動で登録します。また、インストールはされているが無効にされている場合もそれを検出し、自動でそのmilterを使用しないようにします。

milterシステムは複数のMTAでサポートされていますが、完全に同じサポート状況ではなく、MTA毎に異なる部分があります。そのため、milterによってはSendmailでは動くが、Postfixでは動かないというのもありました。(最近はそのようなmilterは減ってきています。)

milter managerはMTAとmilterの間で動作します。その位置でSendmailとPostfixのmilterシステムのサポートの違いを吸収するため、同じmilterを変更せずにそのまま動作させることができます。

他にも、Sendmailはmilter毎にタイムアウトなどのパラメータを設定できるが、Postfixはmilter全体の設定なってしまうなどといった違いがあります。このような違いも、milter managerがmilter毎にパラメータを管理することにより、PostfixでもSendmailと同じようなmilterシステムサポートを利用することができます。

milterシステム管理のまとめ

milter管理のまとめ

このようにmilter managerを導入することにより、milterシステムの管理が負担を減らすことができます。milter managerはMTAとmilterの間に入って動作するため、MTA・milterのどちらも変更せずにmilterシステムのサポートをより充実させることができます。このため、メールシステム全体の管理の負担も減ります。

柔軟なmilter利用

柔軟性: ユーザ毎の設定

前述の通り、milterはすべてのメールに対して適用されるため、milter全体でホワイトリストを共有したり、ユーザ毎に適用するmilterを選択することが面倒になります。それぞれのmilterにまたがって設定をする必要があります。

milter managerを使うとこの問題を解決することができます。MTAはすべてのmilterを適用しますが、milter managerはSMTPセッションの情報を使って動的に適用するmilterを選択する機能を提供しています。また、LDAPやRDBなどからもデータを取得することができるため、メールシステム外にあるアカウントシステムと連携した制御をすることもできます。

この機能を使うことにより、milter全体で共有するホワイトリストやユーザ毎にどのmilterを適用するかということをmilter managerレベルで一括管理できます。これにより、ユーザからの要望や利用状況に合わせた柔軟なメールシステムをメンテナンスしやすい構成で運用できます。

tarpit問題

tarpit問題: ケース例

前述の通り、milter managerはmilterシステムをより使いやすくする機能を提供します。しかし、それだけにとどまらず、さらにメールシステムをより使いやすくする機能も提供します。その1つがtarpit問題の解決方法の提供です。

tarpitとはSMTPクライアントへのレスポンスを(RFCの範囲内で)わざと遅らせることにより、すぐに切断してくる迷惑メール送信SMTPクライアントからのメールを受信しないようにする迷惑メール対策手法です。

迷惑メール送信側はタイムアウト時間をRFCで示されている時間よりも短めに設定していることが多いというデータがあります。これは、できるだけ短時間で多くの迷惑メールを送信したいというのが理由ではないかと考えられています。この特徴にあわせた迷惑メール対策手法がtarpitです。

tarpitを使うことにより多くの迷惑メールを受信せずにすみますが、同時SMTPセッション数が増加し、リソース消費量が増えるという問題があります。1〜2分程度のレスポンス遅延を導入することにより、2倍程度セッション数が増えるというデータもあります。

この問題は、SMTPクライアントが切断したらすぐにSMTPセッションを終了することにより緩和することができます。Postfixなどでtarpitを実現すると、SMTPクライアントの切断を検出せずに、指定した時間までSMTPセッションを維持してしまいます。そのため、必要以上に同時SMTPセッション数が増加してしまうのです。

tarpit問題の解決

解決法2: milter manager

milter managerにはSMTPクライアントが切断したらすぐにSMTPセッションを終了する機能がついています。

milter managerはmitlerプロトコルでMTAからSMTPクライアントのソケット情報を受け取っています。それとnetstatコマンドの結果*1を照合することによってMTA外からSMTPクライアントの切断を検出します。切断を検出したらMTAとmilter双方に処理の中止を通知することですぐにSMTPセッションを終了することができます。

まとめ

柔軟な迷惑メール対策

milterをベースとした柔軟なメールフィルタリングを実現するための仕組みを説明しました。

メールフィルタリングには以下のような仕組みがあり、それぞれ特徴があります。

  • MTAに組み込む方法: お手軽
  • MTAのプラグインとする方法: 柔軟
  • フィルタMTAを挿入する方法: 汎用的

新しい迷惑メール対策にも柔軟に対応していくメールシステムにはプラグインタイプがオススメです。プラグインタイプの仕組みの1つとしてmilterを説明しました。

milterはSMTPと密接に連携している仕組みです。milterプロトコルについても説明し、milterがどのような流れでフィルタリングを行うかも示しました。すでに多くの迷惑メール対策手法がmilterとして実現されているため、今すぐmilterを使って迷惑メール対策を組み込んだメールシステムを構築することができます。

最後に、milterシステムをより使いやすくするソフトウェアとしてmilter managerを紹介しました。milter managerを導入すると、設定の自動化や一元管理によりメンテナンスが容易なメールシステムが構築できることを説明しました。

組織に合わせたメールシステムを構築する場合があれば参考にしてみてください。

*1 Linux上では/proc/以下の情報を利用することも考えられます。

この記事の続き

2010-02-05

«前の記事: 処理待ちをより簡単に行えるようになったUxU 0.7.6をリリースしました 最新記事 次の記事: Ruby/groonga 0.9.0, 0.9.1: 高速で使いやすい検索エンジンライブラリへ向けて»
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|