Apache suExec設定

Apacheは、そのまま使用すると、
「apache」というユーザー権限でPHPが動作することになる。

「httpd.conf」ファイルで実行ユーザーを変更する事も可能だが、
Linuxユーザーごとの権限で動かしたいという場合、
「suExec」という機能を使用することになる。

「suExec」は、設定こそは少々手間ではあるが、
PHPはCGIモードで動作する事になり、各ユーザーの権限で実行するため
仮にマルウェアを埋め込まれたとしても、
他のユーザーの領域にまで被害が及ぶ事がなくなる。

この記事では、「testuser」というユーザーで設定を行う例である。
$ useradd testuser」コマンドで、
ユーザーを作成した前提で説明する。

suExecの確認

多くの場合、デフォルトでsuExecが入っている場合が多い。
以下のコマンドで、環境を確認しておこう。

$ /usr/sbin/suexec -V

すると、以下が出力される。

 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=500
 -D AP_HTTPD_USER="apache"
 -D AP_LOG_SYSLOG
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=500
 -D AP_USERDIR_SUFFIX="public_html"

httpd.confの設定
総合的な設定も含まれているが、
「httpd.conf」の最後に、以下の要素を埋め込むとよい。

<Directory "/home/*/">
    Options Includes FollowSymLinks ExecCGI
    DirectoryIndex index.php index.html index.htm index.cgi
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

「/home/」配下の各ユーザーディレクトリすべてに、適用される。
特に「.htaccess」を使用するため、「AllowOverride」は「All」に設定する必要がある。

各ユーザーのシェルスクリプトの作成

「/var/www/」ディレクトリに、
各ユーザーのシェルスクリプト用領域とファイルを作成する。

$cd /var/www/
$ mkdir users 
$ chmod 0711 users 
$ chown apache.apache users 

「users」ディレクトリを作成し、
パーミッションを「711」に、所有者・所有グループを「apache」にする。

結果、以下の状態にする。

drwx--x--x 4 apache apache 4096 Apr  5 14:37 users

このディレクトリは、一度作成してしまえば、
以降はその中でユーザーごとの領域作成をするとよい。

各ユーザーごとの領域作成

「users」ディレクトリの中に、各ユーザー用ディレクトリを作成する。

$ cd users
$ mkdir cgi-testuser
$ chmod 0710 cgi-testuser
$ chown testuser.testuser cgi-testuser

この場合、「cgi-testuser」というディレクトリ名とする。
以下のようにディレクトリが作成できればよい。

drwx--x--- 2 testuser testuser 4096 Apr  5 15:06 cgi-testuser

そのディレクトリの中に、
「php-cgi」(拡張子は無し)という名称のファイルを作成する。

$ vi cgi-testuser/php-cgi

以下は、「php-cgi」の中身である。

#!/bin/sh
exec /usr/bin/php-cgi

「php-cgi」というファイル名と中身は、全ユーザー共通である。

次に、パーミッションと、所有者・所有グループを設定する。

$ chmod 750 cgi-testuser/php-cgi
$ chown testuser.testuser  cgi-testuser/php-cgi

結果、以下の状態になる。

-rwxr-x--- 1 testuser testuser 32 Apr  5 14:32 php-cgi

各ユーザーディレクトリの設定

ユーザーディレクトリのパーミッションを設定する。
また、ウェブアプリケーションの配置先として、
「public_html」ディレクトリも作成しておく。

$ cd /home
$ chmod 710 testuser
$ mkdir testuser/public_html
$ chmod 710 testuser/public_html

ユーザーディレクトリに入り、そのroot領域に「.htaccess」ファイルを作成する。

$ cd testuser
$ vi .htaccess

「.htaccess」には、以下のように書き込む。

Action php5-cgi /php5-testuser
AddHandler php5-cgi .php

「.htaccess」の権限状況は以下のとおりである。
設定用コマンド

$ chmod 655 .htaccess 
$ chown testuser.testuser .htaccess 

結果

rw-r--r-- 1 testuser testuser   55 Apr  7 09:54 .htaccess

バーチャルホストの設定

以下を一組として扱う。

ScriptAlias /php5-testuser /var/www/users/cgi-testuser/php-cgi

<VirtualHost *:80>
  ServerName testuser
  DocumentRoot "/home/testuser/public_html"
  ServerAlias testuser
  SuexecUserGroup testuser testuser

  ErrorLog logs/testuser-error_log
  CustomLog logs/testuser-access_log combined env=!no_log
</VirtualHost>

ユーザーグループにapacheを参加させる

$ gpasswd -a apache testuser

「usermod」の場合、対象のグループの情報を、
丸ごと変更する形なので、使いにくい。
「gpasswd」で行ったほうが、追加や削除が行えるため、わかりやすい。

確認は、以下のコマンドで行える(厳密には「gpasswd」ファイルの確認)。

$ cat /etc/group

結果

testuser:x:503:apache

対象ユーザーのグループに「apache」が乗っかっていれば成功である。
これで「apache」は、対象ユーザー所有のファイルの中で、
グループに実行権限を与えているものを実行する事が可能となる。

もし間違えて別のグループに所属させてしまったり、
逆にapacheグループにユーザーを所属させてしまった場合は、
以下のように「-d」オプションを使えば、
対象のユーザーを対象のグループから解除する事ができる。

$ gpasswd -d group user

確認方法

以上で設定は完了であるが、
本当にユーザー権限で動作しているかどうかは、
以下のPHPコードを実行してみるとよい。

?<php

echo posix_getpwuid(posix_geteuid())['name'];

これで、「apache」ではなくユーザーの名前が表示されれば成功である。