phpのinstall - SAPI cli, cgi, apache DSO module メモ

今まで専用サーバだからほとんどapache moduleとして入れていたけど、共有サーバだからcgi版で入れようということになったので。phpのことちょっと調べたメモ。

phpのSAPI (Server Application Programming Interface)

defaultではclicgi版 両方がinstallされる。

cli版とcgi版の大きな違いは

  • cgi版は自動的にHTTPヘッダが出力される
    • "Content-type: text/html\n\n"
  • cli版はいくつかのphp.iniの設定が無効化される
    • cli(シェル)環境だと意味がないもの
    • html_errorsとか

cgi版を使用する際は--enable-force-cgi-redirectをつけてコンパイルすることが推奨されている。

*1

apahce DSO moduleのinstall

configure でapxsの場所を指定。

$ ./configure --with-apxs2=/usr/local/apache2/bin/apxs

このオプションを指定すると、自動的に--disable-cgiされてcgi版のバイナリはinstallされなくなる。何らかの理由でapache moduleとcgi版の両方が必要な場合はprefixをわけて別々にinstallする?

cgi版のphpを使って、モジュール用phpをソース変更なし動作させる設定

セキュリティ上の観点から、直接php-cgiバイナリがURLから呼ばれることを禁止する設定。

$ ./configure --enable-force-cgi-redirect
shebangについて

モジュール版の場合、phpinfoを出すphp

<?php phpinfo(); ?>

だけで動く。それに対して、通常cgi版を使った場合はshebangを追加して、ファイルに実行権限を付加する必要がある。

#!/usr/local/php/bin/php-cgi
<?php phpinfo(); ?>

ただ、これだと、他の環境からソースを持ってきた場合などや、配布されているプログラムなどを利用する場合に非常に面倒。なのでshebangを追加しないでも良い方法を探したら2つあった。。

apacheのmod_action使う

まずバイナリを適当なディレクトリにコピー。

# cp /usr/local/php/bin/php-cgi /path/to/secret/cgi-bin/

apacheの設定追加

ScriptAlias /cgi-bin/    /path/to/secret/cgi-bin/
Action     myphp5-script /cgi-bin/php-cgi
AddHandler myphp5-script .php
<Directory /path/to/secret/cgi-bin/>
  ## 適当にアクセス権限とか設定
</Directory>

AddHandlerとActionの1つ目の引数は、そろっていればなんでもいい。けど普通にmod_phpで設定するようなphp-scriptとかだと混同しそうなので適当に変えた。これだとshebangの追加やパーミッションの付加もいらない。

  • 共有サーバでバーチャルホスト設定してる場合

他のユーザにホストする場合を考えると、上の設定だと/cgi-bin/というURLを勝手に使っちゃうことになる。どうしよう。あまり使われなさそうなURLでAliasする?

ScriptAlias /.secret/cgi-bin/ /path/to/secret/cgi-bin/
Action     myphp5-script /.secret/cgi-bin/php-cgi
AddHandler myphp5-script .php

おっと、これだとpsで見たときに/path/to/secret/cgi-bin/php-cgiが表示されるのか。実行されているファイルまでは確認できないのな。あと、suexecしてたらそのユーザで実行してるのが確認できるけど、してなかったらapache起動ユーザにしか見えない。

mod_suphp

phpをsuexecさせるモジュール。mod_suphpの場合も、psで見るとphp-cgiしか見えなかった。が、suexecもsuphpもerror logに実行されたファイルが出るんだけど、suphpのこのログでどのファイルが実行されたかを特定できるようだ。

  • suexecのlog
uid: (1000/1000) gid: (1000/1000) cmd: php-cgi
  • suphpのlog
Executing "/path/to/exec/php" as UID 1000, GID 1000
--enable-force-cgi-redirectが必要な理由

PHP 実行バイナリを Web サーバーの cgi-bin ディレクトリにインストールします。 CERT 勧告 CA-96.11は、いかなるイ ンタプリタを cgi-bin に置くことにも反対しています。PHP バイナリをスタンドアロンインタプリタとして使用することが できる場合でも、PHP は、セットアップにより生じる可能性がある 次のような攻撃を防ぐように設計されています。

(略)

(略)

ぱっと読んだけどあんまし良くわかってない。

  • (shebangを使わない方法だと)phpのバイナリを/cgi-bin以下に置く必要がある
  • CERTはインタプリタcgi-bin に置くことに反対している

ということまではわかる。でも

PHP バイナリをスタンドアロンインタプリタとして使用することができる場合でも、
PHP は、セットアップにより生じる可能性がある 次のような攻撃を防ぐように設計されています。

ってことなのでいらんのでは?と思ったけど。想定外のことが起きるかもしれないし、そもそも直接phpバイナリにアクセスする必要ないから禁止するってことで良いか。

*1:php 5.3.0から--enable-force-cgi-redirect オプションがなくなった。defaultになった?