Postfixで送信メールのログを取得する


経緯

送信メールのログを残したいという依頼を受けたので、試行錯誤した結果、Postfixで送信メールを中継することになった。

環境

  • OS:Ubuntu Server 14.04 LTS
  • postfix 2.11

インストール

以下のコマンドでインストールできる。
ただし、デフォルトでインストールされているexim4が削除されるので、問題ないことを確認すること。

sudo apt-get install postfix

インストール中にpostfixの設定を行うために、いくつか質問に答えなくてはいけない。
今回は以下のように答えた。
1. サテライトシステム(スマートホスト)
2. hostname.domainname
3. 中継先のSMTPサーバのFQDN:ポート番号

無事にインストールが終了したら、コマンドでメールを送信して、届くことを確認する。

echo 'Hello.' | sendmail -f [email protected] [email protected]

設定

デフォルトではローカルホストしか送信できない。/etc/postfix/main.cfを編集して、受信するネットワークのIPアドレスを設定する。

main.cf
#inet_interfaces = loopback-only
inet_interfaces = 1.2.3.4, 127.0.0.1

また、メールの送信を許可するネットワークアドレスを追加する。

main.cf
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.X.X/24 

設定後、デーモンを再起動する。

sudo service postfix restart

送信テスト

通常使用しているメーラにSMTPサーバを追加する。ポートは変更していないので、25番。認証は不要。

ログ設定

Postfixのドキュメントを調べてもログフォーマットのカスタマイズ設定ができないようなので、"Built-in Content Inspection"のデバッグ用アクション"INFO"を使用する。
ログに残したい内容に応じて、フィルターを指定する。
指定できるフィルターは以下の通り
* header_checks
* mime_header_checks
* nested_header_checks
* body_checks
* milter_header_checks
* smtp_header_checks
* smtp_mime_header_checks
* smtp_nested_header_checks
* smtp_body_checks

送信メールに関係するものはsmtpで始まるフィルターだけ。
今回は以下の2つを指定した。

main.cf
smtp_header_checks = regexp:/etc/postfix/smtp_header_checks
smtp_mime_header_checks = regexp:/etc/postfix/smtp_mime_header_checks

右辺の形式は、"テーブルの種類:テーブルファイル"となっている。
今回は、もっとも簡単なregexpにした。
処理速度を考慮すると別の形式がいいらしい。

以下は、それぞれのテーブルファイル。

smtp_header_checks
/^To:(.*)/    INFO    $1
smtp_mime_header_checks
/^Content-Type:(.*)/    INFO    $1

ファイルの内容は、各行に正規表現パターン(/正規表現/)と空白文字を挟んでアクション(INFO)、アクションへの引数となっている。
INFOアクションはパターンにマッチした文字列すべてをログに出力すると思ったが、実際には文字列長に制限があるらしい。
正規表現でマッチしたグループをアクション引数に渡すことで、ログに残したいデータを出力することにした。
指定できるアクションについてはheader_checks参照

また、マルチバイト文字はデコードされたままログに残るので、ログの加工などはFluentdなどで行う予定。