ルモーリン

ApacheのCGIにperlbrewを使う

投稿:2018-12-25

サーバーがCentOS6.5、一緒に入っているPerl(システムPerl)が5.10です。 日進月歩のPerlの新機能を使おうすると「何それ、知らないよ?(・_・ ) ( ・_・)」とか言われてしまう。 この記事を書いている時点で最新版は5.28です。 できれば最新版を使いたい。 もし最新版で都合が悪ければ一歩後退(一つ前のバージョンに変更)とか自在にしたい。
  1. 検索しても同様の手法がない
  2. セキュリティホールの可能性が高い
  3. 尚、死して屍、拾う者なし
  4. 尚、死して屍、拾う者なし
CGIはhttpdサーバーのApacheが起動して、そのサーバーのApacheを実行するアカウントはapacheです。 つまりアカウントapacheがperlbrewを使えるようになればCGIとしてperlbrewのPerlを使えそうです。
/etc/passwdを編集してシェルを使えるようにして、コマンドpasswdでパスワードを設定して、su -l apacheでログインします。 日常でログインしないアカウントにログインの機会を与えておくのはセキュリティの隙を突かれるので作業後に戻します。 なお、アカウントapacheのホームディレクトリは/home/apacheでなく/var/wwwです。
最新版を…と思いましたがパソコンのPerlバージョンを合わせておくとバージョン違いのトラブルを回避できそうです。 パソコンはActivePerlの5.26を使っているのでそれに合わせます。 ところがインストールを始めるとテストのioのshm(共有メモリ)にokが出た直後から反応しなくなり、 これはテスト失敗でなくテスト動作で沈黙するためインストール時オプションの--forceでも沈黙してしまいますから、 仕方がないのでテストを回避する--notestでインストールします。
perlbrew install-cpanm
必要なパッケージをドンドコ入れましょう。とりあえず
perl -c <CGIスクリプト>
を実行して「『@INCにないよ』エラー」が出てくるパッケージを全部入れましょう。
cpanm <パッケージ名>
それとインストール済かどうか自動チェックして動作が変わる場合はチェック対象のモジュールも追加しましょう。 誰だよそんな面倒な動作するモン作ったのは? すみません、私です。m(_ _)m
CGIの1行目、よくあるのは「#!/usr/bin/perl」をインストールしたperlに変更します。 一般的なシェル下でperlbrewを使う場合は「/usr/bin/env perl」と書き、環境変数を利用して起動してます。 これはバージョン切り替えを実現するための仕掛けです。 apacheではシェルの環境変数が反映されていないので起動できません。 ソフトリンクで希望のバージョンのPerlを選択して呼べるようにします。
リンクの設定
cd /var/www/perl5/perlbrew
ln --symbolic perls/perl-5.26.2/bin/perl perl
これでCGIの1行目を「#!/var/www/perl5/perlbrew/perl -w」にできます。
テスト用のCGIを実行して動作チェック。
CGIのプログラムtest.cgi
#!/var/www/perl5/perlbrew/perl -w

use utf8;
use strict;
use warnings;
use open IO => ":utf8";

use CGI '-utf8';
use Encode;
use Encode::Argv;
use Encode::Locale;

use FindBin;
use lib $FindBin::Bin;

use MyTest;

$| = 1;

my $cgi = CGI->new;
print $cgi->header(
	-charset => "utf-8",
	-language => "ja",
);
print $cgi->start_html(
	-title => "CGIのテスト",
);
print $cgi->h1("CGIのテスト");
print $cgi->p("上手く実行できたかな?");
print $cgi->p("モジュールの実行もOK?");
MyTest::test $cgi;
print $cgi->end_html;
モジュールMyTest.pm
package MyTest;

use utf8;
use strict;
use warnings;

sub test($) {
	my ($cgi) = @_;
	print $cgi->p("OK!(ズドン!)");
}

1;

無事成功♪