CGI講座 - PC-Rトップ

Apache &
セキュリティ
&
Vsftpd &
Perl で
著作権・個人情報までも考えて
セーフで∼す
おいおい
著作権はー
札幌市立東川下小学校教諭
大橋
剛
[email protected]
情報教育コーディネーター(JAPET)
NTT ドットコムマスター
Linux サーバー作成・運営
1
本日の流れ
序章
テキストエディタ・FTP ツールについて
1.CGI について
2.VSFTP サーバーの設定
3.Apache サーバーの動作の確認・設定
4.Perl のインストール・Perl の動作の確認
5.CGI のインストール
6.パーミッションの変更
7.動作の確認・手直し
8.カスタマイズ
本日は、Apache 上で CGI を作動させる実習を行います。この組み合わせは、一般のプロ
バイダーでは最もポピュラーな CGI です。比較的理解しやすい Perl 言語が書かれるのが一
般的で、フリーの CGI スクリプトも多く存在します。
仕組みさえわかれば簡単にインストールやカスタマイズができる容易さを持つ反面、セキ
ュリティホールやサーバーのプロセッサーに多くの負担をかけてしまう側面もあり、今後
は CGI から PHP に移行していくことと思われます。
CGI は既に時代遅れの産物という人もいますが、非常に活用のできるものであり、一度仕
組みを理解してしまえばカスタマイズばかりか、100%の自作も可能です。何よりも、
『楽
しい』ホームページを作ることができる CGI。頑張って設定してみましょう。
・本日のグループについて
本日は3人一組の10グループで進めていただきたいと思います。
サブネットマスク
ゲートウェイ
1
2
3
4
5
サーバー
サーバー
サーバー
サーバー
サーバー
クライアント
クライアント
クライアント
クライアント
クライアント
6
7
8
9
10
サーバー
サーバー
サーバー
サーバー
サーバー
クライアント
クライアント
クライアント
クライアント
クライアント
2
序章
テキストエディタについて
エディタは、Windows 標準付属の「メモ帳」と「ワードパッド」の他に以下のようなソフ
トがあります。CGI スクリプトは日本語 EUC で書かれたものもありますので、Windows
上では文字バケしてしまうものもあります。適切なエディタを使うようにしたほうがベタ
ーです。
メモ帳
Windows 付属のエディタ。動作が軽くお手軽だが CGI スクリプトの編集にはやや不向き。
64KB 以上のファイルは扱えない。
ワードパッド
Windows 付属のエディタ。動作が重くこれは使いづらい。CGI スクリプトの編集にはメモ
帳よりはまし。
秀
丸 (入手先 : シェアウェア)
Windows 定番のテキストエディタ。高機能なのに動作が軽いのが特長。本格的にやるなら
ぜひ用意しておきたいツールの1つ。
TeraPad (入手先 : フリーソフト)
これでフリーソフトとは驚きの内容と機能をもつエディタ。
RE for Windows (入手先 : フリーソフト)
文字コード、改行コードが Win, Mac, UNIX 形式に対応した便利なエディタツール。
■ MAC の場合
MAC といえば以下のエディタでしょう。
Jedit (入手先 : シェアウェア)
Mac 定番のテキストエディタ。Windows や UNIX 形式の文字コード、改行コードにも対応
した高機能なエディタ。最近シェアウェアになったとのこと。
YooEdit (入手先 : フリーソフト)
Free の超定番日本語エディタ。Emacs 的キー配列も可。
3
FTP ツールについて
プロバイダへ CGI ファイルを送信したり、「パーミッションの設定」をしたりする時には、
FTPツールといわれるソフトが必要です。ここでは、その FTP ツールを紹介いたします。
なお、ここでは、入手方法の他に、各ソフトの使用方法、および FTP ソフトを利用したパ
ーミションの設定方法等を解説したページへのリンク情報も、併せて提供いたしますので、
初心者の方はそれを参考にしてみてください。
Win95/98/NT/ME/2000/XP ユーザ用
•
FFFTP
o
オススメ度
o
定番 FTP ツール。個人利用の場合、フリーなようです。
o
[入手] http://www.forest.impress.co.jp/library/ffftp.html
o
[基本操作方法] 3web にある FFFTP 利用法解説ページが図を交えながら、
詳しく解説しています。初心者の方はこれを参照してください。
o
[パーミッションの設定方法] 3web にある FFFTP 利用法解説ページが図を
交えながら、詳しく解説しています。初心者の方はこれを参照してください。
•
WS_FTP Limited Edition
o
オススメ度
o
定番 FTP ツール。個人利用の場合、フリーなようです。
o
[入手] http://www.forest.impress.co.jp/library/ws_ftp.html
o
[基本操作方法] 3web にある WS_FTP 利用法解説ページが図を交えながら、
詳しく解説しています。初心者の方はこれを参照してください。
o
[パーミッションの設定方法] 3web にある WS_FTP 利用法解説ページが図
を交えながら、詳しく解説しています。初心者の方はこれを参照してくださ
い。
4
Mac ユーザ用
o
•
Fetch
o
オススメ度
o
Fetch はマッキントッシュ用 FTP ファイル転送ツールです。
ドラッグ&ドロップに対応.パーミションの指定等も可能です.
o
(入手および使い方について) 直江
浩永さんのサイトに、入手方法から、
CGI を設定するときにしないといけない「パーミションの設定」の方法ま
で、非常にわかりやすく解説されています。初心者の方はこれを参考にして
ください。
o
(備考) CGI ファイルのアップロードに利用する場合は、漢字コード自動変換
機能、改行コード自動変換機能を切っておいてください
実習1
http://
.
.
.
から FFFTP と RE を自分のコンピュータにダウン
ロードしましょう。
5
第1章
CGI について
Common Gateway Interface (CGI) とは、WWW サーバーが、WWW クライアントからの要求に
応じて、外部プログラムを起動するための仕組みの事を言い、現在のバージョンは、CGI/1.1
です。例えば、Web ページへの訪問者数を表示するためのアクセスカウンタや、訪問者に
メッセージ等を記入してもらうための掲示板で、ご存知の方も多いでしょう。
CGI が動作する状況をまとめると以下のようになります。
1. WWW サーバーがユーザエージェントから HTTP リクエストメッセージを受け
取る
2. WWW サーバーは外部のプログラムに処理を依頼する
3. CGI プログラムが実行される
4. プログラムが WWW サーバーに実行結果を返す
5. WWW サーバーがステータスライン等をつけて、HTTP レスポンスメッセージを
送り返す
6. ユーザエージェントが処理結果を受け取る
CGI では WWW サーバーが外部プログラムに処理を依頼しますが、この外部プログラムとい
うのは、WWW サーバー以外のソフトウェアを意味します。すなわち、"CGI に対応した WWW
サーバー" とは、外部プログラムへと処理を依頼するための仕組みを持っている WWW サー
バーであると言えます。 CGI プログラムの処理結果が WWW サーバーの認識可能な形式に
なっていれば、WWW サーバーが HTTP ヘッダを付加して、ユーザに返される事になります。
本来、WWW サーバーにおいては、自身が保持している文書をただ送り返す事しかできない
のですが、CGI を使うことによって外部プログラムの処理結果に基づいて動的なリソース
を生成し、送信する事ができるようになります。言い換えれば、CGI は CGI プログラムが
制作したリソースをそのまま、既にサーバー上に存在するリソースと同じようにクライア
ントに返しているに過ぎません。
6
CGI と Perl
現在、Web 上にあるほとんどの CGI プログラムは、テキスト処理に優れているという理由
から Perl というプログラム言語で記述されています。あまりにも多くのプログラムが
Perl で記述されているので、しばしば CGI と Perl が混同される事がありますが、既に
述べた通り、CGI とはサーバーの仕組みであり、Perl はその中で利用されるプログラム言
語という事で、CGI と Perl は全く異なるものであるという事を理解して下さい。即ち、
WWW サーバーを動作させるコンピュータさえ対応していれば、C や Java 等、どんなプロ
グラム言語でも利用可能です。
参照ページ
『Web裏技』
http://www.rescue.ne.jp/
7
第2章
Vsftpdの設定
通常、CGI のインストールや設定は FTP を介して行われます。telnet ポートをユーザーに
開放するのはセキュリティ上、たいへん危険でお勧めできません。
Redhat8.0以降のFTPサーバーはVsftpdです。
設定ファイル
/etc/vsftpd.conf
まずは、ファイアーウオールを許可する設定をします。(システム設定→セキュリティレベ
ル)
・インストールされているパッケージの確認
# rpm -qa │grep vsftpd
・ftp サーバーの起動を確認(vsftpd)
# ps ax | grep vsftpd
なんと anonymous でログインできてしまいます。
しかし permission で蹴られるので一応安心。しかし油断はなりません。
VSFTPD の設定
(
/etc/vsftpd/vsftpd.conf )
・anonumous の不許可
Allow anonymous FTP?
anonymous_enable=NO ←YES から
NO
デフォルトの設定では、ユーザーはルートや他ユーザーのディレクトリの中を自由に移動
できてしまいますので、これを制限します。
・cd の不許可
#chroot_list_enable=YES
←#をとる
# (default follows)
#chroot_list_file=/etc/vsftpd.chroot_list ←#をとる
8
・cd できるユーザーlist の追加
/etc/vsftpd.chroot_list
ファイル名 vsftpd.chroot_list が新規作製されますので順次ユーザーを登録していって下
さい。
Ascii モードの許可
∼ cgi スクリプトはアスキーモードで FTP 転送する必要があります。
デフォルトでは不許可になってるので、許可します。
#ascii_upload_enable=YES
#ascii_download_enable=YES
・VSFTPD の再起動
∼
vsftpd.conf は、vsftpd を再起動しないと反映されません
# /etc/rc.d/init.d/vsftpd restart
パーミッションの設定 ∼ FFFTP でログインすると”permission denied ”と表示されエ
ラーしてしまいます。ユーザーのホームディレクトリのパーミッションを変更してやる必
要があります。
# su (スーパーユーザーになる。ホームディレクトリを書き換えできるのはスーパーユ−
ザーのみです)
# password (パスワードを入力)
# chmod 755
/home/hogehoge(ユーザーのホームディレクトリを rwxrw-rw の設定にする)
実習2
・サーバーで予め、ユーザーを作成しておきましょう。
・ サーバーのファイアーウォールは FTP ができるように設定しておいてください。
(Redhat9 のデフォルトの設定
<中>では FTP できないようになっています)
vsftp.conf を編集して、ユーザーのホームディレクトリにアクセスして、ファイルの
アップロード・ダウンロードができることを確認しましょう。
・ ポイント
∼
ホームディレクトリより上にあがれてしまっていませんか?
パーミッションの設定が間違っていませんか?
9
第3章 Apache サーバーの設定
Apache1.3 以下では srm.conf、
httpd.conf、
mime.conf の3つの conf ファイルがありましたが、
Apache2 では httpd.conf の一つにまとまりました。
今日は、ユーザーごとに”http://xxx.xxx.xxx.xxx/ hogehoge/でアクセスできるホームディレ
クトリを用意し、その中の cgi-bin フォルダ内で cgi を動かすという、一般的なプロバイダでよ
く使われる設定をしたいと思います。
※
ちなにみ、apache2 のデフォルトの設定では /var/www/cgi-bin で cgi を動かすようになっ
ていますが、これではいろいろと問題が発生します。
・apache のバージョンの確認
# rpm -aq | grep httpd
httpd-manual-2.0.40-8
redhat-config-httpd-1.0.1-13
・Apache2 だったら
# rpm -q httpd
httpd-2.0.40-8
・
/etc/httpd/conf/httpd.conf の編集
・まず、各ユーザーのホームディレクトリの
public_html 内で web を公開できるように
します。
</IFModule mod_userdir.c>
・UserDir?行を、disable 行を削除(アンコメント)して public_html の行を有効に
これで、例えば /home/hogehoge/public_html/index.html は、
http://xxx.xxx.xxx.xxx/~hogehoge/index.html で参照できるようになります。
10
次に、apache で cgi が動く設定をしてやります。設定する箇所は、3 箇所あります。
・ScriptAlias の変更
/cgi-bin/
を
∼
cgi をどのディレクトリで動かすかの設定です。
“/var/www/cgi-bin” (デフォルト)
/*/cgi-bin/
"/home/*/public_html/cgi-bin/" にする。(最後の
・AddHandler を有効にして、.pl を付け足す
∼
/
に注意)
どの拡張子が cgi か定義する。
AddHandler cgi-script .cgi .pl
・Directory の設定
∼
ディレクトリへの cgi のアクセス制限
Directory "/home/*/public_html/cgi-bin">
Options FollowSymLinks ExecCGI
</Directory>
apache の再起動
∼ httpd.conf を反映させるためには、apache を再起動します
# /usr/sbin/apachectl restart
実習3
・ ユーザーのホームディレクトリに”public_html” ディレクト
rw-rw リを作成し、パーミッションの許可(rwxrw-rw-)を与えまし
ょう。
httpd.conf を編集して、ユーザーの public_html 下の index.html
ファイル等を作成し、html ファイルが表示できることを確認しま
しょう。
ちょっと知っておくといいかも・・・
Apache2 以降では、極端にいえば Apache1 のマニュアルはあまり参考にならないといってい
いかもしえれません。Conf ファイルの位置が変更になりましたし、文字セット(キャラク
ターセット)が日本語についてあまり考えられていませんし、セキュリティを非常に重視
する設定のため、パーミッション設定には非常にシビアになっています。
11
Apache2.0 でページが文字化けしてしまう場合
Apache2.0 は、次のように META タグで「charset=」指定をしていても、標準設
定で ISO-8859-1(ラテン系欧州語、フランス語、ドイツ語)文字セットを補う。
Redhat8 からは apache2 が導入されており、デフォルト設定のままでは日本語が
表示できません。
これを回避するには
/etc/httpd/conf/http.conf
を編集します。
初期状態では約 760∼770 行目あたりに
AddDefaultCharset ISO-8859-1
という記述がありますので、これをコメントアウトします。
# AddDefaultCharset ISO-8859-1
これで完了です。
httpd を再起動します。
これで日本語が表示されるようになります。また、次の行も編集しておきましょ
う。
LanguagePriority en da nl et fr de el it ja kr no pl pt pt-br ltz ca es sv
tw
↓
LanguagePriority ja en da nl et fr de el it kr no pl pt pt-br ltz ca es sv
tw
12
第4章
Perlの動作の確認
・Perl がインストールされている場所を探す
#which perl
/usr/bin/perl (redhat9 の場合)
・Perl のバージョンの確認
#perl -v
実習4
・ perl のインストールされている場所を確認しましょう
・ perl のバージョンを確認しましょう
第5章
CGI スクリプトのインストール
Ascii モードと Bynary モード
CGI スクリプトは Ascii モードで FTP 転送する必要があります。これは、CGI の改行コードが
Bynary では強制的に変換されてしまうのが原因です。
実習5
・public_html 内に cgi-bin ディレクトリを作成します。
・test.cgi を ascii モードで cgi-bin ディレクトリに転送しましょう。
13
第6章
パーミッション(属性)の変更
インターネットは,たくさんの人が利用しているので,それなりの仕組みが必要です.
その1つにパーミッション(属性,アクセス権,許可権)があります.
パーミッションは読み,書き,そして実行できる人を制限します.
なぜ,そんな面倒くさいことをするのでしょう.
理由は簡単で,あなたのファイルを他の人が書き換えたり,削除できたら困りますよね?
例えば,トップページが他の人のページになってしまったり,ホームページ全てが消されていたり.
そこで,パーミッション(属性)で制限するのです.
あ
な
た
グループ
そ
の
読
み
○
○
○
書
き
○
×
×
実
行
○
×
×
他
読み:ファイルを読み込む権利.つまり,ファイルを見ることを許可する.
書き:ファイルを書き込む権利.つまり,ファイルの作成や修正,削除を許可する.
実行:ファイルを実行する権利.つまり,ファイルを実行することを許可する.
通常,パーミッションはあなたにのみ,読み,書き,実行ができるようになっており,グループ,
その他の人には読みだけができるようになっています.そのため,他の人はあなたのページを見る
ことはできても,あなたのページを書き換えたりできなくなっているわけです.
しかし,CGIを使うためには,この制限を変更し「誰でも書いていいよ!」等の設定しなくては
いけません.
14
変更する仕方
パーミッションは,読み(Readable),書き(Writable),実行(eXecutable)の3つの組み
合わせを,あなた自身,グループ,その他で設定します.指定方法には,rwx で指定するか
数字で指定するかの2つがあります.
•
rwx 指定
読み(r),書き(w),実行(x)を,あなた自身,グループ,その他の順で表すだけです.
例えば,[ rwxr--r-- ] だと,あなた自身は rwx,グループが r--,その他が r--となります.
つまり,あなただけ読み,書き,実行ができて,他の人は読みだけしかできないことになります.
•
数字指定
数字3桁で,あなた自身,グループ,それ以外を示します.具体的には,読み(r)を4点,書き
(w)を2点,実行(x)を1点として,その合計点を求めます.それを,あなた自身,グループ,
その他の順で並べます.例えば,あなたは読み,書き,実行ができ,グループは読みと書き,そ
の他は,読みしかできない場合は以下のように計算します.あなた自身 − 読み,書き,実行が
できるので,4点+2点+1点なので,7点
o
グループ − 読み,書きなので,4点+2点で6点
o
その他 − 読みだけなので,4点
よって,764 になります.
15
•
対応表
わかりにくいと思うので,対応表を用意しました.
RWX 数
値
RWX 数
値
---
000
r--
004
--x
001
-wx
005
-w-
002
rw-
006
-wx
003
rwx
007
FTPで変更する
「FFFTP」を例に説明します.
FFFTPでは,パーミッションを変更したいファイルを選択し,右クリックするとメニュー[属性変更]
がみつかります.
あとは,出てきたダイアログボックスでチェックするだけです.
FFFTPでは,[現在の属性]で数字3桁を直接入力することもできます.
たとえば
パ
シ
を [644] にするときは
16
以
ようにします
たとえば,パーミッションを [755] にするときは,以下のようにします.
たとえば,パーミッションを [666] にするときは,以下のようにします.
たとえば
パ
シ
を [777] にするときは
17
次
ようにします
実習6
・test.cgi のパーミションを変更して、cgi が動くかどうか、試してみましょう
test.cgi のスクリプト
#!/usr/bin/perl
print "Content-type: text/html;¥n¥nOk!¥n";
・コマンドラインから実行
cgi-bin ディレクトリに移動します。
# ./test.cgi(相対パスで test.cgi を実行)
# Ok! という返事がかえってくれば成功です。
・ブラウザから実行
http://xxx.xxx.xxx.xxx/ hogehoge/cgi-bin/test.cgi
みてみましょう。
18
を実行して、成功するか
第7章
CGI スクリプトのインストール。動作の確認及びエラー時の対処(エラーログ)
form.cgi、submit.cgi、jcode.pl、 log.dat、template.dat
public_html
|
(666)
cgi-bin――― ディレクトリ
0 ――template.dat(666)
∼フォームのテンプレート
log.dat(666) ∼記録ファイル
|
|
form.cgi (707) ∼受け付けフォーム
submit.cgi (707) ∼投稿完了フォーム
jcode.pl (707) ∼jcode.pl
init.pl (707) ∼基本設定ファイル
jcode.pl
jcode.pl は、プログラミング言語 Perl で、日本語文字コー
ドを変換するためのライブラリです。
CGI を実行してみましょう。エラーの表示は出ませんでしたか?
エラーが出た場合、エラーの内容により、原因が特定できる場合がほとんどです。
・Permission
denied
パーミッションが許可されていないことによるエラー。
・Eternal Sever Error
CGI が実行できなかったことによるエラー。例
要なファイルが足りない等。
・Premature end of script headers
19
:
CGI スクリプトの間違い。実行に必
CGI は動いているが、HTML への出力ができないことによるエラー。例:Perl のパスの間
違い。文字コードの間違い。パーミッションが緩すぎることによるエラー(Apache2)
第8章
CGI のカスタマイズ
本日使用したサンプル(form.cgi、submit.cgi)
サンプルプログラム form.cgi
#!/usr/local/bin/perl # Perl のパス
require "./jcode.pl";
require "./init.pl";
$method = "PUT"; #ユーザーに PUT で送信させる
if(open(FILE,$template_html)){
# テンプレート・ファイルがあるので読み込む
$temp_html = <FILE>;
}else{
#テンプレート・ファイルがないのでデフォルトの HTML を用意
$temp_html = <<"-----EOF-----";
<HTML><HEAD><TITLE>Join</TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF">
<H1>登録フォーム</H1><HR>
__INSERT_FORM_HERE__
</BODY></HTML>
-----EOF----}
&jcode'convert(*temp_html,'jis'); #JIS に変換
# <FORM>∼</FORM>部分を埋め込む
$temp_html =~ s/__INSERT_FORM_HERE__/&print_form/eg;
# HTML を出力
print "Content-Type: text/html¥n¥n";
print $temp_html;
sub print_form{
#テンプレート・ファイルをオープンする。
20
open(TEMP,$template_dat)
|| return "<STRONG>No template</STRONG>";
# HTML を生成する
$return = <<"-----EOF-----";
<FORM METHOD=$method ACTION="./submit.cgi">
<!-- テンプレート番号の指定を HIDDEN 属性で行う -->
<INPUT TYPE=HIDDEN NAME="template" VALUE="$template">
<DL>
-----EOF----while(<TEMP>){
chop;
&jcode'convert(*_,'euc');
$return .= &input_tags(split(/,/));
}
$return .= <<"-----EOF-----";
</DL>
<INPUT TYPE="SUBMIT" VALUE="送信(submit)">
<INPUT TYPE="RESET" VALUE="クリア(clear)">
</FORM>
-----EOF----close(TEMP);
&jcode'convert(*return,'jis'); # jis に変換す
$return; #作成した HTML を返す
}
sub input_tags{
local($tag,$type,$name,$option,$method,$value) = @_;
local($return,$select_tag,$select_value);
# NAME と VALUE 属性は " で囲むので、取り除いておく
$name =~ s/"//g;
$value =~ s/"//g;
# オプションの頭に空白をつけておく
$option = " $option" if $option;
# 項目名を戻り値に加える
$return = "<DT>$tag¥n<DD>";
if
(/radio/i | /checkbox/i){
# ラジオボタンやチェックボックスの場合
21
foreach(split(/&/,$value)){
($select_tag,$select_value) = split(/=/);
$return
.=
qq!<INPUT
TYPE=$type
NAME="$name"
VALUE="$select_value">!;
$return .= qq!$select_tag<BR>!;
}
}elsif(/select/i){
# セレクトの場合
$return .= qq!<SELECT NAME="$name"$option>!;
foreach(split(/&/,$value)){
$return .= "<OPTION>$_¥n";
}
$return .= qq!</SELECT>!;
}elsif(/textarea/i){
# テキストエリアの場合
$return
.=
qq!<TEXTAREA
NAME="$name"$option>$value</TEXTAREA>¥n!;
}else{
# テキストやパスワード、その他の無効なタイプの場合
$return
.=
qq!<INPUT
VALUE="$value"$option>¥n!;
}
$return;
}
サンプルプログラム
submit.cgi
#!/usr/local/bin/perl
require "./jcode.pl";
require "./init.pl";
# テンプレート・ファイルをオープン
open(TEMP,$template_dat)||&error("No template");
22
TYPE=$type
NAME="$name"
while(<TEMP>){
chop;
# [email protected] に格納
push(@keys,(split(/,/))[2]);
}
close(TEMP);
# テンプレートの順番に項目を処理する
foreach(@keys){
# 項目の値を得る
$value = $param{$_};
# カンマはフィールドの区切りに使うので、ピリオドに置換する
$value =~ s/,/./g;
# 同様に改行を<BR>タグに置き換える
$value =~ s/¥r?¥n/<BR>/g;
push(@values,$value); # [email protected] に格納する
}
open(LOG,">>$log_dat") || &error("Can't open log.dat");
flock(2,LOG);
# カンマ区切りでデータを出力
print LOG join(",",@values);
print LOG "¥n";
flock(8,LOG);
close(LOG);
# Thankyou メッセージを出力する
$tmp =
<<"-----EOF-----";
Content-Type: text/html
<HTML><HEAD><TITLE>Thank you!</TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF">
23
<H1>ありがとうございます</H1>
<HR>
<A HREF="$ENV{'HTTP_REFERER'}">戻る</A>
-----EOF----&jcode'convert(*tmp,'jis');
print $tmp;
Perl のパス
これは Perl インタープリタのパスを示すものです。このソースコードが書かれたファイ
ル自体は、そのままではテキストファイルに過ぎません。このソースコードを読みとって
実行する必要があります。その実行をしてくれるのが、Perl インタープリタです。そのイ
ンタープリタがサーバー内でどこにあるかを示しています。
このパスは多くのプロバイダでは、"/usr/bin/perl"か"/usr/local/bin/perl"ですが、
プロバイダによっては異なる場合があります。(プロバイダに確認する)そのような場合は、
変更してください。
これは必ず 1 行目に記述しなければなりません。この前に改行や空白が含まれていては
いけません。
× # !/usr/bin/perl
× !/usr/bin/perl
#と!の間にスペースが含まれてはいけない
最初に必ず#が必要となる。
変数の定義
設定値(変数)はシングルクォーテーションで囲みます。ダブルクォーテーションで囲む
と、変数が展開されてしまいまい、文字化けやエラーの原因となります。
$test = 'この中に設定値を書く';
シングルクォーテーションの外側は一切変更しないでください。シングルクォーテーシ
ョン自体を消したり、全角にしたり、外側にあるイコールやドルマーク、セミコロンを消
したりすると、一ヶ所だけでもエラーになります。誤って削除しないように注意してくだ
24
さい。シングルクォーテーションの中にシングルクォーテーションを含めたい場合、その
まま書けばエラーになります。そのような場合、中のシングルクォーテーションの前に円
マーク(バックスラッシュ)を付けて下さい。
$test = '掲示板の¥'テスト¥'です';
なお、数字だけで設定するものはシングルクォーテーションは要りません。
$test = 245;
コメント
1 行目を除いて、半角"#"以降、その行の終わりまでは、コメント(注釈)として無視され
ます。HTML でいう<!-- ∼ -->に相当します。通常の構文でも、行の頭に#を付けるとコメ
ントになり、無視されます。意図的に行の頭に#を付けて、コメントにして、実行時に無視
させることさせることをコメントアウトと言います。「だったら最初からその行を削除す
ればいいのでは?」と思うかもしれませんが、デバッグで一時的に無視した場合等で、コ
メントアウトした行を再び有効にしたい場合、#を外すだけでいいわけです。
#$test = 0;
変数 ($ではじまるもの、$test など)を定義する場合、必ず値を指定する必要があります。
値を指定しない場合は、コメントアウトして変数そのものを定義しないようにしてくださ
い。また、''とすることで、空の文字列を指定することもできます。
○ $test = '';
× $test = ;
パスとアドレスの設定
パスとはサーバー内での場所を相対パス(スクリプトがあるディレクトリを基準にする)、
絶対パス(ルートディレクトリ=最上段階層に位置するディレクトリを基準にする)を意
味します。スクリプトと同じディレクトリにある場合は、"./"もしくは無指定、1 つ上のデ
ィレクトリにある場合は、"../"です。このパスはアドレスとは違うものです。"http://∼
"では指定できません。
アドレス(URL)とは、インターネット全体から見た場所、"http://∼"で指定します。
25
PUT と GET
ここでは、CGI にアクセスする時のブラウザの挙動を解説します。実は、ブラウザ
から HTTP サーバーへのデータの受け渡し方法は大まかにわけて 2 つあり、それぞ
れ GET と PUT と呼ばれています。
CGI スクリプトを呼び出す HTML ファイルをエディタなどで見てみると、
<FORM ACTION="CGI スクリプト名" METHOD="GET">
などとなっているのを見かけると思います。ブラウザは、ここの「GET」の部分
で CGI スクリプトにデータを渡す方法を判断します。METHOD="方法"の部分は省略
可能ですが、HTML4.01 では、これを省略した場合は「GET」が指定されたものと
みなすような仕様になっています。
さて、それではそれぞれのデータの渡し方を見てみましょう。まずは GET です。
例えば、
<FORM ACTION="http://xxx.xxx.xxx.xxx/test.cgi" METHOD="GET">
名前<INPUT TYPE=TEXT NAME="name"><BR>
趣味<INPUT TYPE=TEXT NAME="hobby"><BR>
<INPUT TYPE=SUBMIT>
</FORM>
というフォームがあり、「名前」に「Tsuyoshi Ohhashi」、「趣味」に
「drinking」と書いて Submit ボタンを押すと、ブラウザから HTTP サーバーには
以下のようなリクエストが送られます。
GET /testprog.cgi?name=Tsuyoshi%20Ohhashi&hobby=drinking HTTP/1.1
Host: xxx.xxx.xxx.xxx
実は、GET の場合は単に INPUT 要素の NAME 属性で指定された値と、ユーザーが入力
した値を「=」でつないだ対を、さらに「&」文字で繋げて、CGI スクリプトの相
対 URL の後ろに「?」文字を補って指定しているだけなのです。この表記は、通常
のブラウザでは URL 欄にも現れるので、見覚えのある方もいるかと思います。
26
つまり、GET という方法は、今までの HTML ファイルの呼び出し方法と全く変わら
ないわけです。CGI スクリプトは、HTTP サーバーが自動的に「?」文字を探して
CGI スクリプトのファイル名を切り出して起動され、「?」以降を CGI スクリプト
に渡す仕様になっています。
この方法は、FORM 要素を使わなくても、<A HREF="a.cgi?neta=ganmo">のように
A 要素の HREF 属性に直接 CGI スクリプトに渡すデータを記述できるなどの長所があ
ります。逆に、URL の長さは RFC で制限されていますので、あまり巨大なデータは、
正しく渡されることが保証されない、という欠点も持っています。
では PUT はどうでしょうか? こちらは新しい概念が登場します。GET の例を見れば
想像がつくでしょうが、今度は GET の代わりに PUT という新しいコマンド(リクエ
スト・メソッド)を使うのです。HTML ファイルの中で、METHOD=PUT を指定すると、
ブラウザは以下のようなリクエストを HTTP サーバーに送ります。
PUT /testprog.cgi HTTP/1.1
Host: xxx.xxx.xxx.xxx
Content-Length: 37
name=Tsuyoshi%20Ohhashi&hobby=drinking
GET であれば、HTTP ヘッダの終了である空行をサーバーに送ればそれでブラウザ
からの命令は終了だったのですが、PUT の場合はさらに入力待ちになり、
Content-Length: ヘッダで指定された文字数分データを受け取るまでその状態が
続きます。
PUT は、URL の一部にデータを埋め込むという事をせず、HTTP ヘッダの後(=空行
より後。これを Body 部と呼びます)の部分にデータを入力させるので、データ長
に制限がないという長所があります。ただし逆に、いくらでも巨大なデータが受
け取れるため、メモリやハード/ディスク領域を浪費させるいたずらに留意する
必要がでてきます。
最近、フォト・アルバム CGI スクリプトなど、ファイルをアップロードさせるタ
イプの CGI スクリプトを良く見かけますが、これもこの PUT を使っているのです。
27
Sendmail を利用
今回の講座では扱いませんでしたが、投稿されたものをメールで配信したり、予約フォー
ムに入力された内容をメールで送ったりすることも可能です。これはには、CGIを動か
すサーバーで Sendmail(SMTPサーバー)が動いている必要があります。
CGI で使用される環境変数
WWW サーバーは、CGI プログラムに要求があると、適当な環境変数を設定してそのプログ
ラムを起動します。 CGI が設定する環境変数は、
http://hoohoo.ncsa.uiuc.edu/cgi/env.html にて記されています。
常に設定される環境変数
以下の環境変数は、リクエストによらず、全てのリクエストで設定されます。
SERVER_SOFTWARE
リクエストに応答(し、ゲートウェイとして動作)するサーバソフトウェアの名称
と改訂の情報。(参考: RFC2616 sec3.8)
SERVER_NAME
自己参照する URL 中に現れる、サーバーのホスト名、DNS エイリアス、IP アド
レスのいずれか。
GATEWAY_INTERFACE
このサーバーが従う CGI 仕様のバージョン。(例: CGI/1.1)
リクエストに応じて設定される環境変数
以下の環境変数は、リクエストによって特定され、ゲートウェイプログラムによって完成
されるでしょう。
SERVER_PROTOCOL
このリクエストと共に送られたプロトコルの名称と改訂の情報。
SERVER_PORT
リクエストが送られたポート番号。
REQUEST_METHOD
リクエストによって作成されたメソッド。(参考: RFC2616 sec5.1.1, sec9)
PATH_INFO
28
クライアントによって与えられる、特別なパス情報。言い換えれば、スクリプトは
仮想パス名と、その終端に特別な情報を付加したパスでアクセスされうる。特別な
情報は PATH_INFO として送信される。CGI スクリプト渡される前の URL が基
になっている場合、この情報はサーバーによってデコードされるべきである。
PATH_TRANSLATED
サーバーは PATH_INFO を、仮想パスから実際のパスへとマッピングする、解析
したバージョンを提供する。
SCRIPT_NAME
自己参照 URL のために実行され、使用されるスクリプトへの仮想パス。
QUERY_STRING
このスクリプトを参照する URL 中の ? 以下の情報。これがクエリ情報である。
これはいかなる方法によるデコードもされるべきではない。この変数はクエリ情報
がある場合は常に、それがコマンドラインデコーディングであるかに関わらず、セ
ットされるべきである。
REMOTE_HOST
リクエストを作成するホスト名。サーバーがこの情報を持ち合わせない場合、
REMOTE_ADDR をセットするか、セットしないままにすべきである。
REMOTE_ADDR
リクエストを作成するリモートホストの IP アドレス。
AUTH_TYPE
サーバーがユーザ認証をサポートし、スクリプトが保護される場合、これはユーザ
を確認するために使われるプロトコルによって特定される認証メソッド。(参考:
RFC2616 sec11)
REMOTE_USER
サーバーがユーザ認証をサポートし、スクリプトが保護される場合、認証されるユ
ーザ名。
REMOTE_IDENT
HTTP サーバーが RFC 931 識別をサポートする場合、この変数へはサーバーから
獲得されるリモートユーザ名がセットされるであろう。この変数の使用はログ取得
のみに制限されるべきである。
CONTENT_TYPE
HTTP POST や PUT のように、情報が付加されるクエリのために、これはデータ
の内容のタイプである。(参考: RFC2616 sec3.7, sec14.17)
CONTENT_LENGTH
クライアントによって与えられる前述の内容の長さ。(参考: RFC2616 sec14.13)
29
HTTP_ で始まる環境変数
これまでのものに加えて、クライアントから受信されるヘッダがあれば、ヘッダ名の前に
HTTP_ が追加された環境変数が作成されます。この時、ヘッダ名中のすべての - が _ に
変換されます。但し、Authorization, Content-Type, Content-Length のような、サーバ
ーによって既に処理されたヘッダや、その他のものもサーバーが望んだ全てのヘッダは除
外する事ができます。
以下の例は、CGI/1.0 中に定義された HTTP_ACCEPT 変数と User-Agent ヘッダから作成さ
れた環境変数です。
HTTP_ACCEPT
HTTP ヘッダによって与えられる、クライアントが受け入れるであろう MIME タ
イプ。他のプロトコルでは、他の所でこの情報を得る必要であるかもしれない。こ
のリスト中のそれぞれの項目は HTTP 仕様にて分けられる様にコンマによって分
けられるべきである。(参考: RFC2616 sec14.1)
HTTP_USER_AGENT
クライアントがリクエストを送るために使っているブラウザ。 (参考: RFC2616
sec14.43)
これらは標準の環境変数であり、これら以外にもサーバーごとに独自の環境変数をセット
する事が可能です。
CGI とセキュリティ
CGI スクリプト (以下 "スクリプト") は、セキュリティホールを産み出す原因となります。
スクリプトの作者は、サーバーと同じくらい注意を払いながら作成されなければいけませ
ん。十分に注意を払っていないスクリプトが利用された場合、システム内を探査されたり、
サーバログを読まれたり、パスワードファイルをメール送信されたり等、様々に悪用され
てしまう可能性があります。
スクリプト作成時に注意すべき点はいくつかありますが、特に重要なのは自分のサイトと
サーバホストについての情報をあまり多く渡さないことと、ユーザから入力される情報は、
必ずスクリプト内でチェックするの 2 点です。
30