IIS 7.5 上の PHP からイベントログにメッセージを出力するときに注意すること
IIS 7.5 上の PHP でイベントログにメッセージを出力したい時の問題点...
PHP ではエラーログの出力先を php.ini で設定可能になっています。error_log に syslog を指定することによって、 syslog 関数の出力をファイルではなく、アプリケーションイベントログに出力することができることになってます。
error_log = syslog
php.ini にもコメントで "Log errors to syslog (Event log on NT, not valid in Windows 95)" などと書いてあります。
さて、こうしておくと、他の設定、例えば log_errors=On とか error_reporting = E_ALL などにどの情報が出力されるか影響されることはさておき、 基本的にイベントログにログが出力されるハズなのです。
が、実際に IIS 7.5 上で試してみてもログは記録されません。
これが今回の問題点です。これをどうやって解決したか書き留めておきます。
ちなみに、 IIS 7.5 に限らず 6 や 7 でも同じなのかもしれませんが、 試していないので同様の現象が出た場合にはこの資料の内容を試してみたらいいかもしれません。
解決方法。イベントログの書き込みの権限を設定する
ひとことでいうと、PHP からイベントログの書き込み権限を設定することによって解決しました。
Windows イベントコマンドラインユーティリティの wevtutil コマンド でアプリケーションイベントログのアクセス権の設定を確認します。
すると、既定の設定で次のような出力になるはずです。
> wevtutil gl application name: application enabled: true type: Admin owningPublisher: isolation: Application channelAccess: O:BAG:SYD:(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU) (A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)(A;;0x3;;;S-1-5-33)(A;;0x1;;;S-1-5-32-573) logging: logFileName: %SystemRoot%\System32\Winevt\Logs\application.evtx retention: false autoBackup: false maxSize: 20971520 publishing: fileMax: 1
ポイントは channelAccess のラインです。ここにアクセス権限とその対象が列挙されています。
尚、SID とそのアカウント名のマッピングについては、SID ルックアップツール などを使ってもらえば確認できます。
SY | NT AUTHORITY\SYSTEM |
BA | BUILTIN\Administrators |
SO | Server Operators |
IU | NT AUTHORITY\INTERACTIVE |
SU | NT AUTHORITY\SERVICE |
S-1-5-3 | NT AUTHORITY\BATCH |
S-1-5-33 | NT AUTHORITY\WRITE RESTRICTED |
S-1-5-32-573 | BUILTIN\Event Log Readers |
結局のところ、この中に PHP の実行ユーザーが含まれていないために、ログに書き込むことができないことになります。
そこで、実行ユーザーとして考えられるものとして IUSR および Network Service が挙げられますので、 これらに対して書き込み権限を設定しましょう。(ユーザーは環境に依存しますので、いろいろと設定している場合はそれら全て設定する必要が出てくるでしょう)
さて、IUSR、Network Service の SID はそれぞれ S-1-5-17、S-1-5-20 ですから (Well knonw SID です)、 上記の channelAccess のエントリとして次を追加します。
(A;;0x3;;;S-1-5-17)(A;;0x3;;;S-1-5-20)
結局、アプリケーションイベントログの権限を更新するために実行する wevtutil コマンドは次のようになります。 途中省略してますが、要は元の出力を元に後ろに (A;;0x3;;;S-1-5-17)(A;;0x3;;;S-1-5-20) を追加してます。 また、折り返しませんので、注意してください。
wevtutil sl application /ca:O:BAG:SYD:(A;;0xf... (省略) ...-573)(A;;0x3;;;S-1-5-17)(A;;0x3;;;S-1-5-20)
これで、イベントログに PHP のログが記録されるようになるはずです。
しかし、PHP がクラッシュするようになった
上記の設定をすることによって、session_start を必要とする箇所で php-cgi.exe がクラッシュするようになりました。 クラッシュ直前のログを見ると、どうやら一時ディレクトリへのアクセスが拒否されたことによるもののようです。
上記のログ出力の設定変更とどのような関連があるのかわかりませんが、私はこのタイミングでクラッシュが見られましたので、 追記しておきます。
ちなみに、この件も一時ディレクトリ (C:\Windows\Temp 等) への書き込み権限を設定することによって解決できました。