Apache 1

PHP は 別ページ にしました。

今は Apache 2 が出ています。

以下の内容は若干古いかもしれません。

はじめに

UNIX 版の Apache はたいていの Linux などのディストリビューションに入っているはずですが,ここではソースコードからコンパイルしてインストールする方法を解説します。

Apache プロジェクトのホームページはここですが, なるべく近いところから get しましょう。 RingServer/pub/net/apache/dist/httpd/ をお薦めします。

バージョン 1(apache_1.x.xx.tar.gz といったファイル名)とバージョン 2(httpd-2.x.xx.tar.gz といったファイル名)があります。 バージョン 2 は十分安定していますが,PHP と組み合わせる際にはまだバージョン 1 のほうがよさそうです。

セキュリティ上の問題でどんどんバージョンが上がっていますので,最新のものをお使いください。

インストール

あらかじめユーザ www,グループ www を作っておきます。 nobody で代用することも多いようですが,nobody 以外のほうがいいでしょう。 最近の Red Hat ではユーザ apache,グループ apache となっているそうです。 コンテンツも含め,すべてのファイル・ディレクトリは,ユーザ www が書き込めないようにしておきます。 コンテンツ(特に PHP や CGI)については,other から読めないようにしておけば,他のプロセスからソースを参照される危険が減ります。

まずソースを展開してコンパイルします。 後で PHP を使うために Dynamic Shared Object の設定 --enable-module=so をしておきます。

cd apache_1.3.29
OPTIM="-O2" ./configure --enable-module=so
make
make install

インストール場所は /usr/local/apache 以下になります。 場所を変えるには configure に --prefix=/usr/local/apache1326 のようなオプションを付けます。

suEXEC をオンにするには,さらに --enable-suexec --suexec-caller=www とします。 suEXEC とは CGI をその所有者の権限で動かす仕組みです。 通常 CGI は httpd.conf で設定するユーザ(以下の例では www)の権限で動き,CGI プログラムの setuid ビットを立てるとその所有者の権限で動くようになりますが,suEXEC をオンにすれば必ずその所有者の権限で動くようになります。 一般ユーザが勝手に www の権限で悪さをしないようにできます。 しかし,セキュリティチェックのため,従来動いていた CGI が動かなくなる可能性があります。 うちの大学のサーバでは suEXEC は使っていません。

httpd.conf の設定

次に,/usr/local/apache/conf にある httpd.conf を編集します。

まず

ServerType standalone

と書いてあるところは,一般にはこのままでかまいませんが,もし inetd で起動するなら

ServerType inetd

に直します。ごくまれにしかアクセスがない場合は inetd モードにしておけばいいでしょう。

PHP4 を使う場合,

LoadModule php4_module        libexec/libphp4.so
AddModule mod_php4.c

という行があるはずですが,これがもし

<IfDefine SSL>
</IfDefine>

に囲まれているようであれば SSL を使わないと PHP4 も使えないことになります。 この外側に移動しましょう。

もし一般ユーザでインストールすると

Port 8080

となってしまうはずですので,

Port 80

に直します。SSL を使う場合は

<IfDefine SSL>
Listen 80
Listen 443
</IfDefine>

のようにします。

また,

User nobody
Group nogroup  (または Group "#-1")

となっているところは,前にも書いたように,できれば www といったユーザ/グループを作って,

User www
Group www

とするほうがよいでしょう。

ServerAdmin は適当なメールアドレスにします。うちでは

ServerAdmin webmaster@matsusaka-u.ac.jp

として,webmaster を管理人の別名として登録しています。

ServerName はホスト名です。たとえば

ServerName www.matsusaka-u.ac.jp

とします。実験的に自分のマシンで動かすなら localhost でもかまいません。

<Directory "/usr/local/apache/htdocs">

の中の

    Options Indexes FollowSymLinks
    AllowOverride None

となっているところは,自由度を上げるためには

    Options All MultiViews
    AllowOverride All

にします(この最後の行は .htaccess を使えるようにする設定です)。

次の

    DirectoryIndex index.html

となっているところは,たとえば

    DirectoryIndex index.html index.htm index.php index.cgi index.pl

にすると,index.html 以外のファイル名でも省略できるので,便利です。 あるいは,MultiViews(ブラウザ側の設定で同じURLでも異なったバージョンを表示する機能)を生かすなら,これは

    DirectoryIndex index

のようにしておくといいでしょう。 ただしこれではブラウザの設定が *.html より *.gif を優先するようになっていれば index.gif というファイルが表示されてしまうことがあります。 また,MultiView を生かすためには,ユーザ www にディレクトリが読めるようにしておかなければなりません。 パーミッションが 711 等であれば MultiView は効きません。

MultiView が生きているなら,hoge.html と,圧縮した hoge.html.gz を置いておけば,hoge をアクセスしたときに,ブラウザが圧縮をサポートしていれば hoge.html.gz が送られます。 ただし次のものが生きていなければなりません。

