postfix を Solaris SMF に対応
結局 postfix はソースからビルドすることにしたのだけど、最後まで迷った要因が、パッケージ版の方は Solaris SMF に対応している(筈)という点。
由緒正しい SVR4 init 方式の設定でも良いのだけれど、やっぱり他のデーモン類の設定と歩調を合わせておきたいじゃない?
ということで、postfix を Solaris SMF に対応させてみることに。
SUN(現 Oracle) の BigAdmin 日本語版で公開されている設定サンプルおよび手順によると:
の2つを用意した上で:
- svccfg(1M) を使って、サービスマニフェスト記述の検証および登録
- svcadm(1M) を使って、サービスの起動
- svcs(1) を使って、稼働状況の確認
という手順を踏むことになるらしい。
サービスマニフェストの記述に関しては、「Solaris 10 のサービス管理方法」で postfix 向けの記述が公開されているので、"svccfg export svc:/netwokr/smtp" で出力される sendmail 用設定と比較してみる。
ちなみに、sendmail を pkg uninstal したのに SMF の sendmail 向け設定が残っているのは、pkg uninstall 前に svcadm disable するのを忘れていたためなのか否かは定かではないので、出来ることなら pkg uninstall 前に /var/svc/manifest/network 配下から sendmail 用マニフェストファイルを回収しておくのがお勧め。
さて、sendmail 向けと postfix 向けのマニフェストを比較すると:
- マニフェストのバージョン番号
- インスタンス名("sendmail" <=> "postfix")
- 設定ファイルへの依存記述("sendmail.cf" <=> "main.cf")
- exec_method 指定(methods スクリプトの起動指定)
- "" 指定(情報表示用)
といった、わかり易い部分以外に、いくつかプロパティ設定周りに違いが見られる。
sendmail のマニフェストでは、"firewall_config" および "firewall_context" プロパティが設定されている。
他にこれらを設定しているマニフェストが無いか、/var/svc/manifest/network 配下を grep してみることに。
firewall_config に関しては、ネットワークサービスのサーバ向けマニフェストではおおむね同じような設定が記述されているので、縁起物っぽいから入れておくのが良さそう。
firewall_context に関しては ssh.xml などに記述が見られる。
<property_group name='firewall_context' type='com.sun,fw_definition'> <propval name='name' type='astring' value='ssh' /> <propval name='ipf_method' type='astring' value='/lib/svc/method/sshd ipfilter' /> </property_group>
気になるのは ipf_method に "/lib/svc/method/sshd ipfilter" を設定しているところ。これって methods スクリプトの起動設定だよね?
/lib/svc/method/sshd スクリプトを確認してみたところ、ipfilter 指定で起動した場合の挙動は、ipfilter の設定に SSH 接続用の穴を開けているように見える。
特に待ち受けポートをホスト外に向けて解放する必要が無いことから、firewall_context に関しては無しの方向でも大丈夫じゃないかな?
sendmail 向けマニフェストでは name='config' で type='application' なプロパティも定義されているけど、ぱっと見た限りでは、特に必要そうには見えないから、当面これも無しの方向で。
以上でサービスマニフェストの準備は完了したので、svccfg で検証してみる。
$ svccfg validate ./smtp-postfix.xml $
特に何も表示されないので少々不安だが、試しに XML 的に駄目なファイルを読み込ませると、ちゃんとエラー表示をしてくれるし、"echo $?" で戻り値を確認しても 0 だったので、大丈夫そうな感じ。
続いては methods スクリプトの準備。
理論上は、SMF 側で設定ファイルの有無等の依存関係を検証してくれる筈なので、以下の様な簡素な内容で良い筈。
#!/sbin/sh POSTFIX=/usr/sbin/postfix case $1 in 'start') ${POSTFIX} start ;; 'stop') ${POSTFIX} stop ;; 'refresh') ${POSTFIX} reload ;; *) echo "Usage: $0 { start | stop | refresh }" exit 1 ;; esac exit $?
methods スクリプトの起動引数は、マニフェスト記述側で如何様にも変更できるから、元々 start/stop/reload 指定による稼動状態変更が可能な postfix の場合、別途 methods スクリプトなんて用意しなくても良くねぇ?という気がしないでもない。
が、まぁ、郷に入りては郷に従え、ということで、ここはおとなしく methods スクリプトを用意することに。
以上で準備が完了したので:
$ svccfg import ./smtp-postfix.xml $ svcs svc:/network/smtp* STATE STIME FMRI disabled Nov_02 svc:/network/smtp:sendmail disabled 20:26:24 svc:/network/smtp:postfix $ svcadm enable svc:/network/stmp:postfix $ svcs svc:/network/smtp* STATE STIME FMRI disabled Nov_02 svc:/network/smtp:sendmail online 20:28:31 svc:/network/smtp:postfix $
一応 netstat -an で smtp の 25 番ポートが listen されているかも確認。サービス起動前後で listen 状況が変化していることが確認できた。
念のためと思って /var/adm/messages を見ると、なにやら ipfilter からエラー通知が:
smf_get_state failed for svc:/network/smtp:postfix: entity not found is_correct_event failed for svc:/network/smtp:postfix. Service may have incorrect IPfilter configuration
smf_get_state と is_correct_event が失敗する、と言っている模様なのだが、先の firewall_config 設定だけでは駄目だったのか?
とりあえず動いているっぽいけど、あと一押し必要そうだなぁ、と思いつつ、試行錯誤すること暫し。うーん、なんかよくわからん。
どうも、マニフェスト定義を svccfg import した時点で出力されている模様。で、エラー要因となっている smf_get_state なるものの正体を調べてみると、どうやらサービスインスタンスの状態を取得する SMF ライブラリの関数らしい。
ここで言う「サービスインスタンスの状態」というのは、svcs コマンドで出力される online とか disable とか maintenance とかいう奴。
あれ?サービスインスタンスの状態なんて、明らかにう動的なものだから、マニフェスト記述でどうなるものでもないよな?ひょっとして、サービス設定の変更通知を受けて、サービス状態管理領域が出来るよりも、状態取得処理が先に走っているだけ?
試しに再起動してみたところ、postfix はちゃんと起動されているし、ipfilter からも特に設定不正のエラー通知も無い。
うーん、イベント配信の実装がアレってこと? > SMF