Postfix でうまく使えるソフトウェアの例:
Postfix は全てのパラメータがまともなデフォルト値を持つため、ここ
では上書きする物のみを示します。特に、Postfix は自分と同じドメイン
(とサブドメイン)のクライアントとそのクラス A, B, または C ネット
ワークへのメールのみを中継します。とても遅い/速いネット/ マシンが
あれば、 master.cf (inetd.conf といくぶん似ています) をチューン
する必要があります。
ワークステーション:
サーバ:
このような環境で、メールスプールディレクトリが NFS で共有されているか
ユーザがメールボックスに POP でアクセスするか、ユーザが自分のワーク
ステーションでメールを受けるかのどれかでしょう。後者の場合、それぞれ
のユーザはメールをそれぞれのワークステーションに転送するようにサーバに
エイリアスを持ちます:
Server:
エイリアスデータベースが /etc/aliases にないシステムもあります。
あなたのシステムでの場所を探すには、postconf alias_maps
コマンドを実行します。
次の例では、メールは user@domain として送信され、全てのメールは
ローカルドメインを受け持つメールサーバに転送されます。
メールは全て user@nullclient ではなく user@domain として送信される
ため、user@nullclient 宛のメールアドレスに対するメールサーバの特別な
設定は必要ありません。
これはあなたの組織がローカルドメイン用に内部 MX レコードを構築して
いることを想定しています。
あなたのイントラネットが MX レコードを内部で使用していなければ、
イントラネットメールゲートウェイ自身を指定する必要があります:
あなたのイントラネットが DNS を内部で使用していなければ、同様に
DNS 検索も止める必要があります:
インターネットドメインへのルーティング情報をtransport テーブルで指定し、transport テーブル検索をおこないます。
重要: ローカルへメールを配送するエントリを省略しないでください。
メールが "mail loops to myself" 条件でバウンスします。
システムが db の代わりに dbm ファイルを使って
いれば、dbm:/etc/postfix/transport を指定します。Postfix が
どのマップ形式をサポートしているかを見るには、postconf -m
コマンドを使います。
transport テーブルを編集したら、毎回
postmap /etc/postfix/transport コマンドを実行して下さい。
Postfix 警告およびエラーメッセージ
設定例
Sendmail との非互換性
数百の Postfix プロセスを走らせる
Postfix のパフォーマンス
ネットワーク経由でのメール受信
メールの中継
リモート配送
ローカル (非バーチャル) 配送
メーリングリスト
バーチャルドメイン
アドレスの書き換え
コンテンツフィルタリング
他の配送方法: UUCP, FAX, etc.
Postfix キューのメンテナンス
Postfix のコンパイルとインストール
特定のオペレーティングシステムでの問題
Compaq での問題
IRIX での問題
POP や IMAP の問題
Postfix はメール配送システムです。メールを読むための POP や IMAP
といったサービスは Postfix は実装していません。Postfix のような
ソフトウェアと協力できる POP/IMAP の実装がいくつかあります。
スタンドアロンマシン
インターネットに直接アクセスできるスタンドアロンマシンでは、Postfix
は設定の変更なしに動くでしょう。少なくとも、それが Postfix のソース
コードをダウンロードした時に、インストールされる状態です。マシンが
ファイアウォールのあるイントラネット内にあったり、短時間ダイアル
アップで接続されるのであれば、関連するセクションを参照して下さい。
ワークステーションとサーバ
このセクションは、ワークステーション・サーバ環境について記載します。
全てのシステムはメールを user@domain として送信します。全てのシステム
は user@hostname 宛のメールを受け取ります。サーバは user@domain 宛の
メールも受け取ります。
/etc/postfix/main.cf:
myorigin = $mydomain
/etc/postfix/main.cf:
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, $mydomain
/etc/aliases:
joe: joe@joes.workstation
jane: jane@janes.workstation
Null クライアント
Null クライアントはメールの送信のみできるマシンです。ネットワーク
からはメールを受け取らず、ローカルへの配送も全くおこないません。
Null クライアントでは、メールボックスへのアクセスは典型的には
POP または NFS を使います。
/etc/postfix/main.cf:
myorigin = $mydomain
relayhost = $mydomain
/etc/postfix/master.cf:
Comment out the SMTP server entry
Comment out the local delivery agent entry
イントラネットでの Postfix の利用
ファイアウォール内のネットワークのホストで Postfix を設定する最も
簡単な方法は、全てのメールをイントラネットメールゲートウェイに
送り、メールゲートウェイが転送に気をつけるようにするものです。
/etc/postfix/main.cf:
myorigin = $mydomain
/etc/postfix/main.cf:
relayhost = $mydomain
/etc/postfix/main.cf:
relayhost = host.my.domain
/etc/postfix/main.cf:
disable_dns_lookups = yes
/etc/postfix/transport:
my.domain smtp:
.my.domain smtp:
thishost.my.domain local: !!!important!!!
localhost.my.domain local: !!!important!!!
/etc/postfix/main.cf:
transport_maps = hash:/etc/postfix/transport
ファイアウォール上での Postfix の利用
注意: この文章は Postfix のバージョンの日付が 19991115 と
それ以降でのみ使えます。Postfix のバージョンを調べるには、
postconf mail_version コマンドを実行します。
ファイアウォールマシン上の Postfix を、my.domain 宛のメールを 内部のゲートウェイマシンに転送し、*.my.domain 宛のメールを 拒否するように設定する方法は? 問題は標準の relay_domains メール中継制限では my.domain を指定すると *.my.domain へのメールも 許してしまうことです。
/etc/postfix/main.cf: mydestination = $myhostname, my.domain, localhost.my.domain relay_domains = transport_maps = hash:/etc/postfix/transport /etc/postfix/transport: my.domain smtp:inside-gateway.my.domain (forwards user@domain) .my.domain smtp:inside-gateway.my.domain (forwards user@firewall) /etc/postfix/master.cf: Comment out the local delivery agent
システムが db の代わりに dbm ファイルを使って いれば、dbm:/etc/postfix/transport を指定します。Postfix が どのマップ形式をサポートしているかを見るには、postconf -m コマンドを使います。
自分自身のホスト名を持っておらず (動的 IP 割り当て)、必ず user@your-isp.com としてメールを送るのであれば、次のセクションの user@domain としてメールを送る際に、 あるユーザはローカルに配送したい も検討すべきです。
マシンがほとんどの時間接続されていないのであれば、Postfix がメールを 到達が難しい場所へ配送する機会はあまり多くありません。メールを 常時接続されたマシンへ送るのがよいでしょう。
/etc/postfix/main.cf: relayhost = smtprelay.someprovider.com
通常、Postfix は都合が良い時に外行きのメールを配送しようとします。 マシンがオンデマンドダイアルアップ IP を使っていれば、あなたが新しい メールを送信したり、Postfix が遅延メールを配送しようと試みるたびに システムは電話の呼び出しをします。このようなコールがなされるのを 防ぐには、自動 SMTP メール配送を禁止します。
/etc/postfix/main.cf: defer_transports = smtp (オンデマンドダイアルアップ IP を使うシステムのみ)
ほとんどの時間切り離された LAN を通して Postfix を使ってメールを配送 したい人もいるでしょう。このような状況下では、メール配送は Postfix の SMTP クライアントが標準に準拠するために送信先および受信元の DNS 検索を しようとする際に遅延に苦しめられるでしょう。このような遅延を防ぐには、 全ての SMTP クライアントの DNS 検索を使わないようにします。
/etc/postfix/main.cf: disable_dns_lookups = yes (ほとんどの時間切り離された LAN を通した配送のみ)
DNS 検索を使わない場合、relayhost として IP アドレスまたは 一つまたはそれ以上に解決されるホスト名のどちらかを指定しなければ いけません (DNS 検索を使用不可にすると、Postfix は MX 検索を行ないません)。
次のコマンドを PPP または SLIP ダイアルアップスクリプトに加えます:
sendmail コマンドの正確な場所はシステムに依存します。UNIX の あるバージョンでは /usr/lib/sendmail を使って下さい。
キューがフラッシュされたかを見るには、このようなシェルを使います:
#!/bin/sh # Start deliveries. /usr/sbin/sendmail -q # Allow deliveries to start. sleep 10 # Loop until all messages have been tried at least once. while mailq | grep '^[^ ]*\*' >/dev/null do sleep 10 done
メールの自動配送をしたくない(オンデマンドダ イアルアップ IP のみ) を使用しないのであれば、新たにポストされたメールを キューから出すために、ダイアルアップ接続が確立している間に時々上の コマンドを実行する必要があります。
Postfix のような分散されたメールシステムでは、実装するのは困難です。 Sendmail とは違い、Postfix のメール配送プロセスはどれもユーザによる 制御下では動きません。代わりに Postfix はユーザプロセスに親子関係の ないデーモンプロセスがメールを配送します。これは非常にさまざまな、 環境変数やシグナルハンドラ、その他 UNIX の親プロセスから子プロセスへ 渡すプロセスの性質による、潜在的セキュリティ問題をなくします。
Postfix はお互いにサブシステムを隔離するために複数のプロセスを 使います。配送エージェントがユーザプロセスと直接やりとりするのは Postfix を普通のメーラよりも安全にしようとしてきた努力をふいにして しまいます。
Sendmail を使っていた時は、4時間後にメールの配送が遅れているというメールが 常に送信者に戻ってきました。
Postfix が "delayed mail" 通知を4時間後に送るようにするには、次のように 指定します:
/etc/postfix/main.cf: delay_warning_time = 4
Postfix ではメールの遅延通知はデフォルトではおこないません - 常に大量のメールを受け取ることになってしまうので。
これが「正しい」動作であるということを主張さえする人もいるでしょう。 おそらくむしろ期待や慣れの問題でしょう。
これは Postfix を遅くすることでのみ「修正できます」。上の例では、 Postfix は配送を始める前に、まず完全に全ての配送リストを展開する必要が あります。設計では Postfix は異なる配送先へのメールは並列に配送し、 ローカルも例外ではありません。これが Postfix が sendmail よりも速い理由です。
Wietse は Postfix の実装が「正しい」動作だと信じており、sendmail の デフォルトの動作は sendmail がエイリアスループを避けるのにかなり みすぼらしいアルゴリズムを使っていた時の暗い部分の名残ではないかと 疑っています。
しかし、Postfix の作為的な実装による結果、owner-foo エイリアスは エイリアス展開が終わった後のみにしか効果がありません。
コマンドやファイルへの配送を含む、エイリアス展開中に起こった配送問題は 元のエンベロープの送信者アドレスに報告されます。
理由は、送信者アドレスが置き換えられていることを知らない Postfix キューマネージャによりバウンスが送られるためです。
この制限は Postfix ローカル配送エージェントが配送できないメールを 取り扱う方法を変えることで修正されるでしょう。
問題を修正するには、 root で次のコマンドを実行して下さい:
これは Postfix が期待する形式の aliases.db を作成します。# newaliases
これを修正するには、Berkeley DB ライブラリを適切にインストールします。 例えば、RedHat version 7.0 は Berkeley DB version 3 オブジェクト ライブラリをデフォルトで使用していますが、/usr/include/db.h ファイルはデフォルトではインストールされていません。正しく Postfix を構築するには、db3-devel パッケージをインストールしなければいけません。
正しくインストールされたシステムでは、<db.h> ファイルを インクルードし、-ldb でリンクすることで同じバージョンの Berkeley DB ライブラリからファイルをアクセスします。
不幸なことに、Linux システムには自動的にファイルパーミションを Sendmail の sendmail コマンドに想定された状態に「修復する」 linuxconf という役に立つユーティリティを持つものがあります。 Postfix の sendmail 実行ファイルの set-uid ビットをリセット した時でさえ、うれしいことに linuxconf は再びオンにしてくれます。
SuSE システムでは、ファイルパーミション修正ユーティリティは SuSEconfig と呼ばれます。他の Linux システムは異なる名前を 使うかも知れません。通常のマイレージなどの免責事項が適用されます (訳注: 環境によってコマンド名などが違うので、各自の状況に応じて 対応して下さいの意)。
# /etc/rc.d/init.d/linuxconf stop && rpm --erase linuxconf
そして、/etc/rc.config で PERMISSIONS_SECURITY の最後に local があるか 確かめます。例:/usr/sbin/sendmail root.root 755
CHECK_PERMISSIONS=set PERMISSION_SECURITY="secure local"
エンベロープ送信者アドレスは、メッセージで From: ヘッダアドレスが 指定されない場合のデフォルト値にもなります。
To fix, specify the envelope sender address on the sendmail command line: 修正するには、sendmail コマンドラインでエンベロープ送信者アドレスを 指定します:
sendmail -f user@domain ...
カーネルパラメータをブート時に設定するには、次の行を /boot/loader.conf ファイルに追加します (これは FreeBSD 4.x に特有です):
kern.ipc.maxsockets="5000" kern.maxfiles="16384" kern.maxfilesperproc="16384" kern.ipc.nmbclusters="65536"
カーネルパラメータを実行時に設定するには、次のコマンドを root で 実行して下さい (これは FreeBSD 4.x に特有です):
# sysctl -w kern.ipc.maxsockets=5000 # sysctl -w kern.maxfiles=16384 # sysctl -w kern.maxfilesperproc=16384 # sysctl -w kern.ipc.nmbclusters=65536
次の情報はカーネルのバージョンに依存します。
/etc/sysctl.conf を持つ Linux システムでブート時にパラメータを 設定するには、次の行を加えます:
fs.file-max = 16384 kernel.threads-max = 2048
実行時にカーネルパラメータを設定するには、次のコマンドを root で実行します:
# echo 16384 > /proc/sys/fs/file-max # echo 2048 > /proc/sys/kernel/threads-max
メールが incoming キューにたくさんたまっていても、Postfix は外行きの SMTP 配送を少ししか実行しません。なぜもっと SMTP クライアントを動かさないのでしょう?
これはメールを受信することでディスクの I/O が飽和状態になり、 Postfix キューマネージャが要求を処理できる機会を十分に得られないの かもしれません (たくさんの SMTP サーバプロセスがたった一つの キューマネージャとディスクアクセスの競合をします)。
ディスクを速いものと交換することで解決します。
私は現在もソフトウェアサイドからそのスケジューリング問題を解決しようと しています。
現在のところの解決策は、一つのマシンに複数の IP アドレスを設定し、 それぞれの IP アドレス毎に一つずつ Postfix を走らせます。 それぞれの Postfix はキューディレクトリを共有できませんが、 メールボックスディレクトリの共有は可能です。
単にそれぞれの Postfix をことなる設定ディレクトリで動かします:
# postfix -c config_directory start
それぞれの main.cf ファイルは扱うべきインターフェースに依存する、 異なる $myhostname の設定を持ちます。
/my/own/main.cf: queue_directory = /my/own/queue/directory myhostname = foo1.my.domain inet_interfaces = $myhostname
私の Postfix サーバは遅過ぎます。SMTP ポートに telnet で接続 すると (telnet hostname 25)、応答が40秒後に返ります。 その一方で、POP ポートに telnet すると (telnet hostname 110) 遅延なく応答が返ります。
回答:
ネームサービスに問題があります。Postfix は C ライブラリルーチン gethostbyname() および gethostbyaddr() を SMTP クライアントのホスト名を見つける ためにコールします。これらのライブラリルーチンは、要求を満たすために いくつかのシステム設定ファイルを使います。これらは実際、Postfix の制御外の理由で DNS の呼び出しにたどり着くかもしれません。
システムによって、これらの制御ファイルは /etc/nsswitch.conf、 /etc/svcorder、/etc/host.conf や他の名前になっています。 これらのファイルは C ライブラリルーチンがローカルの /etc/hosts を DNS の前か後、どちらに使うかを指定します。
Postfix サーバが SMTP クライアントの接続のログを解決したホスト名では なく数字の IP アドレスで取ります。nslookup を使うとアドレスは 名前に解決されます。
セキュリティを上げるために chroot jail の中で Postfix サーバを 動かしていて、いくつかの設定ファイルが足りないのでしょう。 chroot jail の中で動かすには、Postfix SMTP クライアントとサーバは システムの設定ファイルのコピーを Postfix キューディレクトリに必要と します。正確なファイルのリストはシステムにかなり依存しますが、 少なくとも次のものは必要になるでしょう:
/var/spool/postfix/etc/resolv.conf /var/spool/postfix/etc/services
もちろんこれらのディレクトリとファイルは root が所有し、postfix ユーザがアクセスできなければならないので、ディレクトリは モード 0755、ファイルは 0644 である必要があります。
詳細は Postfix の配布ソースコードにある examples/chroot-setup ディレクトリ内のファイルを見て下さい。
Postfix が SMTP クライアントのホスト名を SMTP クライアント IP アドレスで検索する際には、Postfix は SMTP クライアントの IP アドレスが SMTP クライアントのホスト名にリストされているかもチェックします。
SMTP クライアント IP アドレスが SMTP クライアントホスト名以下に 挙げられていなければ、Postfix は SMTP クライアントのホスト名は SMTP クライアント IP アドレスに属していないと結論づけ、SMTP クライアントホスト名を無視します。この警告はなぜ SMTP クライアントが ジャンクメールもしくはメールリレーチェックで止められたか、又は 止めなかったかをわかるように、ログに記録されます。
SMTP クライアントの DNS レコードを管理する人にコンタクトし、 それぞれの IP アドレスに PTR レコードが必要であり、この PTR レコードに A レコードがマッチすることが必要であると説明しても よいでしょう。
一つの IP アドレスが複数の PTR レコードを持ち得るという RFC を
読む人もいますが、それは PTR レコードを今以上に使いにくくします。
いずれにせよ、一つの IP アドレスに複数の名前を持たせることは、
SMTP クライアントのホスト名を見つける問題を悪化するだけです。
慌ててはいけません! Postfix のバージョン 19991227 またはそれ以降に
更新して下さい。使っている Postfix のバージョンを知るには、
postconf mail_version コマンドを実行します。
それ以前のバージョンの Postfix では、
Postfix の新しいバージョンでは、
正確には、Postfix の UCE 制限が次の条件下でソースルートアドレスの
転送を拒否します:
しかし、プライマリ MX ホストの Postfix は今でも、信頼するクライアント
から受け取った物であれば以前と同様にソースルートアドレスを転送します。
信頼する SMTP クライアントを通したソースルートリレーに対する保護を保証
したいのであれば、正規表現制限を他の SMTPD 受信者制限に先だって指定
します:
これを全ての MX ホストに導入します。
最も好ましい方法は、ユーザに古いプレーン SMTP ではなく、ある認証
プロトコルを通してメールを送信してもらうことです。
次に良い方法は古いプレーン SMTP を使い、例えば "please login via POP
before using SMTP" スキームでユーザを先に認証する方法です。
この場合、DRAC
のような Postfix ではないソフトウェアがクライアントの IP アドレス
情報を持つ Postfix 互換のアクセステーブルを保守します:
システムが db ファイルの代わりに dbm ファイルを
使っているのであれば、hash の代わりに dbm を指定します。
Postfix がどのマップタイプをサポートしているかを知るには、
postconf -m コマンドを使います。
注意: DRAC のような
ソフトウェアには hash ファイルの代わりに btree ファイルを
使うものがあります。その場合、それに応じて上の
check_client_access 制限も合わせる必要があるでしょう。
あまり好ましくない方法は、クライアントの IP アドレス (例えば、
256 ブロック) や DNS ホスト名 (例えば whatever.pop.isp.com) に基づく
ものです。IP/DNS ベースのリレーアクセス制御を使うのであれば、同じ
ISP の顧客が誰もあなたのマシンにスパムを向けないことを祈りなさい。
そうでなければ、あなたはインターネットワイドのブラックリストに名前を
連ねるでしょう。
最も好ましくないのは送信者アドレスに基づく方法です。あなたの
サイトからメールを受け取ったことがある人がだますのは、つまらないほど
簡単です。もし送信者アドレスアクセス制御を使っていれば、あなたの
ユーザのアドレスをスパマーが見つけないことを祈りなさい。
Postfix はユーザごとの制限をサポートしています。制限は SMTP サーバにより
実装されています。こうして、ポリシーを破ろうとしたユーザは、SMTP
サーバによりメールが拒否されます。このように:
この実装は2つの検索テーブルを使います。一つにはどのユーザがどこにメールを
送ることができるかを定義し、もう一つにはどの配送先がローカルかを
定義します。これをあるユーザだけは外部の配送先にメールの送信を許され、
大半は制限されるようにスキームを変更することは読者に演習として残します。
この例では DB/DBM ファイルを想定していますが、これは LDAP や SQL でも
可能です。
システムが db ファイルの代わりに dbm ファイルを
使っているのであれば、hash の代わりに dbm を指定します。
Postfix がどのマップタイプをサポートしているかを知るには、
postconf -m コマンドを使います。
smtpd_restriction_classes 変数は Postfix が chroot jail に入る前に
/etc/postfix/local_domains.db を開けるようにするために存在します。
つまり、単なる実装の産物です。
このスキームはユーザを認証しないため、いくつかの方法でバイパスできて
しまいます:
助けて! Postfix がオープンリレーになった
あるリレーチェックソフトによると、Postfix が任意の非ローカル配送先
宛のメールを受け入れています。
>>> MAIL FROM:<someone@some.where>
<<< 250 Ok
>>> RCPT TO:<test@some.other.site@some.site>
<<< 250 Ok
>>> DATA
<<< 354 End data with <CR><LF>.<CR><LF>
>>> (message body)
<<< 250 Ok: queued as A958F5A15
/etc/postfix/main.cf:
smtpd_recipient_restrictions =
regexp:/etc/postfix/regexp_access
...other restrictions...
/etc/postfix/regexp_access:
/[%!@].*[%!@]/ 550 Sender specified routing is not supported here.
モバイルユーザ宛のメールの中継をしたい
あるマシンで Postfix をセットアップしましたが、これを通して
メールを中継できるインターネットユーザのグループを選びたいのです。
IP アドレス (すなわち 動的 IP の人々の 256 ブロック) またはホスト名
(whatever.dialup.isp.com) のどちらかを中継のベースにしたいです。
/etc/postfix/main.cf:
smtpd_recipient_restrictions =
permit_mynetworks
check_client_access hash:/etc/postfix/client_access
check_relay_domains
/etc/postfix/client_access:
4.3.2.1 OK
5.4.3.2 987654321
/etc/postfix/main.cf:
smtpd_recipient_restrictions =
permit_mynetworks
check_client_access hash:/etc/postfix/client_access
check_sender_access hash:/etc/postfix/sender_access
check_relay_domains
/etc/postfix/client_access:
11.22.33 OK
dialup.isp.com OK
/etc/postfix/sender_access:
joe@my.domain OK
blow@my.domain OK
どのユーザがサイト外にメールを送信できるかを制限したい
あるユーザはインターネットにメールを送信できて、それ以外はできないように
するには、どのように Postfix を設定するのですか? アクセスできない
ユーザには一般にバウンスメッセージを受け取らせたい。このようなアクセス
制限が必要かどうかは議論しないで下さい。私の決定ではないので。
554 <user@remote>: Access denied
/etc/postfix/main.cf:
smtpd_recipient_restrictions =
check_sender_access hash:/etc/postfix/restricted_senders
...other stuff...
smtpd_restriction_classes = local_only
local_only = check_sender_access hash:/etc/postfix/local_domains, reject
/etc/postfix/restricted_senders:
foo@domain local_only
bar@domain local_only
/etc/postfix/local_domains:
this.domain OK matches this.domain and subdomains
that.domain OK matches this.domain and subdomains
Postfix をバックアップ MX ホストとして設定したい
ある他のドメインのセカンダリ MX である場合に必要な設定は次の通りです:
DNS: the.backed-up.domain.name IN MX 100 your.machine.name /etc/postfix/main.cf: relay_domains = the.backed-up.domain.name smtpd_recipient_restrictions = permit_mynetworks check_relay_domains
ある他のドメインのプライマリ MX である場合には次の設定も必要です:
/etc/postfix/main.cf: transport_maps = hash:/etc/postfix/transport /etc/postfix/transport: the.backed-up.domain.name smtp:[their.mail.host.name]
システムが db ファイルの代わりに dbm ファイルを 使っているのであれば、hash の代わりに dbm を指定します。 Postfix がどのマップタイプをサポートしているかを知るには、 postconf -m コマンドを使います。
リモートアドレスのメールサーバに接続すると、次のようになります:
Jul 14 12:45:38 myhostname postfix/qmgr[2246]: 74FBF30501: from=<sender@sender.domain> size=309 (queue active) Jul 14 12:45:39 myhostname postfix/smtp[2349]: 74FBF30501: to=<recip@recip.domain> relay=none, delay=3944, status=deferred (Name service error for domain recip.domain: Host not found, try again)しかし、ホスト名の nslookup はうまくいきます。
いくつかの異なる問題があり得ます。
しかし、いつもメール配送が失敗するのを目撃する場合には、他の問題を 抱えているかも知れません: 壊れたパス MTU 発見プロトコル。もしくは 壊れた PIX ファイアウォールかも知れません。
バグ ID は CSCds90792 です。"fixup protocol smtp" 機能はメールの 最後の "." と "CRLF"が別々のパケットで送られる場合に正しく 扱えません。
"fixup protocol smtp" が有効になった Cisco PIX に隠されたメーラを 認識する方法は? バージョン 5.1 もしくはそれ以降については、 fixup protocol smtp コマンドは SMTP バナーの文字を "2", "0" および "0 SPACE" 文字を除いてアスタリスクに変えます。
このようなフィルタに隠されたメーラに接続すると、次のように見えます:
220 **************************************0******0*********20 ****200**0******** *0*00
しかしメッセージ本体はいくつかのデータグラムとして送られ、それぞれの データグラムはローカルネットワークの MTU に依存しますが、たいてい 1kbyte またはそれよりいくぶん大きいものです。
いつもタイムアウトでメールが失敗するのであれば、パス MTU 発見を 実装した最近の UNIX マシンを送信機で動かしているのではないかと思います。 これはマシンが LAN 上を送るパケットと同じ大きさのパケットを、 IP DON'T FRAGMENT ビットを立てることで中間のルータがそのネットワークに とってパケットが大き過ぎることを理由にフラグメントさせることを妨げて、 マシンに送らせてしまいます。
メッセージがどのネットワークパスに従うかによって、途中のルータが ICMP MUST FRAGMENT メッセージでパケットが大き過ぎるといって応答するものも あります。通常は送信側のマシンがパケットを細かく分割して再送します。
しかし、これは送信側マシンに近い側のあるルータが、ある種の攻撃から システムを保護しようとする誤った試みで、このような ICMP フィードバックメッセージを破棄してしまうと破綻します。この場合、 ICMP フィードバックメッセージは送信側マシンに到達することはなく、 接続はタイムアウトします。
これは間違った設定のパケットフィルタの後ろにある web サーバで起こる 問題と同じ設定問題です: 小さな画像/ファイルは損なわれずに送られますが、 大きな画像やファイルはサーバが MUST FRAGMENT ICMP フィードバック メッセージを見ないためにタイムアウトします。
回避方法: パス MTU 発見を送信側マシンで使用しないようにします。 メールは出ていきますが、もちろん他のみんなが依然苦しむでしょう。 パス MTU 発見を使用不可にするには? Solaris には ndd コマンドがあります; 他のシステムは 動いているシステムのカーネル パラメータを制御するための sysctl のような別の方法を使います。
修正: ICMP MUST FRAGMENT メッセージを破棄するルータを見つけ、 責任者に設定を修正するように説得します。
SMTP を話す最初のサーバがクライアントへのグリーティングで「あなたの メールを受け入れるつもりはない」という意味の 5xx 状態コードで接続を 拒否すると、Postfix は諦めてメッセージを送信者にバウンスします。
SMTP を話す最初のサーバがクライアントへのグリーティングで「後で 来て下さい」を意味する 4xx 状態コードで接続を拒否すると、 Postfix は戻って後に配送を遅延します。
Sendmail がしていることで、もちろん sendmail がすること全てが正しいと 我々が知っていると仮定して、Postfix はサーバが 4xx や 5xx で グリーティングした時でも、他の MX アドレスに接触すべきと主張 する人もいるでしょう。
残念ながら、インフラストラクチャをひどい設定にする人がいます。 最も優先度の高い MX サーバを世界から見えるようにしますが、 これは外部からの接続を 5xx または 4xx グリーティングで拒否します。 Sendmail が二番目によい MX サーバへ行くという理由だけで、これらの 人達は全てのメーラがそうすると思っています。
もしこのような設定が問題であれば、下はそれを回避するコントロールになります。
/etc/postfix/main.cf: smtp_skip_4xx_greeting = yes smtp_skip_5xx_greeting = yes
smtp_skip_5xx_greeting はバージョン 20000104 以降の Postfix リリースにあります。使っている Postfix のバージョンを知るには、 postconf mail_version コマンドを使います。
変更をすぐに反映するには、postfix reload コマンドを実行します。
chroot 操作はシステムへの侵入者に対する重要な壁を作ります。
2つの解法があります:
"unknown mail transport error" の原因を見つけるには、次のコマンドを
タイプします:
"fatal: unknown service: smtp/tcp" が意味するのは?
Postfix /etc/postfix/master.cf ファイルが Postfix SMTP
クライアントが chroot 環境内で走ることを指定しています。しかし、
このモードでの操作に必要なファイルが /var/spool/postfix 以下に
インストールされていません。
メール配送が "unknown
mail transport error" といって失敗します
これは egrep や less という友達に出会う機会です。
Postfix の進展や失敗を含めた動作は、典型的には /var/log/maillog
という名前のログファイルに記録されます。あなたのマシンの Postfix
の動作が記録されている場所を見つけるには、/etc/syslog.conf
ファイルを調べます。
egrep '(warning|fatal|panic):' /var/log/maillog | less
fatal や panic のラベルがついたメッセージには特に
注意を払って下さい。これらは Postfix が幸せに動くために取り組まれる
必要がある、破壊的な失敗を記述しています。fatal のラベルが
付けられた問題は、設定ファイルやファイルの権限などを調整することで、
あなたが修正します。panic のラベルが付けられた問題は
Postfix の作者が Postfix のソースコードを変更することで修正します。
Root のメールが誰にも配送されません
ローカルメールの配送に procmail (または
他のコマンド) を使っていると、Postfix はメールをルートとして配送
しません。代わりに procmail (や他のもの) を nobody
として実行します。いつかきっと Wietse は外部コマンドを root で
走らせるほど十分に Postfix を信頼するようになるでしょう。
解決法: (異常な条件を除いて) root としてログインすることを 考えないのと同様に、root でメールを受け取らないようにします。
/etc/aliases: root: you
エイリアスデータベースが /etc/aliases にないシステムもあります。 あなたのシステムでの場所を探すには、postconf alias_maps コマンドを実行します。
その警告メッセージは comsat ネットワークサービスが off に なっていて、新着メール通知が失敗したことを意味しています。
Postfix 配送エージェントの comsat クライアントコードを 使用不可にするには、次のように指定します:
/etc/postfix/main.cf: biff = no
comsat ネットワークサービスを使用可能にするには、 inetd.conf ファイル内の対応するエントリのコメントを外します。
この警告メッセージは NIS (Network Information Service) が有効になって いないことを意味します。完全にOKです。Postfix が前もってこのことを 知るのはかなり困難です。
Postfix local 配送エージェントの NIS クライアントコードを無効に するには、main.cf ファイルの対応するセクションを更新し、 エイリアスファイルの形式によって次のどれか一つを指定します:
/etc/postfix/main.cf: alias_maps = $alias_database
これは、ローカルのエイリアスデータベースが定義されていれば、 Postfix にそれだけを使うことを強制します。
このセクションの情報は Postfix バージョン 19991216 またはそれ以降に 当てはまります。使っている Postfix のバージョンを知るには、 postconf mail_version コマンドを使います。
デフォルトでは、Postfix の SMTP サーバはどのローカルユーザが存在 するかは知らず、unknown@your.site 宛のメールを手際良く 受け取ります。理由は、異なるローカル配送エージェントが異なる 形式のユーザデータベースを持っているからです。
もちろん存在しないローカルユーザ宛のメールは結果的に配送できないものと してバウンスされますが、なぜまず始めにこのようなメールを受け取るので しょうか? local_recipient_maps パラメータで、ローカルアドレスを 持つ全てのテーブルに問い合わせることで、ユーザが存在するか見つける 方法を Postfix の SMTP サーバに 教えることもできます。
例えば、デフォルトの Postfix ローカル配送エージェントを /etc/postfix/master.cf で使っているのであれば、次のように 指定します:
/etc/postfix/main.cf: local_recipient_maps = $alias_maps, unix:passwd.byname
しかし、Postfix の SMTP サーバを chroot させて動かしていると、 chroot jail の中 (通常は /var/spool/postfix/etc) に パスワードファイルのコピーを必要とするシステムもあります。 これを見つけるにはやってみるしかありません。
デフォルトでは、Postfix の SMTP サーバは Postfix virtual マップについて知っており、 それ以上の設定がなければ known-user@virtual.domain 宛のメールを 受け取ります。
/etc/postfix/main.cf: myorigin = domain.name
/etc/postfix/main.cf: virtual_maps = hash:/etc/postfix/virtual /etc/postfix/virtual: root root@localhost postmaster postmaster@localhost
システムが db ファイルの代わりに dbm ファイルを 使っているのであれば、hash の代わりに dbm を指定します。 Postfix がどのマップタイプをサポートしているかを知るには、 postconf -m コマンドを使います。
変更を反映するには、postfix reload コマンドを実行します。
/etc/postfix/main.cf: home_mailbox = Maildir/
どんな相対パス名も / で終わると maildir 配送にします。 home_mailbox の値がユーザのホームディレクトリのパス名に付加 されます。
maildir フォーマットは .forward ファイルを通した 配送でもサポートされています。/file/name/ を配送先として 指定して下さい。最後に / がつくと maildir 配送をします。
/etc/postfix/main.cf: mailbox_command = /path/to/procmail /etc/postfix/main.cf: mailbox_command = /path/to/procmail -a $EXTENSION
できることなら、 $ や "、IFS、&& のようなシェルのメタ文字やビルドインを使うのは避けて下さい。 Postfix が負荷の大きなシェルプロセスを使わざるを得なくなります。 しかし、procmail はブタであり、シェルを回避して得られるものはあまり ありません。
- DOMAIN
- 受信者アドレスの @ の右側の文字列。
- EXTENSION
- オプションのアドレス拡張部分。
- HOME
- 受信者のホームディレクトリ。
- LOCAL
- 受信者アドレスの @ の左側の文字列、 例えば $USER+$EXTENSION。
- LOGNAME
- 受信者のユーザ名。
- RECIPIENT
- 受信者アドレス全体、$LOCAL@$DOMAIN。
- SHELL
- 受信者のログインシェル。
- USER
- 受信者のユーザ名。
解決法、戦う兆候(?)からDelivered-To: ヘッダをオフにするには:
/etc/postfix/main.cf: smtpd_recipient_restrictions = ... regexp:/etc/postfix/access_regexp ... smtpd_recipient_restrictions = ... pcre:/etc/postfix/access_regexp ... /etc/postfix/access_regexp: /^(.*)-outgoing@(.*)/ 554 Use $1@$2 instead
POSIX 正規表現サポート (regexp) は最近の UNIX システムではデフォルトで 使えます。Perl 互換正規表現サポート (pcre) はオプションです; Postfix ソースディレクトリのトップにある PCRE_README ファイルを 参照して下さい。
FAQ の Majordomo での approve コマンドの問題の項目も参照して下さい。
今のところ、推奨する回避方法は以下にマッチするあらゆるヘッダを取り除く ように approve スクリプトを編集することです:
/delivered-to/i
はい、これはモデレータが自分が何をしているか知っていることを 想定しています。
あまりお勧めしない回避方法は、majordomo のようなコマンドへの配送 時には Delivered-To: を挿入しないことです。 FAQ の 醜い Delivered-To: ヘッダを取り除きたい というエントリを参照して下さい。
10年以上前の脆弱なシステムへのメールを受け取らねばならない場合、 潜在的に危険な MAIL FROM や RCPT TO コマンドを拒否する regexp フィルタを慎重に設定します。
/etc/postfix/main.cf: smtpd_sender_restrictions = regexp:/etc/postfix/envelope-regexp reject_unknown_sender_domain smtpd_recipient_restrictions = regexp:/etc/postfix/envelope-regexp permit_mynetworks check_relay_domains /etc/postfix/envelope-regexp: /[/|]/ REJECT
しかし、/ を持つ全てのエンベロープアドレスを拒否してしまうと、 X.400 アドレス構造があらわに残っている単純な X.400 - インターネットアドレスマッピングで問題を引き起こします。
メッセージヘッダの中身に関しては、header checks 制限に関する ドキュメントも参照してください。これらの制限はコマンド・ファイルを 宛先とする攻撃に対する保護に使われます。例えば、Errors-To: や Return-Receipt_To: メッセージヘッダなど。
内部の email 配送リストを実装したいのです。all@our.domain.com のような もので、これは従業員全てへのエイリアスです。始めはエイリアスマップを 使おうと考えたのですが、"all" が「外部」からアクセス可能になって しまい、これは望みません... :-)Postfix はアドレス毎のアクセス制御を実装できます。次に続くのは クライアントの IP アドレスをベースにしており、IP スプーフィングを 受けやすいです。
/etc/postfix/main.cf: smtpd_recipient_restrictions = hash:/etc/postfix/access ..the usual stuff... /etc/postfix/access: all permit_mynetworks,reject
システムが db ファイルの代わりに dbm ファイルを 使っているのであれば、hash の代わりに dbm を指定します。 Postfix がどのマップタイプをサポートしているかを知るには、 postconf -m コマンドを使います。
さて、あなたのマシンが全てのインターネットメールを直接インターネットから 受け取る時にはこれで十分でしょう。もしネットワークがオフィスよりも 少し大きいと、それはうまくいきそうにありません。例えば バックアップ MX ホストが外から来たメールのクライアント IP アドレスを 「ロンダリング」すると、信頼するマシンから来たようにメールが見えるでしょう。
一般的な場合には、二つの検索テーブルが必要です: 一つは保護する必要がある 配送先のリストを持つテーブルで、もう一つは保護した配送先へメールの送信が 許されたドメインのリストを持つテーブルです。
次に続くのは送信者の SMTP エンベロープアドレスをベースにしたもので、 SMTP 送信者のスプーフィングをうけやすいです。
/etc/postfix/main.cf: smtpd_recipient_restrictions = hash:/etc/postfix/protected_destinations ..the usual stuff... smtpd_restriction_classes = insiders_only insiders_only = check_sender_access hash:/etc/postfix/insiders, reject /etc/postfix/protected_destinations: all@my.domain insiders_only all@my.hostname insiders_only /etc/postfix/insiders: my.domain OK another.domain OK
冗長な smtpd_restriction_classes は Postfix が chroot jail に入る 前にどの検索テーブルを開くかを知るために必要です。単なる実装の産物です。
SMTP の送信者アドレスをかたるだけでよいので、このスキームが見つからずに 済むのは比較的簡単です(?)。
内部リストの流量が少なければ、おそらくモデレートする意義が増すでしょう。
Sendmail 形式のバーチャルドメインは Postfix バージョン 20001118 以前ではサポートされていません。
注意深く virtual マニュアルページの 指示に従ってください。
長めの回答を続けます。
コマンドは適切な権限で実行されねばならないため、 ファイルやコマンドへのメール配送はセキュリティに敏感な操作です。 Postfix ローカル配送エージェントのように root 権限を持つ ソフトウェアしかコマンドの権限をセットできません。
セキュリティ上の理由から、Postfix は root 権限の利用を できるだけ避けようとしています。特に Postfix virtual マッピングは 特権を持たないデーモンによりおこなわれるため、virtual マップに 見られるコマンドを実行したり指定されたファイルに配送する安全な 方法がありません。
回答: あるドメインを一つのメールボックスに配送するのはうんざりする 行為であることにみんな同意すると私は願いたい。SMTP や UUCP を 使ったメールの転送がよりよい選択肢です。不幸にも、SMTP や UUCP は 極めて多い Windows ユーザにとって代替として使えるものではありません。
元のバーチャル受信者情報を Delivered-To: ヘッダに展開することが 可能です。コツは伝統的なインデックスされたファイルの代わりに 正規表現を使ったバーチャルマップを使うことです。
次の例は joe+username@your.domain を含んだ Delivered-To: メッセージヘッダをつけて username@virtual.domain へ配送します。 Postfix はすでにエンベロープ送信者アドレスを Return-Path: ヘッダに つけています。Delivered-To: と Return-Path: ヘッダの中の情報は メールボックス内ドメインの信頼できる実装には十分です。
/etc/postfix/main.cf: recipient_delimiter = + virtual_maps = ...non-regexp virtual maps... regexp:/etc/postfix/virtual_regexp /etc/postfix/virtual_regexp: /^virtual\.domain$/ whatever /^(.*\)@virtual\.domain$/ joe+$1
注意:
アドレスマスカレーディングはメールゲートウェイでのみ使うことを 意図しています。
/etc/postfix/main.cf: masquerade_domains = $mydomain
ゲートウェイは、アドレスマスカレードをしようとする前に全てのアドレスを FQDN 形式にするために、 append_dot_mydomain と append_at_myorigin をオンにすべきであることに注意して下さい。
場合によっては、あるユーザやホストをマスカレードの例外にしたいかも しれません。
/etc/postfix/main.cf: masquerade_exceptions = root
/etc/postfix/main.cf: masquerade_domains = somehost.my.domain otherhost.my.domain $mydomain
上の順番が重要であることに注意して下さい: somehost.my.domain のような例外は $mydomain の先に記述しなければいけません。
この方法で例外扱いしたい特定のホストのメールが始めに user@my.domain として生成されると、これを例外にすることが 難しいのはいうまでもありません。
現在、Postfix には他のプログラムに全てのメッセージを検査させるための フックはないので、メールが Postfix に入る前か Postfix から出る時、 例えばメールボックスへの配送時にスキャンしなければいけません。
例:
/etc/postfix/main.cf: mailbox_command = /some/program ...
この例は全てのローカルメールをメールボックスに配送するコマンドを 指定しています。例えば、サンプルの main.cf ファイルを参照 してください。/etc/aliases で実在する人に向けた root のエイリアスを指定しなければいけません。そうしないと、root に送られたメールは期待通りの動作をしません。
/etc/postfix/main.cf: mailbox_transport = foo
この例はローカルメールボックス配送を /etc/postfix/master.cf で設定された配送方法 foo に委託します。このルートに従うので あれば、パイプメーラのようなものを構築します(?)。master.cf の 例を参照して下さい。
/etc/postfix/transport: some.domain uucp:uucp-host .some.domain uucp:uucp-host
詳細は transport マニュアルページを 参照して下さい。
/etc/postfix/main.cf: transport_maps = hash:/etc/postfix/transport
システムが db ファイルの代わりに dbm ファイルを 使っているのであれば、hash の代わりに dbm を指定します。 Postfix がどのマップタイプをサポートしているかを知るには、 postconf -m コマンドを使います。
/etc/postfix/master.cf: uucp unix - n n - - pipe flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
これは uux コマンドを走らせ、next-hop ホスト名 (uucp-host) と受信者をコマンドを実行する前に置き換えます。uux コマンドは シェルの助けなしに実行されるため、シェルのメタ文字に関する問題は ありません。
/etc/postfix/main.cf: relay_domains = some.domain $mydestination ...
詳細は relay_domains 設定 パラメータの記述を参照して下さい。
変更を反映するには、postfix reload コマンドを実行します。
/etc/postfix/main.cf: relayhost = uucp-gateway default_transport = uucp
/etc/postfix/master.cf: uucp unix - n n - - pipe flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
これは uux コマンドを走らせ、next-hop ホスト名 (uucp-host) と受信者をコマンドを実行する前に置き換えます。uux コマンドは シェルの助けなしに実行されるため、シェルのメタ文字に関する問題は ありません。
変更を反映するには、postfix reload コマンドを実行します。
ここでは Postfix と HylaFax で <fax number>@fax.our.domain スキームを使っています。ここで使った設定:
/etc/postfix/master.cf: fax unix - n n - - pipe flags= user=fax argv=/usr/bin/faxmail -d -n ${user} /etc/postfix/transport: fax.your.domain fax:localhost /etc/postfix/main.cf: transport_maps = hash:/etc/postfix/transport fax_destination_recipient_limit = 1
fax_destination_recipient_limit エントリ (by Simon, Mr. Simix) は複数の送信先をコマンドラインで指定できない FAX ソフトウェアの 場合に必要です。他への影響はありません。
システムが db ファイルの代わりに dbm ファイルを 使っているのであれば、hash の代わりに dbm を指定します。 Postfix がどのマップタイプをサポートしているかを知るには、 postconf -m コマンドを使います。
注意: fax.your.domain を DNS で広めないように気をつけて下さい...
# cd /var/spool/postfix # find incoming active deferred -name ABCDEF -print | sed 1q | xargs rm
上のコマンドは最高1つのファイルしか消さないので安全です。 同じキューファイル名を持ってしまった新着メールを消してしまう可能性は ありません。
大量のメールを削除するのであれば、まず Postfix を止めるのが安全です。
# postfix stop # cd /var/spool/postfix # find incoming active deferred defer -type f -print | fgrep -xf /file/with/queue-ids | xargs rm # postfix start
キューファイルを削除している途中で届いた新しいメールを消してしまうかも しれないので、動いている Postfix システムで上記のコマンドを使っては いけません。
Postfix はキューファイル名をその inode 番号と日時のマイクロ秒部分から 名付けます。こうして、キューファイルに他の inode 番号に基づく名前が ついていると、わずかながらファイル名が別のキューファイルとぶつかる 可能性があります。
キューファイルをコピーする時にキューファイル名の衝突を避けるには、 かわりに maildrop ディレクトリに incoming、active および deferred キューファイルをリストアします。
2000年の後期の時点で、Postfix キューは全てハッシュ化 (例えば ファイル ABCDEF は A/B/ABCDEF に保管されます) されたため、 さらにサブディレクトリからファイルを移動する必要があります。
# postfix stop ... restore incoming/active/deferred queue files under the maildrop directory... # find incoming active deferred -type f -exec mv '{}' . ';' # rm -rf incoming active deferred # postfix startmaildrop ディレクトリ以下にリストアしたファイルと衝突するおそれが あるため、この作業中にはローカルで新しいメールを送信しないでください。
Postfix が起動されると、maildrop ディレクトリからキューファイルが 取り出されて、適切なキューファイル名が与えられます。
ld: Undefined symbol ___dn_expand ___res_init ___res_search *** Error code 1
回答: BIND バージョン 8 のインクルードファイルと違うバージョンの リゾルバライブラリが混在しています。
修正: 正しいインクルードファイルを使います。例:
make makefiles CCARGS="-I/usr/include".
Undefined first referenced symbol in file dbm_pagfno ../lib/libutil.a(dict_dbm.o) dbm_dirfno ../lib/libutil.a(dict_dbm.o)
回答: /usr/include/ndbm.h を使う代わりに、あなたは Postfix を互換性のないサードパーティファイル、典型的には /usr/local/include/ndbm.h を使ってビルドしています。
修正: サードパーティの ndbm.h インクルードファイルを取り除きます。
Postfix を db をサポートしない UNIX で db とともに ビルドするには、www.sleepycat.com にある Berkeley DB ソースコードを使うことができます。 Postfix を Sleepycat の Berkeley DB とともにコンパイルする方法の説明は Postfix 配布ソースコードにある DB_README ファイルを参照して下さい。
gcc を使わなければならないのであれば、 http://www.isc.org/ にある BIND のソースコードの inet_ntoa() ルーチンを使う回避が可能です。
Postfix はメッセージを受け取ったことを示すためにキューファイルに 実行ビットをセットします。キューファイルが実行ビットを持たない限り、 Postfix は「メールはまだ受信中」として無視します。
拡張セキュリティが有効になっていると、Compaq Tru64 UNIX は スーパーユーザ以外が実行ビットをキューファイルに立てようとするのを 認めないという機能を持ちます。不幸にも、Postfix はそのような 試みが失敗したことを知らされず、メールがブラックホールに消えたように 見えてしまいます。
Postfix は実行ビット以外のビットを使うように変更できますが、それは 同様に他のシステムで失敗するかも知れません。他の可能性はスーパーユーザ 以外でも実行ビットをファイルに立てることを許可し、Postfix キュー ファイルシステムを noexec オプションや同等なものをつけて マウントすることです。