<IfModule mod_mime.c>
    AddEncoding x-gzip gz
</IfModule>

*.bz2*.lzh のようなバイナリファイルなのにブラウザに表示されてしまうことを防ぐために

DefaultType text/plain

DefaultType application/octet-stream

にしておくといいかもしれません。

次の

CustomLog /usr/local/apache/logs/access_log common

はコメントアウトし,

CustomLog /usr/local/apache/logs/access_log combined

を生かしておけば,一つ前のページの URL と,ブラウザの銘柄がログに入ります。 つまり,どのページからリンクをたどって来たか,どんなブラウザを使っているかがわかるわけです。

IndexIgnore の行も諸刃の刃で,これのおかげで README.何々 というファイルが見つからなくて困ったことがありました。

次の

        LanguagePriority en da ...

は,もちろん

        LanguagePriority ja en da ...

にしておきます。

次の2行はPHPを使うならコメントを外します(もしなければ追加します)。

    #AddType application/x-httpd-php .php
    #AddType application/x-httpd-php-source .phps

CGIを使うなら,

    #AddHandler cgi-script .cgi

は,コメントを外して,ついでに Perl のために次のようにしておくと便利です。

    AddHandler cgi-script .cgi .pl

次の

    #AddType text/html .shtml
    #AddHandler server-parsed .shtml

も SSI(Server Side Includes)を許すなら頭の # を外しておきます(今は SSI は流行りませんが)。

次の

#<Location /server-status>

および

#<Location /server-info>

の部分は,サーバの状態を表示する機能を生かしたいなら,すべて # を外し,特に

#    Allow from .your_domain.com

*.matsusaka-u.ac.jp からのアクセスを許すなら

    Allow from .matsusaka-u.ac.jp

あるいは 127.*.*.* からのアクセスを許すなら

    Allow from 127

に変えます。 server-status は inetd モードでは使えません。

Ring Server のようにファイル名を一覧表示したい場合は,長いファイル名が途中で切れないように,IndexOptions FancyIndexing となっているところに NameWidth=* を追加します。

実行

inetd モードでない場合の起動,終了,再起動はそれぞれ次のようにします。

/usr/local/apache/bin/apachectl start
/usr/local/apache/bin/apachectl stop
/usr/local/apache/bin/apachectl restart

ただし,このときの環境が CGI にまで引き継がれてしまいますので,できるだけクリーンな環境で実行します。 具体的には su ではなく su - で root になったほうがいいでしょう。 その際,HOME=/root となり,CGI 等で支障が出ることがあります(permission denied 等)。 必要に応じて HOME=/tmp 等とする必要があります。

inetd モードの場合は,/etc/inetd.conf

www stream tcp nowait root /usr/local/apache/bin/httpd httpd

または tcpd を使っているなら

www stream tcp nowait root /usr/sbin/tcpd /usr/local/apache/bin/httpd

と書いて inetd を再起動します(killall -HUP inetd)。 tcpd 使用の場合は /etc/hosts.allow と /etc/hosts.deny で制御ができます。

留意点

Apache 1.3.* では AuthName の右側の文字列は " で囲まなければなりません。

Apache 1.3.* では <LIMIT GET POST>GETPOST 等は必ず大文字で書かなければならないようになりました。

例:

AuthName "Himitsu No Basho"
AuthType Basic
AuthUserFile /home/hogehoge/public_html/himitsu/.htpasswd
<LIMIT GET POST>
    require valid-user
</LIMIT>

オマケ

httpd.conf
#ErrorDocument 404 /cgi-bin/missing_handler.pl

のコメントを外すといろいろ遊べます。 うちではここを

ErrorDocument 404 /cgi-bin/missing.cgi

にして,missing.c という急拵えのプログラムを gcc missing.c -o missing.cgi でコンパイルして使っています。 これは卒業生などの転居先を表示するのにも使う予定です (今のところ卒業生の声を聞く仕組みがないのですが……)。

……と思いましたが,CGI より PHP のほうが便利なので,missing.php にしてしまいました。

転居先表示(と,もしかしたら Refresh による転送)は, ちゃんと会議にかけると申込書に印鑑を押して1年間に限り……などとややこしいことになりそうなので, 私の個人サービスとして始めることにしました(メール転送もそうすりゃよかった)。 しかしまだ申込はありませんね。

ログの回転

Red Hat ベースの Linux なら /etc/logrotate.d の中に apache という名前で次のようなファイルを作っておくと自動的にログが回転します。 /etc/logrotate.conf に直接書いてもかまいません。

/usr/local/apache/logs/access_log {
    missingok
    postrotate
        /usr/bin/killall -HUP httpd 2> /dev/null
    endscript
}

