1.指示子について
この章では UNIX系のOSでもっとも利用されている 『Apache』 ウェブサーバの設定方法を中心に、CGI を利用するための環境作りを解説します。
章の最後に Apacheのダウンロード場所や、インストール手順や設定方法のドキュメントのリンクを掲載しているので、まだ導入されていない方はこれを機会にぜひチャレンジしてみてください。
ウェブサーバとCGIの関係
ウェブサーバの主要な機能は、ブラウザがリクエストしたURLに該当するファイルを送信することです。リクエストがHTMLではなくCGIプログラムの場合は、プログラムの内容を表示する代わりにCGIプログラムを実行して、その出力を送信します。
ウェブサーバの設定は複雑な面もありますが、必要最低限の設定は実はそれほど多くありません。最初にHTMLファイルを表示できるように設定し、あとからCGIプログラムの起動やそのほかさまざまな機能を設定していくのも手です。
Apacheの設定は、httpd.confというテキスト形式の設定ファイルで行います。httpd.confファイルは指示子とコメントから構成されます。
- 指示子
- 指示子はウェブサーバの動作を指定するコマンドを設定します。
- コメント
- コメントは不要な指示子をコメントアウトしたり、注釈を記述するのに便利です。
指示子の記述方法
指示子は次のような形式になっています。
<指示子> 引数 引数
ウェブサーバのルートディレクトリの設定を例にすると、以下のような記述方法になります。指示子と引数の間はスペースかタブで区切ります。
ServerRoot /usr/local/apache
Apacheが自動作成するデフォルトの設定ファイルでは、指示子の頭文字が大文字で、それに小文字が続いていますが、これは見栄えを考慮したもので、実際には大文字・小文字の区別はありません。以下のどれでも正しく認識されます。
ServerRoot /usr/local/apache SERVERROOT /usr/local/apache serverroot /usr/local/apache
引数に空白文字が含まれている場合は、引数をダブルクォーテーション( " )の引用符で囲む必要があります。
BrowserMatch "RealPlayer 4\.0" force-response-1.0
コメント
指示子を削除したいときは、次のようにシャープ記号( # )でコメントアウトします。
# ServerRoot /usr/local/apache
コンテナ指示子
指示子には特殊な使い方があります。HTMLのタグのように前タグと終わりタグで指示子を囲むことができます。コンテナタグの中で設定した指示子は、Apache全体には影響されません。タグで指定したサーバ内のファイルやディレクトリだけに適用されます。
たとえば、任意のディレクトリのみに設定を行いたい場合、<Directory>タグを使って次のように設定します。
# CGIを実行させたいディレクトリ領域に、オプション「ExecCGI」を追加 <Directory "/home/httpd/cgi-bin"> Options Indexes FollowSymLinks ExecCGI AllowOverride None Order allow,deny Allow from all </Directory>
これで「cgi-bin」ディレクトリとそのサブディレクトリに設定が反映されます。
コンテナタグの中にさらにコンテナタグをネストすることができます。タグをネストする場合は、インデントを使って見栄えをよくしたほうがいいでしょう。
<VirtualHost 123.123.123.12> ServerName www.domain.co.jp DocumentRoot /home/httpd/ssl/ <Location /client> DirectoryIndex secound.html </Location> </VirtualHost>
2.標準的な設定
Apacheの設定は/usr/local/apache/conf (Redhat系:/etc/httpd/conf)という設定用ディレクトリの中のhttpd.confファイルで行います。特別な使い方やチューンナップをしなければ、以下の行を確認するだけで正常に動作します。
管理者のメールアドレス
ServerAdmin root@localhost
confやlogディレクトリを格納するディレクトリ
ServerRoot "/etc/httpd"
エラーログ・アクセスログの出力ファイル
ErrorLog logs/error_log TransferLog logs/access_log
DNSに登録されたサーバ名
ServerName www.example.com:80
HTMLファイルを置くルートディレクトリ
DocumentRoot "/var/www/html"
Apacheの設定用ディレクトリにはhttpd.conf以外にも、他の設定ファイルが用意されていることがあります。その中でsrm.conf、access.confはApacheの古いバージョン用ファイルで、最新のApacheには必要ありません。magicとmime.typeは、Apacheを実行するために編集することはめったにありません。
設定用ディレクトリには以下の設定ファイルが用意されている可能性があります。
- httpd.conf
- srm.conf
- access.conf
- mime.type
- magic
3.効果的なログファイルの出力
1.アクセスログを分割
アクセスログは、多くのデータを記録しますが、デフォルトの設定で要求先URLと閲覧ブラウザ名も保存しています。要求先URLは他サイトからのアクセスを調べる際、閲覧ブラウザ名はNetscapeやExplorerの使用率などを調べる際に効果的です。これらはアクセス数とは別に処理するほうがシンプルな方法です。
アクセスログをひとつのファイルに出力するのではなく、たとえば、アクセス数用のaccess_logファイル、要求先URL用のreferer_logファイル、閲覧したブラウザ名用のagent_logファイルに分割することもできます。
httpd.confの設定手順
- アクセスを記録するファイルの指定コマンドTransferLogをコメントアウト
- LogFormatを上記3つのファイル用に設定
- CustomLogにファイル名を設定
※LogFormatで設定したコマンドを指定することを忘れないように。
# TransferLog logs/access_log # ログファイルのフォーマットを設定 # LogFormat <format_string> <command> LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%{Referer}i -> %U" referer # agent_logがいらない場合などは思い切ってコメントアウト # LogFormat "%{User-agent}i" agent CustomLog access_log common CustomLog referer_log referer # agentコマンドをコメントアウトしていたら、忘れずにこちらもコメントアウトする # CustiomLog agent_log agent
2.GIF/JPGファイルを記録しない
GIFファイルやJPGファイルの呼び出し記録をログに記録するのはあまり効果的ではありません。通常はHTMLファイルのアクセス数を記録するだけで十分です。ここではGIF/JPGファイルの呼び出し記録をログに書き込まないように設定しています。
# 環境変数にGIF/JPGファイルを環境変数「object-is-image」に記録 SetEnvIf Request_URI "\.(gif)|(jpg)$" object-is-image # 環境変数object-is-imageに記録されたファイルを記録しないように指定 # CustomLog <directory> <command> <ENV> CustomLog access_log common env=!object-is-image CustomLog referer_log referer env=!object-is-image
4.CGIを実行可能に設定
AddHandlerの設定と、<Direcotry>のOptionsにExecCGIを追加すること。とりあえずこれで十分CGIが使えるようになります。まずは<Directory>タグの使い方を紹介しましょう。
<Directory ディレクトリパス>~</Directory>タグの説明:
<Directory>タグの中に、指定したディレクトリパスのアクセス権を設定する。主なオプションは以下のとおりです。
- Options None/All
指定されたディレクトリ内でアクセスに関する機能を禁止/許可 - Options Includes
SSIを許可 - Options ExecCGI
スクリプトの実行を許可
ServerName www.domain.co.jp ScriptAlias /cgi-bin/ "/home/httpd/html/cgi-bin" AccessConfig /dev/null ResourceConfig /dev/null AddHandler cgi-script .cgi # CGIを実行させたいディレクトリ領域に、ExecCGIオプションを追加 <Directory "/home/httpd/html"> Options Indexes FollowSymLinks ExecCGI AllowOverride None Order allow,deny Allow from all </Directory>
5.セキュリティの向上
FlollowSymLinks/FlollowSymLinksIfOwnerMatch
FollowSymLinksを無効にし、シンボリックリンクをたどれなくすること。そのかわり、SymLinksIfOwnerMatchを設定し、ファイルまたはディレクトリの所有者がシンボリックリンクと同一の場合だけ、リンクをたどれるようにしよう。
<Directory "/home/httpd/html">
# Options Indexes FollowSymLinks
ExecCGI
Options Indexes -FollowSymLinks
+SymLinksIfOwnerMatch ExecCGI
AllowOverride None
Order allow,deny
Allow from all
</Directory>
6.速度の向上
FlollowSymLinks/FlollowSymLinksIfOwnerMatch
セキュリティ向上させるため、FlollowSymLinksのかわりにFlollowSymLinksIfOwnerMatchを使かったよね。でもこれは、シンボリックリンクをチェックするために余分なシステム・コールが発生し、速度性が損なわれるんだ。速度を重視するか、セキュリティを重視するか、それが問題・・・なんだけど、とりあえずの折衷案があるよ。
方法はいたって簡単。必要な場所だけセキュリティチェックを行うようにすること。
<Directory />
Options FollowSymLinks
</Directory>
<Directory /home/httpd/html>
Options -FollowSymLinks +SymLinksIfOwnerMatch
</Directory>
こうすれば、少なくともDocumentRootパスの余分なチェックが要らなくなる。ドキュメント・ルート以外にAliasやRewriteRuleパスがある場合には、同様のセクションを追加する必要があるからお忘れなく。
AllowOverride
URL空間でoverridesを認める場合(通常は「.htaccess」)、Apacheは各ファイルネーム要素ごとに.htaccessを開こうとする。これじゃあ、パフォーマンスの低下は避けられないね。
解決策は、ルートパスでAllowOverride Noneを使うこと。
<Directory />
AllowOverride None
</Directory>
ネゴシエーション
最高の性能を絞り出したい場合には、コンテンツ・ネゴシエーションを極力避けたいところ。でも実践的には、ネゴシエーション機能には性能の低下を補ってあまりあるものがあるから、これは有効にしておこう。
せめて、「DirectoryIndex
index」の様なワイルドカードは使わずに、次のようにファイル名を明確にしてリストする。
DirectoryIndex index.html index.shtml
一番頻繁に使うオプションをリストの頭に持ってこよう。
プロセス
MaxRequestsPerChild命令は個々の子サーバプロセスが取り扱うリクエストの範囲を指定する。MaxRequestPerChild
が設定されると、その設定を超えた後の子プロセスは停止する。もしMaxRequestsPerChild
が0だと、そのプロセスは停止しない。この初期設定値は30になっているけど、子プロセスに肥大したメモリ・イメージを持たせるようなモジュールを使っているサーバでなければ、この値を10,000あたりまで上げてみよう。
そしてKeepAliveTimeoutを60秒以上にしないこと。
7.設定例
# httpd.conf 2002/05/10 # サーバの基本的な動作の設定 # standalone(サーバはメモリに常駐)/Inetd(アクセスごとにサーバを起動) ServerType standalone # Apacheが参照する各種ファイルの起点となるディレクトリパスを設定 # httpd.conf以外の設定ファイル、およびログファイルがServerRootを参照 ServerRoot "/usr/local/apache" # サーバのプロセス番号を記録するファイル名 PidFile /usr/local/apache/logs/httpd.pid # ロックファイルのファイル名 # ログディレクトリがNFSの場合、ログをローカルに保存するよう指定 # 上記以外はデフォルトのままで問題ない。 #LockFile /var/run/httpd.lock # タイムアウトを秒単位で設定 Timeout 300 # ポート番号を設定 Port 80< # ユーザ webuser、グループ webgroupでapacheを立ち上げます。 # webuserは、web専用のユーザとして作成してください。 User webuser Group webgroup # 管理者のメールアドレスを指定 ServerAdmin info@localhost # DNSに登録されたサーバ名を設定します。 ServerName www.localhost # HTMLファイルを置くルートディレクトリを指定 DocumentRoot "/home/httpd/html" <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory "/home/httpd/html"> Options Indexes -FollowSymLinks ExecCGI AllowOverride None Order allow,deny Allow from all </Directory> # ユーザのホームディレクトリを指定 UserDir public_html <Directory "/home/*/public_html"> Options Indexes ExecCGI AllowOverride None order deny,allow allow from all </Directory> # 要求されたURLにファイル名がない場合、デフォルトで表示されるファイル名 DirectoryIndex index.html # ディレクトリのアクセスコントロールファイル # ディレクトリにAccessFileNameで指定されたファイルが存在する場合、そのファイルの定義でaccess.confの定義を上書きします。 # AccessFileName .htaccess <Files ~ "^\.ht"> Order allow,deny Deny from all </Files> DefaultType text/plain # DNSの逆引き解決 # このディレクティブをonに設定した場合、逆引きで得られたホスト名をログに記録し、offではIPアドレスが書き込まれます。 (on/off) # on == DNSの逆引きを行う, off == DNSの逆引きを行わない HostnameLookups on # エラーを記録するファイルとそのディレクトリを指定 ErrorLog /usr/local/apache/logs/error_log # アクセスを記録するファイルとそのディレクトリを指定 # TransferLog logs/access_log # error_log に記録されたメッセージの数 LogLevel warn # ログファイルのフォーマット # フォーマット:CustomLog <directory> <command> LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%{Referer}i -> %U" referer LogFormat "%{User-agent}i" agent # .gif, .jpg の呼び出し記録をログに書き込まない SetEnvIf Request_URI "\.(gif)|(jpg)$" object-is-image CustomLog access_log common env=!object-is-image CustomLog referer_log referer env=!object-is-image CustomLog agent_log agent env=!object-is-image # 実行したいCGIディレクトリのエイリアスを指定 ScriptAlias /cgi-bin/ "/home/httpd/html/cgi-bin/" <Directory "/home/httpd/html/cgi-bin"> AllowOverride None Options None Order allow,deny Allow from all </Directory> # INDEX表示を行う際に、ReadmeNameで指定されたファイルが要求された場合、リストの終わりにその内容を追加します。HeaderNameで指定されたファイルが要求された場合、リストの前にそのファイルの内容を表示します。 ReadmeName README HeaderName HEADER # 指定した拡張子を持つファイルをファイルタイプに関連付ける AddType application/x-tar .tgz # 指定した拡張子を持つファイルをhandler-nameに関連付ける # 拡張子が.cgiのファイルは実行可能なCGIスクリプトとして扱われる AddHandler cgi-script .cgi AddType text/html .shtml AddHandler server-parsed .shtml