FastCGIの例

まず、全ての代表的なFCGI設定を1つのファイルにまとめ、それらをimportすることをお勧めします。

例えば、下記のような /etc/nginx/fastcgi.conf (あるいはdebianでのデフォルトのインストール /etc/nginx/fastcgi_params)を持つかも知れません:

#fastcgi.conf
fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;
fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

これにより、個々のFCGI設定をできる限り簡単にすることができます。SCRIPT_FILENAME内の$document_root および DOCUMENT_ROOT を実際のパスと置き換えたいとも思うかも知れません。$document_root 変数はハードコードされていて、インストールを反映しないかも知れません(通常は'script not found' に変化をもたせたものを起こすでしょう)。NGINX + Virtual Host + PHP を使うには、PHPが正しいDOCUMENT_ROOTを選択するために、SCRIPT_NAME 変数を省略する必要があります。

FastCGI プロセスのspawn

Apache あるいは Lighttpd と異なり、NGINXは自動的にFCGIプロセスをspawnしません。それらを個々に開始する必要があります。実際、FCGIはとてもプロキシに似ています。FCGIプログラムを開始するには2,3の方法がありますが、幸運なことにPHP5は PHP_FCGI_CHILDREN環境変数に設定したのと同じ数だけ自動的にspawnするでしょう。 つまり、単純にphp -b 127.0.0.1:9000 を手動で実行するか、以下のように初期スクリプトを生成します:

#!/bin/bash
BIND=127.0.0.1:9000
USER=www-data
PHP_FCGI_CHILDREN=15
PHP_FCGI_MAX_REQUESTS=1000

PHP_CGI=/usr/bin/php-cgi
PHP_CGI_NAME=`basename $PHP_CGI`
PHP_CGI_ARGS="- USER=$USER PATH=/usr/bin PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS $PHP_CGI -b $BIND"
RETVAL=0

start() {
      echo -n "Starting PHP FastCGI: "
      start-stop-daemon --quiet --start --background --chuid "$USER" --exec /usr/bin/env -- $PHP_CGI_ARGS
      RETVAL=$?
      echo "$PHP_CGI_NAME."
}

stop() {
      echo -n "Stopping PHP FastCGI: "
      killall -q -w -u $USER $PHP_CGI
      RETVAL=$?
      echo "$PHP_CGI_NAME."
}

case "$1" in
    start)
      start
  ;;
    stop)
      stop
  ;;
    restart)
      stop
      start
  ;;
    *)
      echo "Usage: php-fastcgi {start|stop|restart}"
      exit 1
  ;;
esac
exit $RETVAL

これを /etc/init.d/ (あるいは、initスクリプトがある場所)に、php-fcgiとして保存し、 通常のインストール(このdebian initスクリプトの場合、デフォルトはupdate-rc.d php-fcgiです)し、それを開始します。

NGINXを実行中のFastCGIプロセスに接続します

今はもうFCGIプロセスが実行しているので、NGINXにリクエストをFCGIプロトコルを使ってそれにプロキシするように伝えます。

location ~ \.php$ {
    include /etc/nginx/fcgi_params; #or whatever you named it
    fastcgi_pass  127.0.0.1:9000;
}

NGINXを再起動します。

アップロードディレクトリを安全にする!!

あまりに多くの設定例が、アプリケーションの"uploads"ディレクトリを安全にするのに失敗しています。 誰かがxyz.phpという名前のファイルをアップロードすることができ、そのuploadディレクトリが公にアクセス可能であれば、アタッカーがサイトにPHPを挿入できる簡単な方法を提供することになる事を思い出してください...

つまり、アプリケーションがuploadディレクトリ"/images/" を持つ場合、以下のようにfastcgi_passの前に if ($uri !~ "^/images/")を挿入します:

location ~ \.php$ {
    include /etc/nginx/fastcgi_params;
    if ($uri !~ "^/images/") {
        fastcgi_pass 127.0.0.1:9000;
    }
}
TOP
inserted by FC2 system