/usr/local/apache/logs/error_log {
    missingok
    postrotate
        /usr/bin/killall -HUP httpd 2> /dev/null
    endscript
}

補遺

Apache 1.3.12 文字化け問題 をぜひご覧ください。

mod_perl

tar xvzf mod_perl-1.26.tar.gz
cd mod_perl-1.26
perl Makefile.PL
make
make test (optional)  
make install

mod_gzip

クライアントが Accept-Encoding: (x-)gzip というヘッダを送った場合に圧縮した内容を返す。 これは通常の Web ブラウザが対応しているほか,次のように wget でも試すことができる。

wget -S --header="Accept-Encoding: gzip" http://www.matsusaka-u.ac.jp/

mod_gzip のページからソースをダウンロード(コンパイル済みのものも置いてある)。 以下は mod_gzip-1.3.26.1a についての記述である。

あらかじめ /usr/local/bin/perl5 で Perl が動くようにしておく(あるいは /usr/local/apache/bin/apxs の先頭を書き直す)。

mod_gzip ソースを展開し,Makefile の先頭の APXS のパスを直す:

APXS=/usr/local/apache/bin/apxs

あとは make,make install。

httpd.conf に次の行が自動挿入される。

LoadModule gzip_module        libexec/mod_gzip.so

httpd.conf にはたとえば次のように書いておく(ソースツリーの docs/mod_gzip.conf.sample 参照)。

<IfModule mod_gzip.c>
  mod_gzip_on Yes
  mod_gzip_can_negotiate Yes
  mod_gzip_static_suffix .gz
  AddEncoding gzip .gz
  mod_gzip_update_static No
  mod_gzip_command_version      '/mod_gzip_status'
  mod_gzip_keep_workfiles       No
  mod_gzip_minimum_file_size    500
  mod_gzip_maximum_file_size    500000
  mod_gzip_maximum_inmem_size   60000
  mod_gzip_min_http             1000
  mod_gzip_handle_methods GET POST 
  mod_gzip_item_exclude         reqheader  "User-agent: Mozilla/4.0[678]"
  mod_gzip_item_include         file       \.html$
  mod_gzip_item_include         file       \.htm$
  mod_gzip_item_exclude         file       \.js$
  mod_gzip_item_exclude         file       \.css$
  mod_gzip_item_exclude         file       \.ram$
  mod_gzip_item_exclude         file       \.rm$
  mod_gzip_item_include         file       \.php$
  mod_gzip_item_include         file       \.pl$
  mod_gzip_item_include         handler    ^cgi-script$
  mod_gzip_item_include         mime       ^text/html$
  mod_gzip_item_include         mime       ^text/plain$
  mod_gzip_item_include         mime       ^application/x-httpd-php
  mod_gzip_item_include         mime       ^httpd/unix-directory$
  mod_gzip_item_exclude         mime       ^image/
  mod_gzip_dechunk              Yes
  mod_gzip_add_header_count     Yes
  mod_gzip_send_vary On
  mod_gzip_temp_dir /var/tmp
</IfModule>

Vary: ヘッダを返すところがミソである(mod_gzip_send_vary On)。 これにより,squid-1.2.beta21 (1998) 以降,DeleGate 7.6.0 (011016) 以降ではキャッシュしない。 squid-2.5 (2002) 以降ではさらに賢くなり,Vary: は content negotiation を考慮してキャッシュ内容を返す。

トラブル

ときどき「ホームページに入れない」(正しく表示されない/ダウンロードのダイアログボックスが出る)という話を聞く。 原因としては次のことが考えられそうである。

IE6(SP1 以前)のバグ

Internet Explorer 6(Service Pack 1 以前)で Real Player Basic(に含まれる Real Download)のようなダウンロードマネージャがインストールされたときに発生する問題(マイクロソフト サポート技術情報 - 312496 [IE] HTTP 圧縮を使用している Web サーバーから返送されたデータの最初の 2,048 バイトが Internet Explorer で失われる)。 Internet Explorer 6 Service Pack 1 以降に更新することで修正される。

Netscape 4.0 のバグ

Netscape 4.06〜4.08 はサーバに対して「圧縮対応」と宣伝するが実際は正しく扱えない。 新しい mod_gzip ではこれらに対しては圧縮しないで送る。

プロキシのバグ

Content negotiation を使ってブラウザごとに最適な内容を送ることと,プロキシでキャッシュすることとは,相容れないことが多い。 腐ったプロキシサーバが下手にキャッシュを返してしまうと,ブラウザが対応していない形式だったり,古い内容だったりすることになる。 Squid 1.2.beta21 (1998) 以降, DeleGate 7.6.0 (2001) 以降等を正しく設定して使えば問題ない。 不具合が起こる場合は,ネットワーク管理者に遠慮なく文句を言おう。


奥村晴彦

Last modified: 2004-03-30 12:56:57