1 - Postfix LMTP サポート ========================= LMTP は Local Mail Transfer Protocol ローカルメール配送プロトコルを 意味し、RFC2033 に詳述されています。Postfix はローカルホストまたは リモートホストで動いている最終配達エージェントと通信するために、この プロトコルを使います。 このプロトコルは興味深い可能性を開きます: Postfix フロントエンド マシンが複数のメールボックスバックエンドマシンを LMTP を使って 動かすことができます。メールの負荷が増えたら、さらに Postfix フロント エンドシステムと LMTP メールボックスバックエンドシステムを増やせば よいのです。これは Wietse が Postfix のデザインを描き始めたときに 思い描いたモデルです - SMTP サーバとメールボックスサーバを苦痛なしに 増やし続けられる、スケーラブルなアーキテクチャ。 このような分散アーキテクチャには一緒に動き続けるための糊が必要です。 ユーザデータベースをフロントエンドとバックエンドシステムで共有する ために、ネットワークデータベース (LDAP や mysql) を使うことができます。 どのマシンもメールインフラストラクチャの single point of failure と ならないようにするために、複製されたデータベースを使います。 Postfix LMTP サポートは Postfix SMTP クライアントを修正した バージョンをベースにしています。初期のバージョンは Mirapoint, Inc. USA の Philip A. Prindeville によって書かれました。このコードは USA リチャードソン、ダラスの Texas 大学 のAmos Gouaux によりさらに 修正され、多くのドキュメントも改訂されました。Wietse Venema が コードを現在の姿に集約しました。 2 - 概要 ======== このドキュメントのほとんどの例は CMU Cyrus IMAP/POP サーバを使って おり、これは次のところから得られます: http://asg.web.cmu.edu/cyrus/ LMTP を使う唯一のアプリケーションではおそらくありませんが、 これが最も議論される傾向にあります。これらの例は Cyrus 2.1.5 を ベースにしています。Cyrus の 2.x ブランチは以前のリリースよりも LMTP 配送に非常に力を入れています。Cyrus の古いリリースを使う 場合、このドキュメントの補遺に議論があります。 Postfix では様々な方法で LMTP 配送を設定することができます。 UNIX ドメインソケットを使った配送と TCP ソケットを使った配送が 基本的な二つの方法です。 o Postfix LMTP クライアントからの UNIX ドメインソケットを通した 接続では、同じマシンで動いている非 Postfix LMTP サーバに 配送できます。 o Postfix LMTP クライアントからの TCP ソケットを通した接続では、 ローカルネットワークを介して非 Postfix LMTP サーバに配送できます。 注意: 前者では Postfix が内部で Postfix LMTP クライアントと独自の プロトコルで話すために使う UNIX ドメインソケットと混乱しないでください。 UNIX ドメインや TCP 接続の端点の正確な文法は lmtp(8) マニュアル ページに与えられています。例も以下のテキストに与えられています。 どちらのソケットも Postfix main.cf ファイル (セクション 5 参照) か Postfix transport マップ (セクション 6) のどちらかで指定することが できます。どちらのアプローチがよいかは、サーバの配置に依存します。 3 - UNIX ドメインソケットを使った LMTP ====================================== 同じシステム上で動いている LMTP サーバに Postfix LMTP クライアント から配送するには、これを使ってください。 UNIX ドメインソケットはソケットタイプ ("unix") でローカルファイル システムでの名前として指定されます: unix:/path/name "/path/name" 部分はローカルマシン上の LMTP サーバによって作られた ソケットの名前とします。このドキュメントの後にある具体例を 参照してください。 注意: chroot された環境で Postfix LMTP クライアントを動かすのであれば、 /path/name の解釈は Postfix キューディレクトリ (典型的には /var/spool/postfix) からの相対的なものになります。 デフォルトでは、Postfix LMTP クライアントは chroot されては 動きません。ローカルマシンへの LMTP 配送では、Postfix LMTP クライアントを chroot して動かすもっともな理由はありません。 4 - TCP ソケットを使った LMTP ============================= 同じシステムまたは異なるシステム上で動いている LMTP サーバに Postfix LMTP クライアントから配送するには、これを使ってください。 TCP による配送先は、ソケットタイプ ("inet") および配送先ホスト名、 TCP ポートで指定されます。 inet:hostname:port "inet:" 部分はデフォルトのソケット部分であるため、省略可能です。 配送先ポートも省略可能です。現在、このタイプの接続のデフォルト TCP ポート番号は 24 であり、これは "/etc/services" ファイルで カスタマイズすることができます。このドキュメントの後に具体例が あります。 注意: TCP ソケットを使った接続では、Cyrus 2.0.x LMTP サーバの実装が SASL 形式の認証を主張します。これは Postfix が SASL サポート 付きでビルドされなければならなかったことを意味します (SASL_README 参照)。新しい Cyrus のリリースではこの要求を無効にするオプションが 提供されていますが、使われるアプローチを決めて、それを設定するに 当たっては、大いに注意を払わなければいけません。LMTP サーバへの 認証なしでのアクセスは許可しないようにすることは必須です。 以下の例では両方のアプローチを示します。 Cyrus LMTP サーバの実装には、暗号化されていない接続で平文パス ワードを使った SASL 形式の認証を許可しないものがあります。 これは 2.1.5 の場合にはありません。しかし、これは LMTP リンクを 脆弱にする可能性があることを認識しなければいけません。 LMTP 接続が外界に晒されたネットワークを通るのであれば、 暗号化された接続を使うか、MD5 SASL メカニズムを有効にすべきです。 5 - main.cf 設定を使った LMTP の設定 ==================================== これは最もシンプルな LMTP の設定です。 5.1 - 配送メカニズム -------------------- Postfix main.cf は LMTP サーバにメールを配送するための3つの メカニズムをサポートしています。それぞれの方法はあとの セクションで述べるように、UNIX ドメインもしくは TCP ソケットを 使うことが出来ます。 main.cf メカニズム 1 -------------------- mailbox_transport = lmtp:unix:/path/name (UNIX-domain socket example) mailbox_transport = lmtp:hostname:port (TCP socket example) ローカル (ドメインが $mydestination にある) として名前解決 したメールは Postfix local 配送エージェントに渡されます。 Postfix local 配送エージェントは aliases および .forward ファイルを 展開し、メールボックス配送を非 Postfix LMTP サーバに送る Postfix LMTP クライアントに委託します。 main.cf メカニズム 2 -------------------- local_transport = lmtp:unix:/path/name (UNIX-domain socket example) local_transport = lmtp:hostname:port (TCP socket example) ローカル (ドメインが $mydestination にある) として名前解決 したメールは、非 Postfix LMTP サーバに送るPostfix LMTP クライアントに直接渡されます。メールは Postfix local 配送 エージェントによっては処理されません; つまり aliases や .forward ファイルは処理されません。 main.cf メカニズム 3 -------------------- fallback_transport = lmtp:unix:/path/name (UNIX-domain socket example) fallback_transport = lmtp:hostname:port (TCP socket example) ローカル (ドメインが $mydestination にある) として名前解決 したメールは Postfix local 配送エージェントに渡されます。 Postfix local 配送エージェントは aliases および .forward ファイルを 処理し、/var[/spool]/mail/$user に UNIX アカウントを持つユーザ 宛のメールを配送します。他のローカルユーザ宛のメールは、 メールボックス配送を非 Postfix LMTP サーバに送る Postfix LMTP クライアントに委託します。 5.2 - 例 -------- 5.2.1 - UNIX ドメインソケットを使った LMTP ------------------------------------------ Postfix と Cyrus 間の通信のための UNIX ドメインソケットを使う ためには、それぞれの設定ファイルを次のようにします: /etc/cyrus.conf: SERVICES { ... lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=1 ... } /etc/postfix/main.cf: mailbox_transport = lmtp:unix:/var/imap/socket/lmtp /etc/postfix/master.cf: lmtp unix - - n - - lmtp この場合、Postfix local 配送エージェントは aliases および .forward ファイルを展開し、それからメールボックス配送を Cyrus lmtpd サーバにソケット "/var/imap/socket/lmtp" を通して 委託されます。 注意: Cyrus を動かすユーザ ID と Postfix のユーザ ID の両者が ソケット "/var/imap/socket/lmtp" にアクセスできることを 確かめてください。これは上の例で暗示されていますが、 見過ごされがちなので強調するのに値するのです。 5.2.2 - TCP ソケットを使った LMTP --------------------------------- この例では、次のように以下のファイルが設定されているものとします: /etc/cyrus.conf: SERVICES { ... lmtp cmd="lmtpd -a" listen="127.0.0.1:lmtp" prefork=1 ... } /etc/services: lmtp 2003/tcp /etc/postfix/main.cf: mailbox_transport = lmtp:localhost /etc/postfix/master.cf: lmtp unix - - n - - lmtp 上の設定では、Postfix local 配送エージェントは aliases や .forward ファイルを展開し、メールボックス配送を Cyrus LMTP サーバに 委任します。Postfix はローカルホストのポート 2003 に接続し、 続いてメッセージを Cyrus マスタープロセスにより管理された lmtpd サーバに伝達します。24 は Cyrus LMTP サーバが使っているため、 /etc/services のポート番号を 24 から 2003 に変えました。 使っているバージョンが "-a" オプションをサポートしているかどうかを 確かめるには、Cyrus lmtpd(8) man page を参照してください。 注意: ユーザの直接ログインやユーザが制御するプロセスを許可しない 特定のホストの時だけ、このアプローチを考慮してください。 そうしないと LMTP サーバが悪用されるかもしれません! Cyrus lmtp サービスがローカルループバック (127.0.0.1) 以外の ネットワークで待つようにするのであれば、必ず tcp_wrappers サポート 付きでインストールするようにしてください。そして信頼できる ホストからの "lmtp" サービスへのアクセスのみを許可するように tcp_wrapper を使ってください。そうしないと LMTP サーバが 悪用されるかもしれません! 10章には tcp_wrappers を使った例があります。上の設定で使うには、 例にある /etc/hosts.allow の "deliver" を "lmtp で置き換えて ください。 6 - transport マップの設定を使った LMTP の設定 =============================================== このアプローチは Postfix main.cf 設定ファイルで LMTP サービスを 指定するのとかなり似ています。しかしここでは、Postfix local 配送 エージェントからの委譲ではなく、メールを適切な LMTP サーバに向ける ために、transport マップを使います。 なぜこのアプローチが便利でしょうか? これは複数のドメイン宛の メールをそれぞれのメール取得 (IMAP/POP) サーバに向けたい時に 便利です。例: /etc/postfix/transport: domain1.name lmtp1:unix:/path/name domain2.name lmtp2:lmtp2host /etc/postfix/master.cf: lmtp1 unix - - n - - lmtp lmtp2 unix - - n - - lmtp /etc/postfix/main.cf: transport_maps = hash:/etc/postfix/transport Cyrus LMTP サーバの設定の詳細はセクション 5 を参照してください。 "hash" の代わりに、あなたが選んだマップの形式を使ってください。 代わりに "dbm" を使うシステムもあります。サポートされている マップ形式を見つけるには、"postconf -m" を使ってください。 7 - パフォーマンスの考慮 ======================== これまでの議論はかなり直線的でした。これから面白くなっていきます。 以下を読み終わると、LMTP サービスを設定するに当たって、さらに 多くの考慮すべき要素があることがわかるでしょう。 8 - 単一インスタンスによるメッセージの保存 ========================================== 現在のところ、このトピックは Cyrus を動かしているサイトに 適切ですが、他のアプリケーションでも同様に要因になるかも しれません。 1.6.22 以降、Cyrus は LMTP を通して受信したメールが複数の受信者を 含み、これら全ての受信者が同じ Cyrus パーティションにあるので あれば、このメッセージのただ一つのインスタンスがファイルシステムに 書き込まれます。その他の受信者は、この単一のインスタンスの ハードリンクを見ることになります。 ユーザ基盤によっては、これは LMTP を使う大きな動機になるかも しれません。 セクション 5.2 の例で、一度に扱える ($mydestination 宛の)受信者の 数を増やすことができます: /etc/postfix/main.cf: local_destination_recipient_limit = 300 300 は例として任意に選んだものです。ハードウェアの性能に合わせて 数字を選ぶようにしてください。数字を大きくすると、単一メッセージに 格納することの効果がより大きくなります。しかし大きくしすぎると、 LMTP サーバがメッセージを配送するのに時間がかかりすぎて、 Postfix がタイムアウトに直面するようになるでしょう。この値は くれぐれも注意して選んでください。 注意: 全てのローカル配送エージェント transport が1より大きな 受信者数をサポートしているわけではありません。Postfix LMTP クライアント以外でこれを試す前に、必ずその transport の マニュアルページを確認してください。 セクション 6 の設定例でこの単一インスタンス格納テクニックを 使いたいのであれば、設定は次のようになります: /etc/postfix/main.cf: lmtp1_destination_recipient_limit = 300 lmtp2_destination_recipient_limit = 300 前にも述べたように、受信者数制限をこのように設定する前に システムを詳細に分析して十分に注意を払ってください。 9 - 接続キャッシュのパフォーマンスの改善 ======================================== LMTP を使ったメッセージの配送後、それに続く配送が接続を再利用 できるように、Postfix はしばらくの間、接続を開き続けます。 これは接続ごとにプロセスを一つ生成するという LMTP サーバの オーバーヘッドを減らします。 LMTP の接続キャッシュが働くようにするには、Postfix LMTP クライアントが 配送先のホストを変えないようにします。LMTP サーバを一つしか 動かさない場合には問題ありません。しかし、複数の LMTP サーバを 動かす場合は問題になるかもしれません。 それぞれの LMTP サーバに対して別々の LMTP 配送トランスポートを 設定することで、LMTP クライアントがサーバを変えないように することができます。 /etc/postfix/master.cf: lmtp1 unix - - n - - lmtp lmtp2 unix - - n - - lmtp . . . . . . . . LMTP サーバ #1 への全ての配送に使われる lmtp1 メール配送 トランスポートと、LMTP サーバ #2 に対する lmtp2 トランスポート、 というように transport テーブルのエントリを設定します。 /etc/postfix/transport: foo.com lmtp1:lmtp1host bar.com lmtp2:lmtp2host 10 - Appendix: 古いバージョンの Cyrus ===================================== まずはじめに、もしバージョン 2.1.4 より古い Cyrus 2.x を 使っているのであれば、アップグレードを真剣に考慮すべきです。 初期の 2.0 リリースからは多くのバグフィックスやパフォーマンスの 改善があります。 さらに戻って、1.6.24 は最後の 2.x 以前の製品リリースでした。 (実際には 1.6.25-BETA もありましたが、CMU は 2.x ブランチの サポートに焦点を当てているため、これが正式に リリースされるか どうかはわかりません。) 以下の議論では Postfix の LMTP 機能を Cyrus 1.6.24 とともに使う設定方法に触れます。 Cyrus 1.x と 2.x の重要な違いの一つは、"master" プロセスが 2.x に 含まれたことです。この "master" プロセスは imapd や pop3d、 lmtpd といった、さまざまな Cyrus のコンポーネントを動かすことに 責任を持ちます。2.x 以前では、これらのサービスはインターネット サービスデーモンの inetd により管理されていました。 Cyrus 1.6.24 で LMTP 配送を使えるようにするために最初にすべき ことは、 inetd を設定することです。これには次のファイルの編集が 必要です: /etc/services: lmtp 2003/tcp /etc/inetd.conf: lmtp stream tcp nowait cyrus /usr/sbin/tcpd /usr/cyrus/bin/deliver -e -l /etc/hosts.allow: deliver : localhost : ALLOW deliver : ALL@ALL : DENY "/usr/sbin/tcpd" は tcp_wrapper パッケージ由来のものであり、 これは "TCP ソケットを使った LMTP で hosts.allow を使う" 例で 議論されます。権限のないアクセスからこの LMTP ポートを保護するために これをラップするのは重要なことです。 システムによっては、tcpd が inetd に組み込まれていて、inetd.conf ファイルで指定する必要がないものもあります。tcpd/inetd の 代わりに、xinetd もロギングやアクセス制御といった似たような 仕事をすることができます。 さて Postfix を設定しましょう。/etc/cyrus.conf ファイルの例外を 除いて、基本的には TCP を使った LMTP 配送に Cyrus 2.x の議論が Cyrus 1.x にも適用できます。典型的な Postfix の設定は 次のようになるでしょう: /etc/postfix/master.cf: lmtp unix - - n - - lmtp /etc/postfix/main.cf: mailbox_transport = lmtp メールを Cyrus 1.6.24 LMTP サーバに向けるのに、transport マップを 使うこともできます: /etc/postfix/transport: domain1.name lmtp1:lmtp1host domain2.name lmtp2:lmtp2host /etc/postfix/master.cf: lmtp1 unix - - n - - lmtp lmtp2 unix - - n - - lmtp /etc/postfix/main.cf: transport_maps = hash:/etc/postfix/transport Cyrus 2.x のインストールをカバーする議論を読んだのであれば、 UNIX ドメインソケットの記述が欠けているという、Postfix 設定の 重要な違いに気づくでしょう。これは UNIX ドメインソケットでの 配送が Cyrus 2.x で新しく取り込まれたためで、アップグレードする さらにもう一つの理由です :-)