Postfix デバッグ Howto


この文書の目的

このドキュメントには物事が思ったようにいかないときに、Postfix メール システムの部品をデバッグする方法が書かれています。その方法は Postfix に 大量の詳細なログを書かせることから、コールトレーサやデバッガの管理下で デーモンプロセスを動かすことまで様々です。

この文書では、Postfix main.cf および master.cf 設定ファイルは /etc/postfix にあると仮定します。マシン上でのこのディレクトリの実際の 場所を見つけるには、"postconf config_directory" コマンドが使えます。

デバッグのテクニックを中に入り込む順に列挙すると次の通りです:

トラブルの明らかな兆候を探す

Postfix は全ての配送の失敗や成功をログファイルに記録します。ファイルは 通常 /var/log/maillog または /var/log/mail と呼ばれます; 正確なパス名は /etc/syslog.conf ファイルで定義されます。

Postfix がメールを受け取らなかったり配送しなかった場合、最初の仕事は Postfix が正しく働かないようにしたエラーを探すことです:

% egrep '(warning|error|fatal|panic):' /some/log/file | more

注意: 最も重要なメッセージは出力の「最初」の近くです。後に出てくるエラー メッセージはあまり役に立ちません。

それぞれの問題の性質を以下に示します:

内部から Postfix をデバッグする

Postfix バージョン 2.1 以降では、Postfix にデバッグ用メール配送レポートを 生成させることができます。これらのレポートはアドレス書き換えやエイリアス展開、 転送後の送信者/受信者アドレスを示すだけではなく、メールボックスへの配送や 非 Postfix コマンドへの配送、リモート SMTP サーバの応答なども示します。

Postfix はデバッグ用に2種類のメール配送レポートを生成することができます:

これらのレポートには Postfix 配送エージェントが生成した情報が 含まれます。これらはデーモンプロセスとして動き、ユーザとは直接 接触を持たないため、結果はテストメッセージの送信者にメールとして 送られます。これらのレポートの書式は通常の非配送通知と事実上同じ 書式です。

メール配送状態レポートの詳細な例は、 ADDRESS_REWRITING_README ドキュメントの最後にある デバッグセクション を参照してください。

master.cf で chroot 操作を無効にしてみる

よくある間違いは、chroot 環境を構築するのに必要な全てのステップを 踏まずに master.cf ファイルで chroot 動作を有効にしてしまうことです。 そうすると、さまざまなファイルが見つからないために Postfix デーモン プロセスを失敗させてしまいます。

以下の例は chroot を無効に設定した SMTP サーバを示しています:

/etc/postfix/master.cf:
    # =============================================================
    # service type  private unpriv  chroot  wakeup  maxproc command
    #               (yes)   (yes)   (yes)   (never) (100)
    # =============================================================
    smtp      inet  n       -       n       -       -       smtpd

master.cf を調べて、chroot 動作が無効になっていないプロセスを探します。 有効になっているものがあったら、master.cf ファイルのコピーを保存し、問題の エントリを修正します。"postfix reload" コマンドを実行した後で問題が なくなっていることを確認します。

chroot 動作を無効にすることで問題がなくなったらおめでとう。ほとんどの サイトではこの方法で Postfix を動かし続けるのが適しています。chroot して 動かすのが好きなら、 Postfix での chroot 動作の準備方法に関する情報を Postfix BASIC_CONFIGURATION_README ファイルで参照してください。

特定の SMTP 接続に対して冗長なログを取る

/etc/postfix/main.cf で、 debug_peer_list パラメータにリモートのサイト名または アドレスをリストアップします。例えば、ループバックインターフェースから、 もしくはループバックインターフェースへの接続に対して大量の情報をソフトウェアが syslog デーモンでログを記録するようにするためには、次のようにします:

/etc/postfix/main.cf:
    debug_peer_list = 127.0.0.1

一つ以上のホストやドメイン、アドレス、net/masks を指定できます。変更を すぐに有効にするためには、"postfix reload" コマンドを実行します。

ネットワークスニファで SMTP セッションを記録する

この例では tcpdumpを使います。会話を記録するために、 "-s" オプションで十分に大きなバッファを指定する必要があります。そうしないと、 パケットペイロードの一部もしくは全てを失うことになります。

# tcpdump -w /file/name -s 2000 host example.com and port 25

これをしばらく動かし、終わったら Ctrl-C で止めます。データを見るには バイナリビューア、ethereal を使うか、 ftp://ftp.porcupine.org/pub/debugging/ で得られる tcpdumpx ユーティリティを使います。

Postfix デーモンプログラムをより饒舌にする

/etc/postfix/master.cf の選択したデーモンの定義に一つ以上の "-v" オプションをつけて "postfix reload" とタイプします。 これは大量の活動を syslog デーモンでログに記録します。例:

/etc/postfix/master.cf:
    smtp      inet  n       -       n       -       -       smtpd -v

これは Postfix SMTP サーバをより饒舌にします。アドレス書き換えでの問題を 診断するには、"-v" オプションを cleanup(8)trivial-rewrite(8)デーモンに、メール 配送の問題を診断するには、"-v" オプションを qmgr(8) または oqmgr(8) キューマネージャ、もしくは lmtp(8)local(8)pipe(8)smtp(8)virtual(8) 配送エージェントに指定します。

Postfix デーモンプロセスをマニュアルでトレースする

多くのシステムでは、システムコールトレーサを使って動いているプロセスを 調べることができます。例えば:

# trace -p process-id (SunOS 4)
# strace -p process-id (Linux and many others)
# truss -p process-id (Solaris, FreeBSD)
# ktrace -p process-id (generic 4.4BSD)

