apache suexec 活用法
apache の suexec は非常に便利な機能であるが,セキュリティを脅かす 危険性があるため,厳しい制限がかかっている.そのため,問題ないと思われる 場合でも Internal Server Error が出てしまう場合がある.この文書はその制限を うまく回避して,動作させることを目的とする.
suexec とは
apache から起動される CGI は,apache のプロセスから fork するため, apache が root 権限で動いていない限り(通常は root 権限で動かさない) CGI は apache の権限で動作する.しかし,サーバコンピュータ上では 様々なユーザが存在し,それぞれが CGI を動作させることを考えると, CGI を利用して他のユーザの CGI が利用するデータなどを破壊することが 可能である.これを回避するために,suexec と呼ばれる setuid root コマンドを使って CGI を起動することで,当該ユーザの権限で CGI を 動作させる.これが suexec である.
suexec の制限
suexec は setuid root されたコマンドなので,誰が起動しても強大な 権限を持つ.その利用を制限するために,suexec コマンド内部で様々な チェックを行っており,このチェックに一つでもひっかかればエラーで 終了するようになっている.制限は,下記参考文献の apache ドキュメントに 詳細に載っているのでそちらを参照すること.
コマンド所有者制限の回避
suexec の制限のひとつに,コマンド所有者の制限がある.これは,suexec 経由で動作させるコマンドは,そのユーザの所有かどうかチェックする. コマンドが symlink の場合は,symlink 先をチェックする. たとえば,Debian パッケージでインストールした /usr/lib/cgi-bin/example.cgi を ~tach/public_html 以下に symlink した場合,example.cgi の所有は root であるために,suexec での実行がエラーになる.
そこで,簡単な回避としては,コマンドをコピーするという対策が 考えられるが,コピーしてしまうと,たとえばパッケージのバージョン アップで example.cgi が置き換わってもコピー先は置き換えられず, 古いままで放置されてしまうという問題がある.とくに,セキュリティ のためのバージョンアップの場合にこれは問題になる(コピーし直せば いいのだが,忘れがちだ).
そこで,このような場合は以下のような簡単な shell script を書いて, symlink の代わりにおいておく.
#!/bin/sh exec /usr/lib/cgi-bin/example.cgi
この shell script は,指定されたコマンドを起動するだけの単純なものだが, コマンドの所有が自分自身になるため,この制限を回避できる.ただし, exec で起動するコマンドが安全であることを確認しておくことが重要. 他人のホームディレクトリにあるようなあやしいスクリプト・コマンドをここで exec すべきではない.
環境変数を変える
通常は意識することはないが,suexec で起動されるコマンドは,環境変数のセットが 制限されている.たとえば,mod_env の SetEnv? ディレクティブを使って環境変数を セットしても,suexec で起動されるコマンドにはその環境変数は渡されない.
そこで,前項と同じようにシェルスクリプトを使って,環境変数をセットする.
#!/bin/sh export TRAC_ENV /home/tach/trac exec /usr/lib/cgi-bin/example.cgi
この技は通常の CGI のときにも有効で,mod_env が利用できない場合や, apache から渡される SCRIPT_NAME や PATH_INFO といった環境変数を 強制的に変更する場合にも有効である.
