Sunday, January 20, 2013

はじめての PHP インストール

前回の記事 では Apache HTTP Server (2.4 系) のインストールをしました. 今回は PHP のインストールをしてみます.

mod_php ではなく php-fpm という選択肢

最新の安定版リリースは, バージョン 5.4.11 です. 一昨日リリースされたばかりのようです. これを使ってみたいと思います. まずは php-5.4.11.tar.gz を適当な場所に展開しまして, configure スクリプトを実行します.

~/php-5.4.11$ ./configure --prefix=/opt/php-5.4.11 \
  --enable-fpm \
  --with-fpm-user=phpfpm \
  --with-fpm-group=phpfpm

ところで, Apache HTTP Server (以後は単に Apache と呼ぶことにします) と PHP とを組み合わせる場合, Apache に PHP モジュールを追加で組み込むという方法が, 従来は一般的だったのではないかなと思います. 検索してみると, そういう記事が比較的多い気がします. ただ, その場合は, Apache の MPM (Multi-Processing Module) は prefork でなければならない, という話もよく見聞きします. たとえば, PHP 公式サイトの PHP: Apache 2.x on Unix systems - Manual というページの冒頭には, 次のような警告が掲げられています.

We do not recommend using a threaded MPM in production with Apache 2. Use the prefork MPM, which is the default MPM with Apache 2.0 and 2.2. For information on why, read the related FAQ entry on using Apache2 with a threaded MPM

事情をよくわかっていないわたしのような素人目線からすると, PHP はスレッドセーフじゃないのかよ, などと勘違いをしてしまいそうな警告でもあります. PHP: Installation - Manual というページには, 次のようにも書かれています.

Why shouldn't I use Apache2 with a threaded MPM in a production environment?

PHP is glue. It is the glue used to build cool web applications by sticking dozens of 3rd-party libraries together and making it all appear as one coherent entity through an intuitive and easy to learn language interface. The flexibility and power of PHP relies on the stability and robustness of the underlying platform. It needs a working OS, a working web server and working 3rd-party libraries to glue together. When any of these stop working PHP needs ways to identify the problems and fix them quickly. When you make the underlying framework more complex by not having completely separate execution threads, completely separate memory segments and a strong sandbox for each request to play in, further weaknesses are introduced into PHP's system.

If you want to use a threaded MPM, look at a FastCGI configuration where PHP is running in its own memory space.

さすがに, PHP がスレッドセーフでないだとかいうような, そんな素朴な話でもないようではあります. ただ, いずれにしても, ここでは Apache の 2.4 系については触れられていないことと, FastCGI の利用を検討してみてほしいとも記されていることから, もう少し今風 (?) の方法を考えてみたいと思いました.

で, 最初に掲載した configure スクリプトのオプションにあるように, PHP-FPM をためしてみることにした, という次第です.

具体的な手順は, おもに Apache 公式 Wiki の PHP-FPM - Httpd Wiki というページを参考にしました.

ビルドからインストールまで

PHP-FPM を利用するということは, Apache とは別に, PHP-FPM のサービスが別途起動するということでもあります. ということであれば, PHP-FPM 用のユーザーとグループもあらかじめ作っておくのがいいでしょう. (デフォルトでは nobody らしいですが.)

~/php-5.4.11$ sudo groupadd -g 502 phpfpm
~/php-5.4.11$ sudo useradd -M -u 502 -g phpfrpm -s /bin/false phpfpm

そのうえで, 先ほどからの再掲となりますが, PHP の configure スクリプトを実行します.

~/php-5.4.11$ ./configure --prefix=/opt/php-5.4.11 \
  --enable-fpm \
  --with-fpm-user=phpfpm \
  --with-fpm-group=phpfpm

これ, 実はわたしの手元の環境では, ただちに失敗してしまいました. "Configuring extensions" のフェーズで次のような結果となってしまうのです.

checking whether to enable LIBXML support... yes
checking libxml2 install dir... no
checking for xml2-config path...
configure: error: xml2-config not found. Please check your libxml2 installation.

わたしの環境では, たしかに libxmllibxml2 もインストールされていません. すればいいんでしょうけれど, 何をするものなのか, 何のために必要なのか, 現時点ではまだ理解していないので, いったんはそれを除外して進めることにしてみました.

具体的には, configure スクリプトに, まず --disable-libxml オプションを付加するのですが, それだけでは済みませんでした. というのも, これに依存する機能がほかにもいくつかあるらしく, それらも無効にする必要があったからです. ひとつひとつ確認して行った結果, 次のようになりました.