より参考になるのはシステムライブラリコールのトレースです。例:

# ltrace -p process-id (Linux, FreeBSD や BSD/OS にもポーティングされています)
# sotruss -p process-id (Solaris)

詳細はシステムのドキュメントを参照してください。

動いているプロセスのトレースはプロセスがしようとしていることに関する 脆弱な情報を与えます。後のセクションに記述されているように、これは インタラクティブデバッガプログラムを動かさずに得られるのと同じくらいの 量の情報です。

Postfix デーモンプロセスを自動的にトレースする

Postfix はデーモンプロセスの起動時にいつでもコールトレーサを取り付ける ことができます。コールトレーサにはいくつかの種類があります。

  1. tracetrussstracektrace のような コールトレーサ。これらはプロセスとカーネルの間の通信を表示します。

  2. sotrussltrace のようなライブラリコールトレーサ。 これらはライブラリルーチンのコールを表示し、プロセスの中で起ころうとして いることをよりわかりやすく示します。

-D オプションを /etc/postfix/master.cf の疑わしいコマンドに 加えます。例えば:

/etc/postfix/master.cf:
    smtp      inet  n       -       n       -       -       smtpd -D

選択したコールトレーサを呼び出すために debugger_command 定義を編集 します。例えば:

/etc/postfix/main.cf:
    debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin;
         (truss -p $process_id 2>&1 | logger -p mail.info) & sleep 5

"postfix reload" とタイプして、ログファイルを監視します。

インタラクティブ xxgdb デバッガでデーモンプログラムを 走らせる

Postfix マシンに X Windows がインストールされているなら、xxgdb のようなインタラクティブデバッガが便利です。

xxgdb を呼び出すために /etc/postfix/main.cf で debugger_command の定義を 編集します:

/etc/postfix/main.cf:
    debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         xxgdb $daemon_directory/$process_name $process_id & sleep 5

gdb がコマンドサーチパスにあることを確認し、X アクセスコントロールが 働くように XAUTHORITY をエクスポートしてください。例えば

% setenv XAUTHORITY ~/.Xauthority (csh 文法)
$ export XAUTHORITY=$HOME/.Xauthority (sh 文法)

-D オプションを /etc/postfix/master.cf の疑わしいデーモンに加えます。 例えば:

/etc/postfix/master.cf:
    smtp      inet  n       -       n       -       -       smtpd -D

Postfix システムを止めて、それから起動してください。これは Postfix が 正しい XAUTHORITY および DISPLAY 設定で動くのに必要です。

疑わしいデーモンプロセスが起動されるたびに、デバッガウィンドウがポップ アップし、起こっていることを詳細に監視できます。

非インタラクティブデバッガの下でデーモンプログラムを 走らせる

Postfix マシンに X Windows をインストールしていなかったり、インタラクティブ デバッガに慣れていないのであれば、gdb デバッガを非インタラクティブ モードで動かしてみて、プロセスがクラッシュしたときにスタックトレースを表示 させます。

gdb デバッガを呼び出すためには /etc/postfix/main.cf で debugger_command 定義を 編集します:

/etc/postfix/main.cf:
    debugger_command =
        PATH=/bin:/usr/bin:/usr/local/bin; export PATH; (echo cont; echo
        where; sleep 8640000) | gdb $daemon_directory/$process_name
        $process_id 2>&1
        >$config_directory/$process_name.$process_id.log & sleep 5

-D オプションを /etc/postfix/master.cf の疑わしいデーモンに加えます。 例えば:

/etc/postfix/master.cf:
    smtp      inet  n       -       n       -       -       smtpd -D

設定の変更を有効にするために "postfix reload" をタイプして ください。

疑わしいデーモンプロセスが起動されるたびに、デーモン名とプロセス ID から 名前が付けられた出力ファイルが作られます (例えば smtpd.12345.log)。プロセスが クラッシュすると、スタックトレース (と"where" コマンドからの出力) が ログファイルに書かれます。

不合理な振る舞い

Postfix によって表される振る舞いがソースコードに合わない場合が時々 あります。なぜ作者によって与えられた指示からプログラムが逸れるのでしょうか? 2つの可能性があります。

どちらの場合も、実行されたプログラムは想定された動作をするプログラムでは ないため、何でも起こり得ます。

3つ目の可能性もあります:

ハードウェア関連の不具合は、電源を入れ直したりシステムを再起動すると、 たいていの場合全く同じようには再現しません。悪いハードウェアについて Postfix が できることはほとんどありません。最低限メモリエラーを検出できるハードウェアを 使うようにしてください。そうでなければ、Postfix はビットエラーに当たるのを ただ待っているだけです。重要なシステムは本物のハードウェアで構成すべきです。

コンパイラがエラーを作ると、プログラムが実行されるたびに問題が再現します。 コンパイラのエラーはコード最適化で最もよく起こります。電源を入れ直したり システムを再起動しても問題が再現する場合、最適化を無効にして Postfix を 再構築して最適化で違いがでていないか確認する価値があります。

最適化を無効にして Postfix をコンパイルするには:

% make tidy
% make makefiles OPT=

これはコンパイラに最適化を要求しない Makefile のセットを生成します。

一旦 makefile がセットアップされたら、ソフトウェアを構築します:

% make
% su
Password:
# make install

問題がなくなれば、そろそろベンダに助けを求める時間です。

postfix-users@postfix.org に問題を報告する

postfix-users@postfix.org に参加している人たちは、特に「あなたが」 十分な情報を出せばとても助けになります。これらのボランティアの人たちは 喜んで助けてくれますが、彼らの時間は限られていることを忘れないでください。

問題を報告する際には、以下の情報を含めるようにしてください。