このドキュメントに書かれているキュー投入前コンテンツフィルタリング 機能は、流量が少ないサイトにのみ適しています。詳細は以下の"メリットとデメリット" のセクションを参照してください。
バージョン 2.1 では、Postfix SMTP サーバは入ってくるメール全てを、 Postfix メールキューに入れられる「前に」全てのメールを検査するコンテンツ フィルタリングプロキシサーバに転送できるようになりました。
キュー投入前コンテンツフィルタは以下のように使うことを意図しています:
インターネット -> Postfix SMTP サーバ -> キュー 投入前 フィルタ -> Postfix SMTP サーバ -> Postfix cleanup サーバ -> Postfix キュー -< smtp
local
virtual
キュー投入前コンテンツフィルタを FILTER_README ドキュメントに記述されているアプローチと混同しないでください。そちらは Postfix メールキューに入れられた「後に」メールをフィルタリングするものです。
このドキュメントには以下の話題について書いてあります:
フィルタ前の Postfix SMTP サーバがインターネットからメールを受信して 通常のリレーアクセス制御や SASL 認証、RBL 検索、存在しない送信者や受信者 アドレスの拒否などを適用します。キュー投入前コンテンツフィルタは フィルタリングされていないメールコンテンツを Postfix から受け取り、以下の いずれか1つをおこないます:
SMTP を通して Postfix にメールを再投入しますが、その内容や 配送先は変えられているかもしれません。
Postfix に適切な SMTP ステータスコードを送り返すことでメールを 拒否します。Postfix はリモートの SMTP クライアントにそのステータスを 返します。こうすれば Postfix はバウンスメッセージを送る必要は ありません。
フィルタ後の Postfix SMTP サーバはコンテンツフィルタからメールを 受け取ります。それ以降 Postfix は通常通りメールを処理します。
ここに書かれたキュー投入前コンテンツフィルタは FILTER_README ドキュメントに書かれた キュー投入後コンテンツフィルタのように働きます。多くの場合は以下の "メリットとデメリット" セクションで書かれた制限の 下で、同じソフトウェアを使えます。
メリット: Postfix は入ってくる SMTP メール転送が完了する前に メールを拒否することができるため、Postfix は拒否したメールを送信者 (これは たいてい偽造されています) に送り返す必要がありません。受け入れなかった メールの責任はリモート SMTP クライアントに残ります。
デメリット: リモート SMTP クライアントは期限内に SMTP 応答が あることを期待しています。システムの負荷が上がるにつれ、期限内に答えるのに 使える CPU サイクルの残りがだんだん少なくなっていき、結果としてメールの 受付を止めるかメールのフィルタリングを止める必要が出てきます。キュー 投入前コンテンツフィルタが流量の少ないサイトでのみ使えるというのは、 こういった理由のためです。
デメリット: コンテンツフィルタリングソフトウェアが多量のメモリ リソースを使ってしまうことがあります。メモリを使い果たさないようにする ためには、フィルタ前の SMTP サーバプロセス数を減らして、メールの集中で コンテンツフィルタプロセスを起動しすぎてシステムをダウンしないように します。言い換えると、SMTP クライアントはサービスを受けるまで長時間 待たなければいけないということです。
以下の例では、フィルタ前 Postfix SMTP サーバはメールを localhost ポート 10025 で待つコンテンツフィルタに渡します。フィルタ後の Postfix SMTP サーバは localhost ポート 10026 を通してコンテンツフィルタからメールを受け取ります。 それ以降 Postfix は通常通りメールを処理します。
コンテンツフィルタ自身にはここでは触れません。SMTP が使えるならどんな フィルタを使っても構いません。SMTP が使えないコンテンツフィルタ ソフトウェア用には、Bennett Todd の SMTP プロキシがすばらしい PERL/SMTP コンテンツフィルタリングフレームワークを実装しています。 http://bent.latency.net/smtpprox/ を参照してください。
インターネット -> Postfix SMTP サーバ on port 25 -> フィルタ on localhost port 10025 -> Postfix SMTP サーバ on localhost port 10026 -> Postfix cleanup サーバ -> Postfix incoming キュー
これは master.cf ファイルを編集することで設定します:
/etc/postfix/master.cf: # ============================================================= # service type private unpriv chroot wakeup maxproc command # (yes) (yes) (yes) (never) (100) # ============================================================= # # フィルタ前の SMTP サーバ。ネットワークからメールを受け取り、 # localhost ポート 10025 のコンテンツフィルタに渡します。 # smtp inet n - n - 20 smtpd -o smtpd_proxy_filter=127.0.0.1:10025 -o smtpd_client_connection_count_limit=10 # # フィルタ後の SMTP サーバ。コンテンツフィルタからメールを # localhost ポート 10026 で受け取ります。 # 127.0.0.1:10026 inet n - n - - smtpd -o smtpd_authorized_xforward_hosts=127.0.0.0/8 -o smtpd_client_restrictions= -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o smtpd_data_restrictions= -o mynetworks=127.0.0.0/8 -o receive_override_options=no_unknown_recipient_checks
注意: "=" や "," の前後に空白を置いてはいけません。
フィルタ前の SMTP サーバエントリは、通常 master.cf ファイルの最初で 設定されるデフォルトの Postfix SMTP サーバエントリを修正したバージョン です:
SMTP セッションの数がデフォルトの 100 からたった 20 に 減らされています。これはメールの集中でコンテンツフィルタのプロセスが 多くなりすぎてしまって、動いているシステムがダウンしてしまうことを 防ぎます。
"-o smtpd_client_connection_count_limit=10" は 1つの SMTP クライアントだけで 20 の SMTP サーバプロセス全てを使って しまわないようにします。この制限は信頼するリレーホストからしかメールを 受けないのであれば不要です。
注意: この設定は安定版 Postfix 2.1 リリースでは無視されます。 この機能は Postfix 2.2 までは experimental 版のみで使えます。
"-o smtpd_proxy_filter=127.0.0.1:10025" は フィルタ前 SMTP サーバに、localhost ポート 10025 で待っている コンテンツフィルタに入ってきたメールを渡すように伝えます。
フィルタ後の SMTP サーバは新しい master.cf エントリです:
"127.0.0.1:10026" はフィルタ後の SMTP サーバをネットワークに 晒さないように、localhost アドレスのみで待たせます。「絶対に」フィルタ後の SMTP サーバをインターネットに晒さないでください :-)
"-o smtpd_authorized_xforward_hosts=127.0.0.0/8" によってフィルタ後の SMTP サーバがフィルタ前 SMTP サーバからリモート SMTP クライアントの情報を受け取れるようになり、フィルタ後 Postfix デーモンが localstho[127.0.0.1] ではなく、リモート SMTP クライアントの 情報をログに記録できるようになります。
フィルタ後の SMTP サーバの残りの設定は、"フィルタ前" SMTP サーバですでにおこなったことと重複しないようにするためのものです。
デフォルトでは、フィルタが仕事をするのに与えられた時間は100秒です。 それ以上かかると、Postfix は諦めてリモート SMTP クライアントにエラーを 報告します。この時間制限を長くすることもできますが (以下のセクションの 設定パラメータを参照)、そうするとリモートクライアントがタイムアウト したときに制御できなくなるので無意味です。
プロキシを制御するパラメータ:
smtpd_proxy_filter (文法: host:port): キュー投入前コンテンツフィルタのホストおよび TCP ポート。ここに host または host: が指定されないと、localhost が想定されます。
smtpd_proxy_timeout (デフォルト: 100s): キュー投入前コンテンツフィルタへの接続とコマンドや データの送受信のタイムアウト。プロキシエラーはすべて maillog ファイルに ログとして記録されます。プライバシー上の理由から、リモートの SMTP クライアントは "451 Error: queue file write error" しか見えません。 内部の詳細を他人に公開するのは正しいことではないでしょう。
smtpd_proxy_ehlo (デフォルト: $myhostname): キュー投入前コンテンツフィルタに EHLO コマンドを送るときに使うホスト名。
フィルタ前 Postfix SMTP サーバはコンテンツフィルタに接続し、 メッセージを1つ配送して接続を切ります。コンテンツフィルタにメールを 送っている間、Postfix は ESMTP を話しますが、コマンドパイプライニングは 使いません。Postfix は独自に EHLO、XFORWARD (localhost [127.0.0.1] の 代わりにリモートクライアント IP アドレスをログに記録するため)、DATA および QUIT コマンドを生成し、フィルタ前 Postfix SMTP サーバが拒否 しなかった MAIL FROM および RCPT TO コマンドすべてのコピーを改変せずに 転送します。SMTP プロキシサーバは Postfix SMTP サーバと同じ MAIL FROM および RCPT TO コマンドの文法を受け付けなければいけません。Postfix は その他の SMTP コマンドは送りません。
フィルタ前 Postfix SMTP サーバから、通常は標準ではないポートで 待っているフィルタ後の Postfix SMTP サーバへは、コンテンツフィルタは SMTP コマンドを改変しないで渡すことが期待されています。フィルタが コンテンツを拒否する場合、フィルタは否定的な SMTP 応答をフィルタ前 Postfix SMTP サーバに返し、フィルタ後の Postfix SMTP サーバとの SMTP の 会話を完了させずに接続を強制切断すべきです。
Postfix からプロキシへの相互作用の詳細は、"透過性" というタイトルのセクションにあります。
フィルタ前 Postfix SMTP サーバは承認された MAIL FROM、RCPT TO および DATA コマンドを転送しますが、TLS や SASL コマンドのような他のコマンドは 転送しません。なので透過的ではないかもしれません。
一方、リアルタイムコンテンツフィルタは透過的でなければいけません。 非透過的リアルタイムコンテンツフィルタをサポートするためには、Postfix は フィルタ前 Postfix ESMTP 機能と Postfix がリアルタイムコンテンツ フィルタから受け取る機能を組み合わせなければいけないでしょう。
将来の Postfix のバージョンが DSN をサポートしても、 コンテンツフィルタが EHLO 応答で DSN サポートを通知しなければ、 フィルタ前 SMTP サーバは 1) EHLO 通知で DSN 機能を隠すか、2) DSN を 知っているメールが非 DSN 配送先に配送されるときに必要な仕事をすべて 複製するかのどちらかが必要です。
コンテンツフィルタは EHLO 応答で 8BITMIME サポートを 通知しないため、フィルタ前 SMTP サーバは 1) EHLO 通知で 8BITMIME 機能を隠すか、2) コンテンツフィルタに渡す前にコンテンツを quoted-printable に変換するかのどちらかが必要です。
パフォーマンス: リアルタイムコンテンツフィルタと互換性が ないために Postfix がフィルタ前 EHLO 応答から要素を削除しなければ ならない場合、Postfix はクライアントが有効な EHLO コマンドを送ったら すぐにコンテンツフィルタに接続しなければいけません。これは MAIL FROM や RCPT TO コマンドがすべて拒否されたときに大量のリソースを 無駄にします。
そのため、Postfix SMTP サーバはキュー投入前コンテンツフィルタに関して 透過することはできません。