Not only is the Internet dead, it's starting to smell really bad.:2015年04月中旬

2015/04/11(Sat)

[www][ンッギモヂイイ X] NetBSD で nginxを使う(その3)

@外部アプリケーションを FastCGI プロセスとして実行する wrapper を用意する

おあつらえむきに fcgiwrapというものがあります、ただこれ pkgsrc にはまだ無いので pkgsrc-wip(Work In Progress)から導入する必要があります。よってバイナリパッケージは用意されてないので pkgin とか pkg_add ではなく、自分でビルドしないとダメ。

@pkgsrc-wipの導入

導入方法は pkgsrc と pkgsrc-wip を CVS からか snapshot の tarball を拾ってきて、pkgsrc/wip として配置するだけで後は普通の pkgsrc と同様にビルドできます。

$ cvs -d:pserver:anoncvs@anoncvs.netbsd.org:/cvsroot get -P pkgsrc
$ cvs -d:pserver:anoncvs@pkgsrc-wip.cvs.sourceforge.net:/cvsroot/pkgsrc-wip checkout -P wip
$ mv wip pkgsrc
$ mv pkgsrc /usr

詳しくは 読め

ちなみに pkgsrc は4半期ごとに pkgsrc-2015Q1( リリースノート) のようにリリースと呼んでいいのかスナップショットなのかちゅーものを世に出しますが、pkgsrc-wip は基本的に pkgsrc-currentでしか依存関係その他の動作確認してないはずなんで、そっち使ってください。

@wip/fcgiwrap のインストール

この

のビルドには別途 FastCGI SDK が必要ですが、こっちは pkgsrc にすでに存在します。

まぁ pkgsrc は依存関係にあるパッケージが未インストールなら勝手にインストールするので

$ cd /usr/pkgsrc/wip/fcgiwrap
$ make install

と叩くだけではあります。

@www/spawn-fcgi の起動方法

まず基本的な使い方を確認します、spawn-fcgi の manual をみると syntax は以下のとおり。

spawn-fcgi [options] [ -- <fcgiapp> [fcgi app arguments]]

-- に続けて起動対象の FastCGI アプリケーションおよび引数を指定します。

さらに spawn-fcgi には以下のオプションを指定可能です *1

  • -d <path> … FastCGI アプリの使うカレントディレクトリを指定
  • -a <address> … TCP/IP でプロセス間通信を行う、引数にはバインドする IP アドレスを指定 (-s とは排他)
  • -p <port> … 〃 ポート 〃
  • -s <path> … UNIX ドメインソケットでプロセス間通信を行う、引数にはソケットファイルを指定 (-a とは排他)
  • -u <user> … 引数で指定したユーザに setuid(2) する
  • -g <group> … 引数で指定したグループに setgid(2) する
  • -U <user> … UNIX ドメインソケットの所有権を引数のユーザに変更する
  • -G <user> … UNIX ドメインソケットの所有権を引数のグループに変更する
  • -M <mode> … UNIX ドメインソケットのパーミッションを指定する

デフォルトの nginx.conf にある設定例では

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        /usr/pkg/etc/nginx/fastcgi_params;
        #}

と、nginx と spawn-fcgi + php-cgi の通信を TCP/IP(127.0.0.1:9000)で行うようになってますが、この設定に対応するよう spawn-fcgi + php-cgi を起動するには

$ spawn-fcgi -a 127.0.0.1 -p 9000 -- /usr/pkg/libexec/cgi-bin/php

ちゅー感じで起動すればおk、TCP/IPなら nginx と spawn-fcgi を同じサーバで動かす必要もありまへん。

まぁ性能面ではUNIXドメインソケットの方が勝るので、複数台でスケールアウトする必要がなければこっちですな。

fastcgi_pass 127.0.0.1:9000;

fastcgi_pass unix:/var/run/foo.sock;

のようにソケットへのパスに書き換えるだけです、この場合 spawn-fcgi は

$ spawn-fcgi -s /var/run/foo.sock -- /usr/pkg/libexec/cgi-bin/php	

になります。

なお UNIX ドメインソケットの場合、nginx は nginx.confで

user nginx nginx;

と指定したユーザグループにsetuid/setgidしてますので、この権限で読み書きできる必要があります。

# spawn-fcgi -s /var/run/foo.sock -u nginx -g nginx -- /usr/pkg/libexec/cgi-bin/php	

とユーザグループを同じにして起動すればおk。

より安全に *2動かすため spawn-fcgi をさらに特権分離し別ユーザグループ(以下の例では spawnfcgi:spawnfcgiとする)で起動するのなら

# spawn-fcgi -s /var/run/foo.sock -u spawnfcgi -g spawnfcgi -U nginx -G nginx -- /usr/pkg/libexec/cgi-bin/php	

とする、あるいは nginx ユーザを spawnfcgi グループに所属させて

# spawn-fcgi -s /var/run/foo.sock -u spawnfcgi -g spawnfcgi -M 0660 -- /usr/pkg/libexec/cgi-bin/php	

とするなどしてグループにも読み書き権限を許可してやってください。

@spawn-fcgi + fcgiwrap の設定例

基本的にはさっきの起動方法で説明した PHP の設定例と同じです。

location ~ \.cgi$ {
	root		html;
	fastcgi_pass	127.0.0.1:9000;
	#fastcgi_pass	unix:/var/run/foo.sock;
	fastcgi_index	index.cgi;
	fastcgi_param	SCRIPT_FILENAME  /scripts$fastcgi_script_name;
	include		/usr/pkg/etc/nginx/fastcgi_params;
}

単に拡張子を .php から .cgi に変更しただけです。

起動方法も同じ、FastCGI アプリを php から fcgiwrap に変えただけです。

$ spawn-fcgi -a 127.0.0.1 -p 9000 -- /usr/pkg/sbin/fcgiwrap
$ spawn-fcgi -s /var/run/foo.sock -- /usr/pkg/sbin/fcgiwrap

@次回予告

今回は spawn-fcgiのオプションをあっさり目に説明しましたが、次はを手動でなく起動時に自動実行するようにスクリプトを設定する方法を説明します。

*1:他にも -c/-S/-C/-Fがありますが回を改めて説明します。
*2:より安全にと書きましたが、セキュリティに関する話はまた回を改めて書きます。