2022年8月、ホームページを全面リニューアルしました! 情報を分かりやすくお伝えできるサイト作りを目指してまいります。

Postfixの構造と導入の勘所!

Postfixは、使いやすいメールサーバ(MTA)として定評がある。さらに、sendmailのようにセキュリティホールがやたら多くないのも嬉しい限りである。そんでもって、qmailもセキュアーで良いけれど、使い勝手やプラグインモジュールの種類の豊富さなどからみてもPostfixが俺はお気に入りだ。
話は変わるが、鯖構築の初心者は、キーワード検索をしてPostfixネタを見つけたらそのサイトで設定ファイル等を真似して自分の鯖を構築するのが定番だと思う。しかし、意味を納得して設定するのと意味が解らず設定するのでは、以降、自鯖への管理レベルの違いが大きく現れる。つまり、セキュリティに強い自鯖を作ることができるのだ。そんな意味からも、今回は Postfixの導入方法 と言うより、Postfixの構造とか設定の勘所みたいなことについて話してみたい。

ここで説明に使う環境)
マシン:Dell PowerEdge SC-430
OS:CentOS4.3
MTA:postfix
[root@ns ~]# postconf | grep mail_version
mail_version = 2.2.10



1.Postfixの構造
Postfixは、一つのモジュールで動いているのではないのを知ってる?複数のモジュールが配送に関わっている。その関わりのあるモジュールの内訳を構造図と実際のLinuxのサービスのプロセスを見ながら解説する。

Postfix構造図(あくまでも大まかな構造 図1)

図1

1.1 各モジュールの役割(コアメール処理モジュール)
1)master:Postfixの各モジュールのプロセス制御をする、設定は master.cf で行う

2)qmgr:キューマネージャ(メールキューの管理を行う)、incomingキューのメッセージを処理して、そのメッセージの宛先及び配信する方法を決めて、メッセージを配信する処理を作り出すところ

3)pickup:ローカルメールの収集、maildropキューへのメッセージをポーリングして、受け取ったメッセージをcleanupへ投げて処理をスタート

4)smtpd:SMTPサーバ本体、外部ホストからのメールを受信

5)proxymap:プロセスに読み込み専用のテーブル検索サービスを提供する

6)anvil:セッションのカウント及びリクエストレートの制御(統計情報などはここで発行する)

7)trivial-rewrite:cleanupやqmgrからメッセージを受け取り以下の処理を行ってから戻す
①アドレスを標準形式に書き換える
②一つのアドレスを3組 (transport, nexthop, recipient) に解決する
■ transport
使用する配送エージェント、これは master.cf ファイルのエントリの最初のフィールド
■ nexthop
送り先のホストおよびオプションで配送方法の情報
■ recipient
nexthop に渡されるエンベロープ受信者アドレス
③アドレス検証を目的としてアドレスを解決する

8)cleanup:着信メールのヘッダを処理して、次のincomingキューへ投げる

9)smtp:SMTPを使ったリモート配送、外部ホストへメールを配送

10)sendmail:sendmail用クーロン、Unixではmailモジュールとしてはあまりにも有名であるため、sendmailと連携してメールを送信する必要があった、そのためのsendmailI/F

11)postdrop:maildropキューへ直接メッセージを入れられないため、sendmailからのメッセージは一端postdropへ収められる

12)local:ローカルユーザ宛のメッセージを配信する

13)incoming:絶えず最新の電子メールメッセージが保管されるメールバッファ

1.2 受・配信のプロセス
1)外部からメール受信→ローカルユーザメールボックスへ配信
以下のプロセスで処理される(図2)。

図2

2)外部ホストからメール配送依頼→外部ユーザ宛へ配信(メールリレー)
以下のプロセスで処理される(図3)。

図3

3)ローカルホスト→ローカルユーザメールボックス
以下のプロセスで処理される(図4)。

図4

1.3 各モジュールのプロセス状態
以下、フェーズ別にモジュールの稼働状態を示している。

[ニュートラルフェーズ]
root 2515 1 0 Mar06 ? 00:00:01 /usr/libexec/postfix/master
postfix 18971 2515 0 Mar15 ? 00:00:00 qmgr -l -t fifo -u
postfix 28335 2515 0 12:55 ? 00:00:00 pickup -l -t fifo -u

送信や受信が無い状態では、以下の3つのモジュールが常駐している。

[メール受信フェーズ]
root 2515 1 0 Mar06 ? 00:00:01 /usr/libexec/postfix/master
postfix 28410 2515 0 13:34 ? 00:00:00 smtpd -n smtp -t inet -u
postfix 28411 2515 0 13:34 ? 00:00:00 proxymap -t unix -u
postfix 28412 2515 0 13:34 ? 00:00:00 anvil -l -t unix -u
postfix 28413 2515 0 13:34 ? 00:00:00 trivial-rewrite -n rewrite –

smtpdが動いて受信動作に入ってる。

[メール送信フェーズ]
root 2515 1 0 Mar06 ? 00:00:01 /usr/libexec/postfix/master
postfix 18971 2515 0 Mar15 ? 00:00:00 qmgr -l -t fifo -u
postfix 28335 2515 0 12:55 ? 00:00:00 pickup -l -t fifo -u
postfix 28522 2515 0 14:24 ? 00:00:00 smtpd -n smtp -t inet -u
postfix 28523 2515 0 14:24 ? 00:00:00 proxymap -t unix -u
postfix 28524 2515 0 14:24 ? 00:00:00 anvil -l -t unix -u
postfix 28525 2515 0 14:24 ? 00:00:00 trivial-rewrite -n rewrite –
postfix 28526 2515 0 14:24 ? 00:00:00 cleanup -z -t unix -u
postfix 28527 2515 0 14:24 ? 00:00:00 smtp -n smtp-amavis -t unix
postfix 28530 2515 0 14:24 ? 00:00:00 smtpd -n 127.0.0.1:10025 -t
postfix 28531 2515 0 14:24 ? 00:00:00 smtp -t unix -u