~/php-5.4.11$ ./configure --prefix=/opt/php-5.4.11 \
  --enable-fpm \
  --with-fpm-user=phpfpm \
  --with-fpm-group=phpfpm \
  --disable-libxml \
  --disable-dom \
  --disable-simplexml \
  --disable-xml \
  --disable-xmlreader \
  --disable-xmlwriter \
  --without-pear

これが済んだら, 順に次のように進めます.

~/php-5.4.11$ make
~/php-5.4.11$ make test
~/php-5.4.11$ sudo make install

テストにおいては, 12290 件のうち, 4406 件をスキップし, 7847 件をパスしました. 残り 37 件のうち, 36 件は "Expected fail" でしたが, 1 件だけ "Tests warned" でした. PHP :: Bug #52062 :: large timestamps with DateTime::getTimestamp and DateTime::setTimestamp というページに記録されているものなのですが, ここでどうすればよいのか, よくわかりません.

とりあえず, 先に進むことにします.

インストールまで済んだら, php.iniphp-fpm.conf を用意します.

~/php-5.4.11$ sudo cp -p php.ini-development \
  /opt/php-5.4.11/lib/php.ini
~/php-5.4.11$ sudo cp -p /opt/php-5.4.11/etc/php-fpm.conf.default \
  /opt/php-5.4.11/etc/php-fpm.conf

とはいえ, 現時点では, 何をどういじったらよいのか, まだまったく理解していないので, とりあえずデフォルトのままにしています. (デフォルトのままであれば, ひょっとしたらこれらの設定ファイルは, そもそも存在しなくても構わないのかもしれませんが. それはともかく, 蛇足ながら, php.ini って, なぜ etc/ ではなく lib/ に置くのでしょうか?)

PHP-FPM の起動は, 次のようにします.

~/php-5.4.11$ sudo /opt/php-5.4.11/sbin/php-fpm

デフォルトでは, 127.0.0.1:9000 において, リクエストを待ち受けることになります.

停止の仕方がよくわかりません. 現時点では, 素朴に kill していますが.

Apache 側の設定

まず, mod_proxymod_proxy_fcgi を有効にする必要があります. Apache をビルドする際に, DSO (Dynamic Shared Object) の選択で few にでもしていないかぎり, デフォルトではどちらのモジュールもインストールされていると思います. あとは httpd.conf で, それらのロードがコメントアウトされていると思うので, コメントを外せばいいんだと思います.

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

次に, ためしに, /opt/httpd-2.4.3/htdocs に次のような内容の pi.php というファイルを置いてみます.

<?php
    phpinfo();
?>

そのうえで, たとえば httpd.conf とか httpd-vhosts.conf とかで, 次のように設定をしてみます.

<LocationMatch ^/phpinfo$>
    ProxyPassMatch fcgi://127.0.0.1:9000/opt/httpd-2.4.3/htdocs/pi.php
    Require ip 192.168.0.2
</LocationMatch>

いったん Apache を再起動しまして, 手元の PC (192.168.0.2) のブラウザから http://192.168.0.1/phpinfo にアクセスしてみます. いろいろな情報が表示されれば, とりあえず成功でしょうか.

ちなみに, http://192.168.0.1/pi.php にアクセスした場合は, PHP のプロセッサに処理が行かないので, 何も情報は表示されません. また, 別の PC からアクセスすれば, 403 Forbidden です.

まあ, しかし, さわりはじめたばかりとはいえ, 上記の設定内容は少し間違えるとけっこう致命的な脆弱ポイントになりそうにも見えます. (その気になれば OS のルートディレクトリにアクセスさせるような設定も可能そうですし.) やはり, php.ini だか php-fpm.conf だかも十分に設定を調節するべきなのかもしれません.

まとめ

これまで, PHP には, ほとんど触れることもありませんでした. たしかに, 仕事のうえでは, 技術力のありそうな取引先さんにかぎって PHP を使って開発をおこなう傾向にあり, そうでない取引先さんはそもそも開発をおこないません. 自分なりに多少さわってきた Java を仕事で使う機会は, 実はほとんどありません. 仕事上の便宜を考えれば, 本当は Java ではなく, PHP を学ぶべきだったかもしれません.

ただ, 食わず嫌いで, なかなか踏み出せずに来ました. というのも, PHP というのは誰でも簡単に脆弱なものを作れるので, ある程度のセキュリティクラスタでないと危険がいっぱいだという, 漠然とした印象を抱いてきたからです.

なのに, なぜいま PHP なのかというと, ちょっと WordPress というものに興味を持ち始めまして, それが PHP で書かれているらしいので, ここでちょっと始めてみようかなと思ったのです.

なので, それへの興味が薄れたら, たぶんやめてしまうんだと思います. その前に, 記録だけでも残しておこうと, 今回のこの記事を書くことにしました.

以上です. おしまい

No comments:

Post a Comment