複数の宛先を追加するときは複数回送る。「何番目の宛先」という形式で指定する。<rcpt-parameters>付きで宛先を追加する。このメールは受理するという応答。milterプロトコルでのメールトランザクションの処理はここで終了し、これ以降MTAからコマンドは送られてこない。変更後の本文が大きい場合は複数のチャンクに分けて応答する。次のコマンドへいってくれという応答。処理中のメッセージを破棄する。SMTPでのメールトランザクションの処理はここで終了するので、milterプロトコルでのメールトランザクションも終了する。差出人を変更する応答。ヘッダーを追加する応答。複数のヘッダーを追加するときは複数回送る。ヘッダーは末尾に追加される*7。指定した位置にヘッダーを挿入する応答。指定した位置のヘッダーを変更する。milterの処理に時間がかかっていることをMTAに知らせる応答。MTA側のタイムアウト時間を伸ばせる。このメールを隔離するという応答。このメールの受信を拒否するという応答。SMTPでは5XX系のレスポンスになる。このメールトランザクションの処理を途中でやめるという応答。このメールの受信を一時的に拒否するという応答。SMTPでは4XX系のレスポンスになる。SMTPレスポンスのコードとメッセージを設定する。「宛先追加」や「ヘッダー変更」などメッセージ本体を変更する応答は「メッセージ終了コマンド」の応答のときでないと返せないことに注意してください。2014/12/10中ではまとめきれなかったので応答のデータフォーマットなどの説明は省略します。まとめmilterプロトコルについてまとめきれませんでした。したら後で追記するかもしれません。managerの作者にばったり会ったときにでも聞いてください。(途中ですが)milterプロトコルの説明を見るとmilterではいろんなことができることがわかります。milterを使うとPostfixの設定だけではできないようなことも実現できます。Postfixの設定だけでは実現できないなぁと思ったときは、milterも組み合わせることも検討してみてください。実際、クリアコードではRubyで小さなmilter(100行以内のもの)を書いて、Postfixの設定だけでは実現できない(実現しようとすると複雑になる)メールシステムの構築をお手伝いしていたりします*8。managerのメーリングリスト、有償でもよいならお問い合わせフォームを使って相談してみてください。libmilterのバインディング開発者にはそんなに有用ではないが、自分でmilterプロトコルを実装する開発者には有用。managerのmilterプロトコル実装はそう。managerを実装しているときはこの情報を知らなかったので一から調べました。以前のPostfixはダメでしたが、Postfixにパッチを送って取り込んでもらったので、今はできるようになっています。こんな機能あったのか。managerでは実装していないな。MTAの実装依存かも。100行以上になるような込み入った機能を実現するmilterをRubyで開発することもあります。managerの約2年ぶりのメジャーバージョンアップである2.0.0をリリースをしました。managerのウェブサイトから引用します。managerはmilterを使って効果的に迷惑メール対策(スパムメール対策・ウィルスメール対策)を行うフリーソフトウェアです。managerはmilterをサポートしているSendmailやPostfixといったMTAと一緒に使うことができます。Ubuntu、CentOS、FreeBSDなどのプラットフォーム上で動作します。メジャーバージョンアップですが、1.8系とは互換性があるため、設定ファイルを変更せずにそのまま簡単にアップデートすることができます。前回のリリースから大きな変更もないのにメジャーバージョンをあげて2.0.0にした理由は、開発が継続していることと動作が安定していることをアピールするためです。managerの前回のメジャーアップデートは2011年6月10日でした。そこから、10回目のリリースが今回のメジャーバージョンアップです。リリースの間隔が6ヶ月あいてしまったこともありましたが、こつこつと改良を続けてきました。managerのメーリングリストだけでアナウンスしていたため、メーリングリストに参加していない方々には開発の様子が見えづらいものでした。managerがより便利になり、より安定したことをアピールします。実際、動作実績が増え*1、ユーザーのみなさんが問題を報告してくださったおかげで、1.8.0の頃よりさらに動作が安定しました。manager本体はもちろんですが、Rubyでmilterを書くための機能であるRuby/milterもかなり安定しました。Rubyでmilterを実装する機会が増え、さまざまなノウハウが溜まりました。これらのノウハウがRuby/milterに反映されています。2.0.0は1.8.0よりも確実によくなっていると自信を持って言えます。リリースに対する反応リリースメールを以下のMLに流したところ、いくつか反応があったので紹介します。postfix-users@postfix.org全て個人宛てに返信があったので、メールをくれた方の名前やメールアドレスは伏せます。パッケージを追加するための作業をしてくれるそうです。いつかやりたいと思っていたことなので大変嬉しいご提案です。いうプロジェクトがあるのでご紹介しておきました*2。later.自分が知っている情報を共有してくれています。PolicyDというプロダクトは知らなかったので、参考になりました。アイデアをとても褒めてくれています。いうプロジェクトがあるので紹介します。test-mailsプロジェクトtest-mailsプロジェクトは、メールシステムのテストに必要なメールを共有することを目的としたプロジェクトです。共有したメールはオープンソースとして利用できるので、だれでも自分のメールシステムのテストに有効活用できます。メールシステムの開発をしていると、テストのためにとても多くのパターンのメールが必要になります。そのようなメールを個人で集めたり作成したりするのは大変です。そんなとき、自由に再利用できるテストメール集があると便利だと思いませんか?このようなメール集を共有すると、自分で多くのテスト用メールを作成したり管理したりするコストが削減でき、網羅的なテストをしやすくなることが期待できます。興味のある人はmilter-manager/test-mailsを参照してください。現在はまだ少しだけですが、テストで使用可能なメールを追加してあります。managerはPythonで書かれたmilterも組合せて使うことができます。managerについて紹介します。managerはサーバーサイドの迷惑メール対策システムをできるだけ簡単に構築するためのフリーソフトウェアです。その秘密は強力な設定記述力にあります。多くのソフトウェアはパラメーターを変更することでプログラムの動作をカスタマイズすることができます。managerにはRubyという本格的なプログラミング言語のインタプリタが内蔵されていて、単にパラメーターを変更するだけではなく、システムにインストールされている迷惑メール対策プラグインを自動検出する(設定の自動化)、怪しい送信元は迷惑メールチェックを強化するが認証済みユーザは緩くする、といったこともできてしまいます。多くの便利な設定は組み込みで含まれているため、そのまま使うだけでも自動でシステムに合わせて効果的な設定になってくれます。導入・運用を簡単にしたいという場合は、外部のメールシステムやアプライアンス製品の利用も十分選択肢に入るはずです。この場合は費用対効果やメールシステムを外部に出してもよいか、どこまでカスタマイズする必要があるか、などが判断基準になることでしょう。managerにはユーザ向けメーリングリストもあるので、検討段階などで疑問点などがあった場合はそこで質問してみてください。managerについて紹介しました。managerはパフォーマンス改善もおこなっており、個人サーバーから大規模なメールシステムまでいろいろな環境で効率的に動かせるようになっています。managerの利用を検討してみてはいかがでしょうか。1.6.4をリリースしました。(メーリングリストでのアナウンス)スケーラビリティ向上のための主な追加機能は以下の3点です。マルチプロセス対応libev対応writeの非同期化このうち、「マルチプロセス対応」と「libev対応」は「実験的」な扱いということで、デフォルトでは無効になっています。「writeの非同期化」は有効になっています。このため、Postfixや子milterのreadが遅い場面では劇的にスループットが向上するでしょう*1。スケーラビリティ向上に加えてRuby対応を強化しています。1.9.2に対応したことです。Rubyでmilterを書くのがより便利になりますね。1.6.4をリリースしたので代表的な変更内容を紹介しました。大量の宛先を削除するmilterを使っている場合。この場合、Postfixのcleanupのreadが遅い。managerの開発を始めたのが2008年の9月なので、2年と少し前になります。この当時はPostfixでmilterを使うというのはそれほど一般的ではありませんでした。最近ではPostfixでmilterを使うというのが選択肢の1つになっています。これは、Postfixのmilter対応が強化されたことと、Web上にPostfixでmilterを利用した事例が増えてきたことが大きな要因でしょう。managerを利用することを想定しないといけません*1。managerがよりスケールするように内部の構造を改良する予定です。1.6.3としてリリースする予定です。1.6.Xシリーズの間は「実験的」な扱いで機能を提供し、1.8.0になった段階で「正式」な機能扱いとする予定です。改良は以下の2点です。マルチプロセス対応イベントループの高速化マルチプロセス対応ではマルチコアのマシンでの性能向上を目指します。イベントループの高速化では1プロセスあたりの性能向上を目指します。ちなみに、現在はシングルプロセス・シングルスレッドで、イベントループにはpoll(2)*2を使っています。managerではマルチプロセスを採用します。manager内部にあるRubyインタプリタとの相性からです。スレッド毎にRubyインタプリタを持てるのであればマルチスレッドでもよかったのですが、現在のRuby(MRI)はそれができないため処理を直列化する必要があり、マルチスレッドにしてもマルチコアを活かしきれないと判断しました。そのためマルチプロセスを選択しています。以下のようにPostfixのmaster/smtpdと同じような構成になります。(worker)」に対応します。(worker)が行います。(master)が行うため、外からはシングルプロセスの構成と区別がつきません。managerがどちらの構成を使っていても同じように扱えるため、Postfixの設定を変更する必要はありません。(worker)の数だけCPUコアを利用して並列に処理することができます。イベントループの高速化メールシステムは複数のメールを同時に扱います。managerはI/Oを多重化し、I/O待ちの間に別のメールを処理することにより、同時に複数のメールを処理しています。I/OとI/Oを待っている間の処理を繰り返して動作することになります。この繰り返しがイベントループです。ここを高速化することにより、1プロセスで同時に処理できるメール数を増やします。規模の大きなメールシステムではより同時接続数が増えますが、このとき、I/Oを多重化する仕組みによって性能特性が変わってきます。伝統的なI/O多重化の仕組みはselect(2)やpoll(2)ですが、これらはI/O対象の数(監視するファイルディスクリプタ数)が増えると大きく性能が落ちることが知られています*3。managerはpoll(2)を使っています。managerは1つのメールに対して複数のmilterに接続するため、I/O対象の数がすぐに大きくなってしまいます。6つmilterを利用している場合は、1メールに対してI/O対象の数が6つ増えます。同時に30メールを処理する場合はI/O対象の数が180になるわけです。そのため、規模が大きいメールシステムではpoll(2)の性能劣化が顕著になるくらいまでI/O対象の数が増えてしまうことになります。managerのイベントループでpoll(2)ではなくlibevを利用できるようにします。libevを利用することにより、I/O対象の数が増えてもイベントループでの急激な性能劣化を防ぐことができ、より大きな規模のメールシステムでもサービスを提供できるようになります。managerを改良しています。改良が終わっていないので少し気が早いのですが、どのような改良を進めているかを紹介しました。1.6.3では簡単にここで紹介した改良を試すことができるようになる予定です。楽しみにしていてください。managerをよろしくお願いします。これまでは中規模のメールシステム(アカウント数が1000件いかない程度)でも利用できることを想定していた。GLibのメインループのバックエンドがpoll(2)だから。1.6.2をリリースしました。このリリースではRubyでmilterを書くために必要な機能がすべて実装されました。これまではメールを拒否したり、隔離する機能は提供していたのですが、差出人を変更する、宛先を追加する、本文を変更するなどメッセージを変更する機能は部分的にしか対応していませんでした。このリリースからメッセージを変更する機能も提供されるようになったので、ほとんどのmilterはRubyでも実装できるようになりました。Rubyでmilterを書くとどのようになるかはhbstudy#15の発表内容で紹介しています。1.6.2のインストール方法・アップグレード方法は以下にまとまっています。managerで簡単迷惑メール対策hbstudy#15でmilterについて発表しました。公開しているスライドの内容は実際に使ったものと異なっています*1。実際に使ったものや当日の雰囲気などが気になる人はUstreamの録画を観てください。スライドのPDFやソース、当日使ったmilterなどはスライドページからダウンロードできます。milterはスライドのソースと同じアーカイブに含まれています。スライドはRabbitというRubyで書かれたフリーソフトウェアで作成しています。Ruby界隈ではとても有名なプレゼンツールなのですが、インフラ界隈ではあまり有名ではないので、当日使ったRabbitの機能を簡単に説明しておきます。スライドの下にでていたうさぎとかめは、うさぎがページ数を、かめが経過時間を示しています。うさぎが前を走っていればペースが速い、かめが前を走っていれば間に合わない、というようにプレゼンテーションの進み具合が視覚的に一瞬でわかるのがよいところです。「残り7:35」と出てもいい感じで進んでいるのかどうかがわからないですよね。タイマー用のテキストがスライドの中にあると不自然ですが、うさぎとかめがスライドの中にいても不自然ではないので、発表者用のビューではなく、表示用のビューに表示することができるのもよいところです。PCの画面とディスプレイの内容を同じ内容にできるので、ディスプレイ側の表示だけおかしくなっている、という状態を防ぐことができます。聞いている人が発表よりもうさぎとかめの方が気になってしまうという問題があります。ここは発表者の腕でなんとかする必要があります。携帯電話でRabbitを遠隔操作していました。仕組みを図示したのものがとちぎRuby会議02の資料公開にあります。今回も大体これと同じ構成です。処理の流れは以下の通りです。ノートPC上のRabbitプロセスの「次のページへ遷移メソッド」が呼び出されて、次のページへ遷移システムとしてはカッコイイのですが、目の前のノートPC上で動いているRabbitを操作するためにインターネットを経由しているので多少タイムラグがあります。それでは、以下に発表内容を簡単にまとめておきます。省略している部分が気になる場合は上述のUstreamの録画を観てください。managerそのものの話は最後に少しする程度にしました。managerがベースとしている技術であるmilterについてです。milterを言葉や図だけで理解するのは少し大変なので、今回は実際にありうる例を動かしながら理解していきます。milterについてmilterとはSendmailが作ったメールフィルターの仕組みです。実際には、この仕組みの中で使われるネットワークプロトコルや、メールフィルターを開発するためのAPI、メールフィルターそのもののことも「milter」と呼ぶことがあります。多くの場合は文脈からどれを指しているかがわかるので、それほど混乱することはありません。8.12.0から正式サポートされています。9年の歴史がある枯れた技術といえます。SendmailだけではなくPostfixでもサポートされています。Postfixでは2006年6月にリリースされた2.3.0からサポートされ、現時点の最新版2.7.1ではmilterのほとんどの機能がサポートされています。こちらも4年の歴史があり、もう十分に実践に投入できるほど使われています。現時点ではmilter*2を用いてメールフィルター機能を実現することは「実験的な試み」ではなく「いくつかある有力な選択肢の1つ」といえます。日本語でのmilterの情報が少ないことは事実です。milterに関する英語の情報はmilter.orgに集まっています。milter.orgにはmilter*3を検索する機能や開発者向けの情報なども載っています。Flowに載っている以下の擬似コードを見れば、複数のmilter*4を同時に用いたときにどのような動作になるかはわかります*5。(xxfi_close)}日本語でもこれと同じような情報を読むことができれば、milter利用の敷居が低くなるかもしれません。ここでは、実際に動かしながらmilter*6がどのように動くのかを確認していきます。上記のmilterの動作フローをざっくりとまとめると、以下のようになります。本文は直列(前のmilterの影響を受ける)本文以外は並列(前のmilterの影響を受けない)詳細な結果は最後に返すmilterは迷惑メール対策に使われることがほとんどです。迷惑メールの手法は複雑化しているので、1つの迷惑メール対策方法で完璧ということは不可能です。複数のmilter(迷惑メール対策方法)を組み合わせて効果的な迷惑メール対策システムを構築する必要があります。milterは上記のような動作のため、milter1の結果を使ってmilter2の挙動を変えるということが難しくなっています。milter1の詳細な結果を使いたければ、メール全体の処理が終わるのを待たなくてはいけません。milter2がエンベロープ情報(送信元や宛先)を取得した段階で実行する迷惑メール対策方法*7を採用している場合は、メール全体の処理が終わるまで待つのは効率的ではありません。milterがどのように動作するかがわかれば、複数のmilterをどのように組み合わせることが効果的かを検討することができます。そのため、milterを用いて効果的な迷惑メール対策システムを構築する場合はmilterの挙動を理解しておく必要があります。milterの挙動の詳細miltrの挙動を理解するためには、以下の3つの要素があることを理解するのが早道です。要素の名前はここでの説明のために便宜的に付けたもので、milterで一般的な用語ではないので注意してください。メールフィルターとして行えることmilterが処理を行うタイミングはSMTPのコマンド+αだけあります。どのようなタイミングかを一言解説を付けています*8。SMTPクライアントが接続してきたとき。SMTPクライアントがHELO/EHLOコマンドを実行したとき。FROMコマンドを実行したとき。TOコマンドを実行したとき。SMTPクライアントがDATAコマンドを実行したとき。メールサーバがメールのヘッダー1つを解析したとき。ヘッダーの数だけn回発生する。メールサーバがメールのヘッダーをすべて解析し終わったとき。メール本文を処理しているとき。メール全体を処理したとき。message」のときしか実行できません。「メッセージ変更機能」は後述します。milterは処理を行うたびにメールサーバに結果を返さないといけません。メールサーバに返せる結果は以下の通りです。