smtpが動いてリモート送信状態に入ってる。


2.メッセージキュー
メッセージキューはいわばlogで有る。これによってPostfixの健康状態が解ると言っても過言ではない。メッセージキューによって、相手先にまともに配送されたか、もしくは何らかの理由によって配送出来なかったのかは、このメッセージキューが知らせてくれる。

1)メッセージキューの所在
Postfixのメッセージキューの在処は、デフォルトで、/var/spool/postfixに有る。以下参照。
mity@ns:~$ cd /var/spool/postfix/
mity@ns:/var/spool/postfix$ ls -al

total 80
drwxr-xr-x 19 root root 4096 May 24 2006 .
drwxr-xr-x 6 root root 4096 Sep 24 21:12 ..
drwx—— 18 postfix root 4096 Nov 12 2005 active
drwx—— 5 postfix root 4096 Jan 3 12:50 bounce
drwx—— 2 postfix root 4096 Oct 19 2005 corrupt
drwx—— 18 postfix root 4096 May 26 2006 defer
drwx—— 18 postfix root 4096 May 26 2006 deferred
drwxr-xr-x 2 root root 4096 Mar 6 07:37 etc
drwx—— 3 postfix root 4096 Nov 12 2005 flush
drwx—— 2 postfix root 4096 Oct 19 2005 hold
drwx—— 18 postfix root 4096 Mar 23 06:26 incoming
drwxr-xr-x 2 root root 4096 Mar 6 07:37 lib
drwx-wx–T 2 postfix postdrop 4096 Mar 23 06:25 maildrop
drwxr-xr-x 2 postfix root 4096 May 26 2006 pid
drwx—— 2 postfix root 4096 Mar 7 17:20 private
-rw——- 1 root root 1024 Mar 23 13:47 prng_exch
drwx–s— 2 postfix postdrop 4096 Mar 6 07:37 public
drwx—— 2 postfix root 4096 Oct 19 2005 saved
drwx—— 2 postfix root 4096 Oct 19 2005 trace
drwxr-xr-x 3 root root 4096 Oct 19 2005 usr

2)メッセージキューの意味
① active
 : qmgrによって現在処理中のメッセージを保存
② bounce
:配信できなかったメッセージログを保存
③ corrupt
:postfixの形式に則ってないメッセージの保存
④ defer
:一時的に配信できなかったメッセージログを保存、ただし、postfixはリトライを試みる
⑤ deferrd:一時的に配信できなかったメッセージを保存、ただし、postfixはリトライを試みる
⑥ incoming
:リモートで受信した最新のメッセージを保存
⑦ maildrop
:ローカルユーザから受信した最新のメッセージの保存

3)logに出るメッセージキューステータス
Mar 18 09:00:46 ns postfix/local[24409]: 662465BE0B: to=<hoge@xxxxxxxx.net>, relay=local, delay=1, status=sent (delivered to command: /usr/bin/procmail -m /etc/postfix/procmailrc)

上記は、mailログのlogメッセージ一部だ。ここの 「 status= 」 でメールの配送状態を表す。ちなみに、 status=sent と有るのは旨く送信が終わった事を示す。その他には、 status=bounce (配送できなかった事を表す)とか status=deferred (一時的に配送できなかったがリトライする)とかがlogに現れる。


3.Postfixの設定の勘所
誰でも好んで間違った設定や穴がある設定を行う人など居ないはず。だから簡単な設定で、さらに不正中継が不可能な設定を伝授してみたい。以下の main.cf は本当のスタンダードな設定だ。Postfixをとにかくめんどくさくなくセキュリティ(不正中継)をも気にせずに済む設定を伝授してくれ!と言うなら以下の設定で完璧だろう。
基本的に不正中継の防御はパラメータ1行(mynetworks)の設定だけでOKだ。さらに、詳しいことを知りたければ、 ここ とか ここ を参照して欲しい。

queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
mail_owner = postfix
inet_interfaces = all

# mynetworks_style = host
# mynetworks_style = subnet
# mynetworks_style = class
mynetworks = 127.0.0.0/8 192.168.10.0/24

上記は、mynetworksパラメータを設定しているところだ。mnetworksパラメータは、信頼されたネットワークアドレスを設定して、中継を許可するパラメータだ。
mynetworksパラメータが設定されていない場合は、mynetworks_styleパラメータが優先される。コメントしてあるmynetworks_styleの上記の意味はhostとsubnetは解ると思う。classは、classA、classB、classCのネットワークアドレスになるので広範囲に渡って中継が許可されてしまうので危険な設定値だ。一番安全なのは mynetworks = 127.0.0.0/8 を設定して127.0.0.0/8インターフェースのネットワークアドレスを信頼されるアドレスとして設定して中継を許可する方法を推奨する。また、それに加えてclassCのアドレスのホストグループを許可したい場合は、スペースをあけて以降に192.168.10.0/24とかを指定すれば良い。しかし、アドレス偽造等を考えた場合は、127.0.0.0/8のみを指定して「smtpd_recipient_restrictions」パラメータ等でSMTP-AUTH等の送信認証システムを指定した方がよりベストだ。

debug_peer_level = 2
debugger_command =
PATH=/usr/bin:/usr/X11R6/bin
xxgdb $daemon_directory/$process_name $process_id & sleep 5
myhostname = mail.xxxxxxxx.co.jp
myorigin = $myhostname
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
program_directory = /usr/lib/postfix
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq

以上

コメント