[nginx] nginxでbash/CGIを動かす – ブラウザからシェルスクリプトを実行してみよう!


profile-photo-usptomo-96x96こんにちは。USP友の会のnullpopopoです!と言うより「シェル芸人です!」と名乗ったほうが通りがよいことに気がついた今日この頃ですが、いかがお過ごしでしょうか。nginxでCGI、PerlやPHPだけじゃなく、ここはシェルスクリプトも動かしたいところ。それでは早速やってみましょう。

ここからの手順は、[nginx] nginxでperl/CGIを動かす の手順を応用していますので、CGIを動かせる環境構築はこちらを参考にしてください。

■ nginx バーチャルホスト設定

CGIの拡張子は何でもよいのですが、ここは「.sh」で動かすことにしましょう。バーチャルホストのconfigに以下を追記します。

    location ~ .sh$ {
        gzip off;
        root   /home/vhosts/www.example.com/public_html;
        include /etc/nginx/fastcgi_params;
        fastcgi_pass 127.0.0.1:10500;
        fastcgi_index index.sh;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

気をつける箇所ですが、 fastcgi_pass のポートは1024より大きな値にしてください。また、こちらでは8999番ポートを使用しているので、ポートが被らないよう、確認しましょう。本ページでは10500番ポートでListenすることにします。次にラッパーファイルとスタートスクリプトを作成しますが、いずれもファイルのオーナーは一般ユーザーとします。

■ ラッパーファイル作成

以前、nginxで perl/CGI を動かしたときに、 /usr/bin/fastcgi-wrapper.pl を作成しましたが、Listenするポートを変更して今回は /usr/bin/fastcgi-10500-wrapper.pl を作成することにします。オリジナルの /usr/bin/fastcgi-wrapper.pl との差分は以下の通りです。

[ (っ´∀`)っ@友の会 ~]$ diff /usr/bin/fastcgi-wrapper.pl /usr/bin/fastcgi-10500-wrapper.pl
30c30
<         $socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 ); #use IP sockets
---
>         $socket = FCGI::OpenSocket( "127.0.0.1:10500", 10 ); #use IP sockets

 

■ スタートスクリプト作成

前回は /etc/init.d/perl-fastcgi を作成しましたが、同様に /etc/init.d/perl-fastcgi-10500 を作成します。ロックファイルを生成するために sudo を使っていますので、適宜 visudo で権限を編集しておきましょう。ファイルの差分は以下の通りです。

[ (っ´∀`)っ@友の会 ~]$ diff /etc/init.d/perl-fastcgi /etc/init.d/perl-fastcgi-10500
21c21
< perlfastcgi="/usr/bin/fastcgi-wrapper.pl"
---
> perlfastcgi="/usr/bin/fastcgi-500-wrapper.pl"
24c24
< lockfile=/var/lock/subsys/perl-fastcgi
---
> lockfile=/var/lock/subsys/$(basename $0)
32c32
<     [ $retval -eq 0 ] && touch $lockfile
---
>     [ $retval -eq 0 ] && sudo touch $lockfile
41c41
<     [ $retval -eq 0 ] && rm -f $lockfile
---
>     [ $retval -eq 0 ] && sudo rm -f $lockfile

 

■ 各デーモン起動

ここまでできたら、各デーモンを起動しましょう。nginxが動いていたら再起動します。決して /etc/init.d/perl-fastcgi-10500 をrootで起動しないように気をつけましょう。TCP 10500番ポートがrootでバインドされていないことを起動後に確認しましょう。

[ (っ´∀`)っ@友の会 ~]$ sudo lsof -i:10500
COMMAND    PID   USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
fastcgi-1 2433 hamada    3u  IPv4 2068475      0t0  TCP localhost:10500 (LISTEN)

このように、USERの列が一般ユーザであればOKです。それでは、htmlを表示するシェルスクリプトをドキュメントルートにデプロイしてみましょう。

[ (っ´∀`)っ@友の会 ~]$ vi hello.sh
#!/bin/bash

echo "Content-type: text/html"
# An empty line is needed here. So echo nothing.
echo ""

echo ""
echo ""
echo "Wow"
echo ""
echo ""
echo "

Hello World!

" echo "" echo ""

それではブラウザからアクセスしてみましょう。

bashcgi

このように表示されればOKです。さらに、rootでないと実行できないコマンドを書いて、実行できなければ完璧です。スクリプトの末尾に「iptables -L -n」と追記して、ターミナルを立ち上げながらブラウザをリロードしてみましょう。ターミナルに

iptables v1.4.7: can't initialize iptables table `filter': Permission denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.

と表示されていればOKです。スクリプトに万が一「sudo iptables -L -n」のような記述があっても実行されないよう、 /etc/sudoers には「Defaults    requiretty」の記述があるか、またはCGIを実行するユーザの「Defaults:ユーザ名    !requiretty」がないことを確認しましょう。

これでブラウザ経由でシェルスクリプトを実行する環境が整いました。ね、簡単でしょう?

[amazonjs asin="4797321946" locale="JP" title="入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界"]