ほんのちょっとした、Debian GNU/Linuxの情報

DebianでPHPをユーザ権限で実行する

どういう条件で実現しようとしているかというと

対象は、PHP7.0です。サーバはApache2です。

Debianは、9(stretch)です。

一般的なレンタルサーバで用いられている(と思われる)CGIではなく、FastCGI(PHP-FPM)を使用します。

ユーザ単位にバーチャルサーバを用意します。

PHPはパッケージphp(php7.0)が、インストール済を前提として説明します。

この方法が、本当に正しいのかは、保証できません(^_^;

PHP-FPMのインストール

PHP-FPMのパッケージをインストールします。

$ sudo apt install php-fpm

Apache2を既にインストール済みであれば、インストール中に、以下のメッセージが表示されます

NOTICE: Not enabling PHP 7.0 FPM by default.
NOTICE: To enable PHP 7.0 FPM in Apache2 do:
NOTICE: a2enmod proxy_fcgi setenvif
NOTICE: a2enconf php7.0-fpm
NOTICE: You are seeing this message because you have apache2 package installed.

内容はだいたい見ての通りです。

PHP 7.0 FPMは、デフォルトで有効になっていません。

Apache2でPHP 7.0 FPMを有効にするには、a2enmodコマンドでproxy_fcgiとsetenvifの各モジュールをロードし、
a2enconfコマンドで、php7.0-fpmの設定を有効にしてください。

PHP-FPMのセットアップ

その前に

PHPをインストール済みの場合、既にモジュールモードの設定がなされているはずなので、その設定を削除します。

モジュールモードとCGIモードは(多分設定によれば)共存できるのですが、php7.0-fpmのデフォルトの設定では、PHPのモジュールが無効の場合のみphp-fpmにリダイレクトするので、PHPのモジュールを削除しないと有効になりません。

また、PHPのモジュールはかなり大きなライブラリなので、どうしても必要なケースを除けば、削除したほうが不要なメモリを使わずに済みます。

特に、Apacheをprefork(1リクエストを1プロセスで処理する)で動かしている場合は、影響が大きいです。

モジュールモードが設定されているかは、以下のコマンドで確認できます。

$ sudo a2query -m | grep php

設定されていれば、以下のように表示されます、設定されていなければ、多分何も表示されません。

php7.0 (enabled by maintainer script)

削除は、以下のコマンドで行います。

$ sudo a2dismod php7.0

すると、以下のようなメッセージが表示されるので、

Module php7.0 disabled.
To activate the new configuration, you need to run:
  systemctl restart apache2

メッセージどおりに、apache2を再起動してもいいですが、次の「php7.0-fpmの設定」が終了してから再起動しても、問題ありません。

$ sudo systemctl restart apache2

php7.0-fpmの設定

php-fpmパッケージをインストールした時に表示されたコマンドを実行します。

$ sudo a2enmod proxy_fcgi setenvif

普通にapache2をインストールしていれば、setenvifはセットアップ済みのはずなので、そのようなメッセージが表示されます。

Considering dependency proxy for proxy_fcgi:
Enabling module proxy.
Enabling module proxy_fcgi.
Module setenvif already enabled
To activate the new configuration, you need to run:
  systemctl restart apache2
$ sudo a2enconf php7.0-fpm

こちらも、成功すれば以下のようなメッセージが表示されます。

Enabling conf php7.0-fpm.
To activate the new configuration, you need to run:
  systemctl reload apache2

メッセージどおりに、apache2を再起動します。

$ sudo systemctl restart apache2

まだ、ユーザ権限で実行する設定ができていませんが、phpが実行できるかを確認します。ここでphpが実行できないままユーザ権限での実行を設定すると、後々泣くことになります。

ユーザ権限で実行できるように設定する

php7.0-fpmのシーケンス

php7.0-fpmで、phpが実行される仕掛けは、以下のようなシーケンスによります。

php7.0-fpmで、phpが実行される仕掛け

この時、「php-fpmプロセス」が各ユーザの権限で実行されることにより、最終的に実行されるphpスクリプトがユーザ権限で実行されます。

php-fpmプロセスの設定

デフォルトプロセスの設定は、下記ファイルになります。

/etc/php/7.0/fpm/pool.d/www.conf

色々書かれていますが、コメントを削除すると設定内容は以下のようになります。

www.conf

プロセスとの通信設定は、下記ファイルとなります。

/etc/apache2/conf-enabled/php7.0-fpm.conf
php7.0-fpm.conf

ここで重要なのは、10行目のSetHandlerで、www.confの4行目の設定と合わせてあります。

必要な作業は、新しいプロセスの設定をwww.confを元に作成し、その内容をバーチャルサーバに設定することです。

新しいプロセスの設定を作成する

前出のwww.confの設定内容で、変更が必要なのは最初の4行で、それ以外は変更不要です。

www.confを元に同じディレクトリにlocaluser.confを作成し、下記のように変更します。

localuser.conf

1行目の[]内はプール名で、他と区別できるユニークな名前を付けます。

2行目と3行目は、それぞれプロセスを実行するユーザとグループです。

4行目が、Apacheのモジュールと通信するためのUNIXドメインソケットです。

バーチャルサーバ側の設定は、下記のようになります。

virtualHost.conf

4-6行目を追加します。

5行目のUNIXドメインソケットを、localuser.confのそれと合わせます。

php7.0-fpmとapacheを再起動します。

$ sudo systemctl restart php7.0-fpm
$ sudo systemctl restart apache2

下記のようなphpスクリプトを用意してアクセスすれば、実行ユーザが確認できます。

<?php
echo posix_getpwuid(posix_getuid())['name'];
?>