コンテンツにスキップ

Webサーバ構築

Apacheを用いてWebサーバを構築します。Apacheのインストールはソースから行います。プログラムをソースからインストールすることの利点、欠点を考えます。Webサーバが提供するサービスは馴染みが深いので、サーバを構築した達成感が得られると思います。

  • Webサーバの説明
  • ソースインストールの説明
  • Apacheのコンパイルオプションについて
  • Apacheのインストール
  • 動作確認

WebサーバとはWebの機能を提供するサーバのことです。Webについては、みなさんも普段から使っているので、だいたいの内容はわかっていると思います。しかし、Webサーバがどのように機能しているか理解している人は少ないのではないでしょうか。とりあえず押さえておくべき基本的なWebサーバの動作は次の二つです。

+クライアント(Webブラウザなど)から要求されたファイルをそのままクライアントに返す
+クライアントから要求されたプログラムを実行し、その結果をクライアントに返す

上から説明します。Webサーバは、わたしたちが見るWebページをファイルとして保存しています。WebブラウザはWebサーバにそれらのファイルを要求します。要求を受け取ったWebサーバはファイルをクライアントに返します。ブラウザはそのファイルを解釈し、わたしたちが見やすいように表示します。例えば、Webブラウザのアドレスバーにhttp://cis.k.hosei.ac.jp/index.html**と入力しエンターキーを押すと、Webブラウザに法政大学情報科学部のWebページが表示されます。このときの流れは次のようになります。
+WebブラウザはWebサーバ
cis.k.hosei.ac.jp**にindex.htmlというファイルを要求する。
+Webサーバはその要求に答え、index.htmlをクライアントに返す。
+Webブラウザはindex.htmlを表示する。

また、Webには掲示板のような動的なコンテンツがあります。このようなページでは、サーバ上のファイルをそのまま返すという動作だけでは上手く機能しません(掲示板なのに書き込めない!)。動的なページを実現するために、もうひとつの基本的な動作「クライアントから要求されたプログラムを実行し、その結果をクライアントに返す」が使われます。Webサイトを作ったことがある人は、CGI(Common Gateway Interface)という言葉を聴いたことがあるかもしれません。プログラムはCGIを通して実行されます。また、その実行されるプログラムをCGIプログラムと呼び、拡張子は.cgiです。http://www.example.com/bbs.cgi**にアクセスした場合、基本的な動作の流れは次のようになります。
+WebブラウザはWebサーバ
www.example.com**にbbs.cgiというファイルを要求する。
+Webサーバはその要求がCGIであることを確認し、bbs.cgiを実行する。
+Webサーバはその実行結果をクライアントに返す。
+Webブラウザは実行結果を表示する。

今回構築するWebサーバにはApacheを使用します。Apacheはアパッチと読みます。現在、世界で最も使われているWebサーバで、Apacheライセンスに基づいてフリーで公開されています。

Apacheの特徴には以下のようなものがあります。

  • 低コスト
  • 安定した品質
  • 高いレスポンス性能
  • モジュールによる機能の拡張

この中でいまいち意味が掴めないのは、最後の「モジュールによる機能の拡張」だと思います。

Apacheは機能がモジュール化されたWebサーバです。新しい機能が必要な時は、その機能を実現するモジュールを動的共有オブジェクト(DSO)としてコンパイルします。すると、サーバの起動時、または再起動時にそのモジュールをロードして、サーバの機能として付け加えることができます。この利点はApacheを再ビルドすることなく機能を拡張できることです。

httpdとはWebサーバの機能を実現するデーモンです(デーモンとはシステムのバックグラウンドで動作し、システムの機能を実現したり、サービスを提供したりするプログラムです)。Apacheは代表的なhttpdです。また、HTTP(HyperText Transfer Protocol)とはWebサーバとWebクライアント間でやりとりするときに使用されるプロトコルです。通常サーバ側のポート番号は80番です。

パッケージインストールとソースインスール

Section titled “パッケージインストールとソースインスール”

ソフトウェアのインストール方法には大きく分けてふたつあります。ひとつは、RPMやyumを用いてコンパイル済みのバイナリパッケージをインストールする方法です。もうひとつの方法では、ソースコードを自分でコンパイルしてバイナリファイルを作成し、それをインストールします。

パッケージインストールをする利点は、簡単なことです。例えば、RPMを使ってインストールする場合は次のようにコマンドを打つだけです。

rpm -i (インストールしたいパッケージ)

インストールされているパッケージの情報はデータベースに保存されているので、管理も容易です。
また、インストールするパッケージが他のパッケージを必要とする場合、そのパッケージも一緒にインストールしてくれるパッケージマネージャもあります。

逆に欠点としては、コンパイルされたバイナリが自分の環境に合わないことがあります。特にApacheのようにコンパイルオプションが多いソフトウェアではそれが顕著に現れます。さらに、バイナリコードはマシンに最適化されていません。RPMパッケージのファイル名にi386と書いてあることに気付いた人もいると思いますが、RPMパッケージをインストールする場合、i386版をインストールします。i386とはIntelが20年近く前に出したプロセッサ386を意味します。Pentium4はこの386と互換性があるので、386用のプログラムも実行することはできます。しかし、Pentium4用に最適化されたプログラムにくらべて実行速度は落ちます。また、すべてのソフトウェアがパッケージ化されているわけではないのに注意しましょう。最新バージョンのソフトウェアも直ぐにパッケージ化されるとは限りません。そのようなソフトウェアをインストールしたい時にはソースからインストールせざるをえません。

(正確に言うと、パッケージインストールにもバイナリではなくソースからインストールするものがあります。有名なのはFreeBSDのportsとGentoo LinuxのPortageシステムです。また、RPMにもSRPMというソースからインストールするパッケージがあります。)

ソースインストールの利点は、プログラムを自分の環境に合わせることができる点です。これはパッケージインストールの欠点を見事にカバーしています。

欠点は面倒くさいところでしょう。コンパイルオプションを調べたり、プログラムの依存性を調べなくてはいけません。インストールした後も自分でしっかりと管理する必要があります。ソースからインストールしたプログラムのアップデートやアンインストールは手動でやらなければいけません。

以上をまとめて表にしておきます。

パッケージソース
管理簡単大変
機能不十分なプログラムもある自分で設定可能
最適化期待できない自分で設定可能
制限パッケージ化されていないプログラムがある基本的にはない
時間かからないかかる
  • Apacheのソースコードのダウンロード
  • コンパイル、インストール時のオプションの設定
  • ソースコードのコンパイル
  • Apacheのインストール
  • 設定ファイルと起動スクリプトの編集
  • ファイアウォールの設定
  • 動作確認

Webサーバを構築した後に動作確認をやります。今回は、動作確認をノートパソコンのWebブラウザ(IEなど)を用いてやることにしました。そのためには、SSHのポートフォワーディング機能を使う必要があるため、PuTTYの設定を少し変える必要があります。(こんな面倒くさいことをする理由を知りたい人は、前回のSSHサーバ構築の記事を読めばわかるかもしれません。)

PuTTY1.png

  • 踏み台サーバ(step.cis.k.hosei.ac.jp)の設定を読み込みます。

PuTTY2.png

  • 左のカテゴリからトンネルを選びます。源ポートに10080を、送り先に自分のサーバマシンのIPアドレス:80を設定します。(IPアドレスは192.168.1.1xxのxxをマシン番号に変えたものです)

PuTTY3.png

  • 追加をクリックすると上図のようになります。なりましたら設定を保存します。(左のカテゴリでセッションを選ぶと、右側に保存というボタンが現れます)

以下、作業は自分のサーバマシンにSSHでログインして行います。ログインの仕方等を忘れてしまった人は前回のSSHサーバ構築の記事を参照してください。

Apacheがインストールされていないか確認

Section titled “Apacheがインストールされていないか確認”

Linuxをインストールしたときに、Apacheがインストールされていないかどうかチェックします。チェックするために下のコマンドを実行します。

yum list httpd

これを実行して下のように表示された場合、Apacheはインストールされていません。次のソースコードのダウンロードに進んでください。

Looking in Available Packages:
Name Arch Version Repo
--------------------------------------------------------------------------------
httpd i386 2.0.50-2.1 updates-released
Looking in Installed Packages:
Name Arch Version Repo
--------------------------------------------------------------------------------

下のように表示された場合、Apacheがインストールされていますので、まずはそれをアンインストールします。

Looking in Available Packages:
Name Arch Version Repo
-------------------------------------------------------------------------------
Looking in Installed Packages:
Name Arch Version Repo
-------------------------------------------------------------------------------
httpd i386 2.0.50-2.1 db

Apacheのアンインストールは次のようにします。rootで作業する必要があるので、su -を実行してrootになります。

su -
yum remove httpd

この後は一般ユーザで作業するので、一般ユーザに戻ります。

exit

Apacheの最新版のソースコードをダウンロードします。ソースコードはhttp://httpd.apache.org/download.cgiからダウンロードできます。ダウンロードをするときは物理的に近い場所にあるミラーサイトからにしましょう。学内でなら、http://storage.cis.k.hosei.ac.jp/のミラーからダウンロードできます。

wget http://storage.cis.k.hosei.ac.jp/pub/apache/httpd/httpd-2.0.50.tar.gz

ダウンロードしたソースコードはtar.gzという形式で圧縮されているので、それを解凍します。

tar zxvf httpd-2.0.50.tar.gz

カレントディレクトリにhttpd-2.0.50というディレクトリがあらわれます。ここに解凍されたソースコードが入っています。

cd httpd-2.0.50

httpd-2.0.50の中をlsで見てみましょう。

ls
ABOUT_APACHE LAYOUT README.platforms config.layout libhttpd.dsp
Apache.dsp LICENSE VERSIONING configure modules
Apache.dsw Makefile.in acconfig.h configure.in os
BuildBin.dsp Makefile.win acinclude.m4 docs server
CHANGES NOTICE apachenw.mcp.zip emacs-style srclib
INSTALL NWGNUmakefile build httpd.spec support
InstallBin.dsp README buildconf include test

READMEというファイルがあることに気付くと思います。READMEファイルがある場合、まずはそれに目を通すのが基本です。

less README

READMEを読むと、インストール方法はINSTALLファイルに書いてあるとあります。これにも目を通します

less INSTALL

ちゃんとしたインストールドキュメントの場所が書いてあります。また、せっかちな人のためのインストール方法が書かれています。本来はインストールドキュメントをしっかり読むべきなのですが、今回は割愛します。

configureを用いて、コンパイルオプションとインストールオプションを設定します。設定の仕方は./configureを実行する時にコマンドの引数としてオプションを与えます。./configureに—helpオプションを与えると、どのようなオプションがあるかを表示します。

./configure --help

なんかすごい速さで表示されました。これでは普通の人は全部見れませんね。このようなときは次のようにします。

./configure --help | less

どのようなオプションがあるかは分りましたが、個々のオプションの説明が簡単すぎてよく分りません。こういう場合、より詳しいインストールドキュメントを読むと良いでしょう。

今回はこっちで勝手にオプションを指定します。

"./configure" \
"--prefix=/usr/local/httpd" \
"--enable-layout=Apache" \
"--with-mpm=prefork" \
"--enable-modules-shared=all" \
"--enable-so" \
"--enable-deflate" \
"--enable-proxy" \
"--enable-suexec" \
"--with-suexec-caller=httpd" \
"--with-suexec-logfile=/var/log/httpd/suexec_log" \
"--with-suexec-docroot=/home" \
"--disable-asis" \
"--disable-auth_anon" \
"--disable-auth_dbm" \
"--disable-dav" \
"--disable-dav-fs" \
"--disable-imap" \
"--disable-status"

このような長ったらしいのは直接打つのではなく、コピペでやりましょう(上のコマンドとオプションをコピーして、PuTTYに右クリックでペーストします)。

configureの実体はディレクトリhttpd-2.0.50内にあるスクリプトファイルです。そのため、実行する時に./を頭につけます。

:—prefix=/usr/local/httpd:全体のインストール先を/usr/local/httpdにします。

:—enable-layout=Apache:インストールパスを指定するためのレイアウトを使用します。使用できるレイアウトはconfig.layoutファイルにあるものです。またconfig.layoutにはどのようにインストールされるかの詳細が書いてあります。

:—with-mpm=prefork:preforkというマルチプロセッシングモジュール(MPM)を有効にする。MPMは他にworkerなどがあります。詳しくはhttp://httpd.apache.org/docs-2.0/mpm.htmlを参照してください。

:—enable-modules-shared=all:全てのモジュールをダイナミックロードできる形(DSO)でコンパイルとインクルードします。このあとに—disable-”MODULE”として指定したモジュールは取り除くことができます。allのほかにmostやモジュール名を=の後に置く事ができます。

:—enable-”MODULE”:MODULEモジュールをコンパイルして、インクルードします。モジュールをDSOとしてコンパイルする場合はモジュール名の後に=sharedオプションを指定します。

:—with-suexec-xxx:suEXECの設定オプションです。suEXECについては後で説明します。

:—disable-”MODULE”:コンパイルされてインストールされるモジュールを取り除きます。

個々のモジュールの説明はhttp://httpd.apache.org/docs-2.0/mod/を参照して下さい。

configureが終了したら、次はコンパイルです。コンパイルするにはmakeコマンドを実行します。

make

コンパイルが終ったら、作成されたプログラムをインストールします。インストールはrootで行います。

su -
cd /home/(ユーザ名)/httpd-2.0.50
make install

たとえば、一般ユーザの名前がhogeなら下のようになります。

su -
cd /home/hoge/httpd-2.0.50
chown -R root:root .
make install

これで、インストール作業は終了です。次は設定です。

これより後はrootで作業します。

Apacheをインストールしたディレクトリ/usr/local/httpdのしたにconfというディレクトリがあります。そこにApacheの設定ファイルhttpd.confがあります。それを自分の環境に合うように設定します。httpd.confで設定する個々の項目のことをディレクティブといいます。今回変更するディレクティブは、以下のとおりです。

  • Userディレクティブ
  • Groupディレクティブ
  • ServerAdminディレクティブ
  • ServerNameディレクティブ
  • ErrorLogディレクティブ
  • CustomLogディレクティブ

httpd.confを書き換えるので、何かあったときのために初期設定を保存しておきます。

cp /usr/local/httpd/conf/httpd.conf /usr/local/httpd/conf/httpd.conf.default

以下の作業はviでhttpd.confを開いた状態で行います。

vi /usr/local/httpd/conf/httpd.conf

Userディレクティブでは、サーバがリクエストに応答する際に利用されるユーザIDを指定します。今回はhttpdというユーザを新たに作成し、それをUserディレクティブに設定します。Userディレクティブはデフォルトではnobodyになっているので、httpdに書き換えます。

User nobody
User httpd

Groupディレクティブでは、リクエストに応答される際に所属するグループを指定します。今回はhttpdグループです。Groupディレクティブはデフォルトでは#-1になっています。

Group #-1
Group httpd

ServerAdminディレクティブでは、クライアントに返すエラーメッセージに載せるe-mailアドレスを指定します。自分のメールアドレス(大学のメールアドレス)を書いておきましょう。

ServerAdmin you@example.com
ServerAdmin 自分のメールアドレス

ServerNameディレクティブではホストネームとポートを指定します。これはサーバが自分自身を認識するのに使われます。今回はホストネームは自分のIPアドレスです。ServerNameディレクティブは290行目付近にあります。コメントがついていますので外してください。

#ServerName www.example.com:80
ServerName 192.168.1.1xx:80

エラーログを保存するファイルを指定します。多くのサービスはログを通常/var/log以下に保存するので、それに習い/var/log/httpdというディレクトリの下にApacheのログを保存します。エラーログは/var/log/httpd/error_logに保存するように設定します。

ErrorLog logs/error_log
ErrorLog /var/log/httpd/error_log

サーバーへのリクエストのログを保存するファイルとログのフォーマットを指定します。CustomLogディレクティブは500行目あたりにあります。/var/log/httpd/access_logに保存するようにします。またログのフォーマットはcommonです。CustomLogはいくつかありますが、コメントアウトされていない(#で始まらない行)もののうち、末尾がcommonとなっているものを編集してください。

CustomLog logs/access_log common
CustomLog /var/log/httpd/access_log common

これでhttpd.confの編集は終了です。変更を保存し、viを終了してください。個々のディレクティブの詳しい説明はhttp://httpd.apache.org/docs-2.0/mod/quickreference.htmlを参照してください。

デーモンの設定ファイルは/etc以下に置かれるのが普通ですので、/etc/httpdの下にhttpd.confを置くことにします。また、/usr/local/httpd/confに/etc/httpd/httpd.confのシンボリックリンクを貼っておきます。

mkdir /etc/httpd
mv /usr/local/httpd/conf/httpd.conf /etc/httpd
cd /usr/local/httpd/conf
ln -s /etc/httpd/httpd.conf httpd.conf
groupadd -g 300 httpd
useradd -g 300 -u 300 -c "Apache Daemon User" -M httpd

ログを保存するディレクトリの作成

Section titled “ログを保存するディレクトリの作成”
mkdir /var/log/httpd
chown httpd: /var/log/httpd
/usr/local/httpd/bin/apachectl -t

これを実行して

Syntax OK

と表示されればOKです。何かエラーが表示された場合は、httpd.confの設定が間違ってると思われます。

iptablesを編集して、TCPポート80番を開けます。-A INPUT -p tcp -m tcp —dport 22 -j ACCEPTの下に**-A INPUT -p tcp -m tcp —dport 80 -j ACCEPT**を加えます。

vi /etc/sysconfig/iptables
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp --icmp-type any -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT (←この行を追加)
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
/etc/init.d/iptables restart

Apacheを起動します。

/usr/local/httpd/bin/apachectl start

ノートパソコンのWebブラウザで次のアドレスのページを表示させます。

http://localhost:10080/

「あなたの予想に反して、このページが見えているでしょうか?」という文が表示されたでしょうか。表示されたら、次はCGIの動作チェックです。不幸にも表示されなかった人は、ログやIEのメッセージを頼りに間違えた場所を特定します。Apacheのログは/var/log/httpd以下にあります。

以下はIEに表示されるエラーメッセージごとの対処方法です。

iptablesの設定が間違っている可能性があります。この場合、httpdにリクエストが届く前にパケットが殺されているので、Apacheのログには残りません。

404エラーです。アドレスが間違っている、もしくはファイルが存在していない可能性が高いです。

許可のないファイルにアクセスしています。この場合、Apacheのerror_log(/var/log/httpd/error_log)にエラーログが残ります。パーミッションがhttpdがアクセスできるようになっているか確認して下さい。

ログを見るには次のコマンドが便利だと思います。

tail -5 /var/log/httpd/access_log

tailはファイルの終わりの部分を表示します。今回はオプションで-5を渡しているので終わりの5行を表示します。新しいログはファイルの後ろに追加されるので、tail -5は最新の5つを表示することになります。

以下のエラーログはあくまで一例です。実際には環境等によってエラーメッセージは変わりますし、もしかしたら全く新しいエラーログが出ているかもしれません。そのような場合でもエラーメッセージをよく読み、何がエラーの原因なのか自分で考えるようにしましょう。

tail -5 /var/log/httpd/error_log
[Sat Jul 24 19:44:14 2004] [error] [client 192.168.1.2] (13)Permission denied: access to /~you/cgi-bin/index.cgi denied

このエラーの場合、you、cgi-binディレクトリまたはindex.cgiのうちのどれかがhttpdからアクセスできないようになっています。これらのパーミッションを調べてみてください。ここでのyou、cgi-bin、index.cgiなどは環境によって変わります。重要なのは**(13)Permission denied: access to**というエラーメッセージが多くの場合パーミッション設定のミスによって現れるということです。

[Sat Jul 24 19:46:47 2004] [error] [client 192.168.1.2] Premature end of script headers: test.cgi, referer: http://192.168.1.50/~you/cgi-bin/

これはtest.cgiが関わっているエラーです。また/~you/cgi-binにも問題がありそうです。CGIによって起こされるエラーなのでsuEXECにも何か関係がありそうです。suEXECのログを見てみます。

tail -5 suexec_log

すると、下のようなエラーメッセージがありました。

[2004-07-24 19:46:47]: directory is writable by others: (/home/you/public_html/cgi-bin)

どうやらcgi-binディレクトリが第3者によって書き換えられるようになっているのためにエラーが起こったみたいです。cgi-binのパーミッションを変更して、他ユーザが書き換えできないようにしましょう。

[Sat Jul 24 19:49:02 2004] [error] [client 192.168.1.2] Premature end of script headers: test.cgi

これはtest.cgiというCGIプログラムによって起きたエラーです。この場合、実際のエラーはsuEXEXCによって起こされている可能性がありますので、suEXECのログを見てみましょう。

tail -5 suexec_log
[2004-07-24 19:49:02]: file is writable by others: (/home/you/public_html/cgi-bin/test.cgi)

このようなログがあった場合、CGIプログラムのパーミッションでそのプログラムの持ち主以外がそのプログラムへの書き込み権を持っていると考えられます。suEXECはそのような状態を許していません。パーミッションを持ち主以外は書き込めないように変更しましょう。
また、次のようなログがsuexec_logにあるかもしれません。

[2004-07-24 19:55:28]: target uid/gid (500/500) mismatch with directory (500/500) or program (500/300)

このエラーはCGIプログラムのユーザIDまたはグループID、もしくはそのプルグラムが置いてあるディレクトリのユーザIDまたはグループIDがsuEXECのターゲット(普通はそのページの管理者)のユーザID、グループIDと異なるために発生します。ユーザIDとグループIDを適切なものに設定しましょう。(このエラーログの例の場合、CGIプログラムのグループIDが300になっているのがおかしいです)

CGIプログラムは/usr/local/httpd/cgi-binディレクトリに置きます。今回、テスト用に簡単なCGIプログラムを作成します。

vi /usr/local/httpd/cgi-bin/test.cgi
#!/usr/bin/perl
print "Content-type: text/plain\n\n";
print "$_\t$ENV{$_}\n" for (keys %ENV);

CGIは実行ファイルなので、そのようにパーミッションを変更します。

chmod 755 /usr/local/httpd/cgi-bin/test.cgi

ノートパソコンのWebブラウザで次のアドレスにアクセスしてください。

http://localhost:10080/cgi-bin/test.cgi

下のような感じにブラウザで表示されればOKです。表示されなかった場合は上のエラーログの記事を参照してください。

SCRIPT_NAME /cgi-bin/test.cgi
SERVER_NAME 192.168.1.xx
SERVER_ADMIN you@example.com
HTTP_ACCEPT_ENCODING gzip, deflate
HTTP_CONNECTION Keep-Alive
REQUEST_METHOD GET
HTTP_ACCEPT image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
SCRIPT_FILENAME /home/httpd/cgi-bin/test.cgi
SERVER_SOFTWARE Apache/2.0.50 (Unix)
QUERY_STRING
REMOTE_PORT xxxx
HTTP_USER_AGENT Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
SERVER_PORT 80
SERVER_SIGNATURE <address>Apache/2.0.50 (Unix) Server at 192.168.1.xx Port 80</address>
HTTP_ACCEPT_LANGUAGE ja
REMOTE_ADDR 192.168.1.xx
SERVER_PROTOCOL HTTP/1.1
PATH /sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
REQUEST_URI /cgi-bin/test.cgi
GATEWAY_INTERFACE CGI/1.1
SERVER_ADDR 192.168.1.xx
DOCUMENT_ROOT /home/httpd/public_html
HTTP_HOST 192.168.1.xx

Apacheがちゃんと動いていることは確認できました。しかし、Apacheを起動するのに毎回手動で

/usr/local/httpd/bin/apachectl start

とやるのはあまりよくありません。もしサーバマシンを再起動したら、Apacheは自動的に起動されません。そこで、起動スクリプトを作成し、起動時にApacheを起動するようにします。作成するとは言っても、自分でいちから書く必要はありません。たいていの場合、起動スクリプトはすでに用意されています。Apacheの場合もソースコードディレクトリのbuild/rpmの下にhttpd.initという名前で用意されています。

用意されている起動スクリプトを、他のデーモンの起動スクリプトが置いてあるディレクトリ(/etc/init.d)にコピーします。

cp /home/(ユーザ名)/httpd-2.0.50/build/rpm/httpd.init /etc/init.d/httpd

一般ユーザがhogeの場合は下のようになります。

cp /home/hoge/httpd-2.0.50/build/rpm/httpd.init /etc/init.d/httpd

起動スクリプトを編集します。Apacheのインストール先に合うようにパスを書き換えます。

vi /etc/init.d/httpd
変更するところとその変更後の値
apachectl=/usr/local/httpd/bin/apachectl
httpd=${HTTPD-/usr/local/httpd/bin/httpd}
CONFFILE=/etc/httpd/httpd.conf

起動スクリプトを使って再起動します。

/etc/init.d/httpd restart

エラーが出たらエラーメッセージをヒントに起動スクリプトを再編集します。

起動スクリプトを有効にするために、以下の2つのコマンドを実行します。

chkconfig --add httpd
chkconfig --level 345 httpd on

起動スクリプトが有効かどうか確認します。

chkconfig --list | grep httpd

以下のように表示されればOKです。

httpd 0:オフ 1:オフ 2:オフ 3:オン 4:オン 5:オン 6:オフ

ログファイルを放って置くとファイルが肥大化し扱いにくくなってしまいます。そのためlogrotateを用いて定期的にログファイルをローテーションし、そのようになるのを回避します。Apache用のlogrotate設定ファイルもすでに用意されています。それを、他のデーモンのlogrotate設定ファイルが置いてあるところ(/etc/logrotate.d)にコピーします。

cp /home/(ユーザ名)/httpd-2.0.50/build/rpm/httpd.logrotate /etc/logrotate.d/httpd

/etc/logrotate.confを編集し、ログをどのくらい期間でローテーションし、どのくらいの世代を残すか等の設定をします。今回は月に一度ローテーションし、24世代残すようにします(つまり2年分のログを残すわけですね)。

vi /etc/logrotate.conf
weekly
monthly
rotate 4
rotate 24
create 0664 root utmp
create 0660 root utmp

各ユーザごとに自分のホームディレクトリでWebページを管理したいという願いをかなえるのがUserディレクティブです。Userディレクティブに指定したディレクトリをユーザのホームディレクトリの下に置けば、http://www.example.org/~user/index.htmlといった感じでWebサイトをみることができます。下の設定を/etc/httpd/httpd.confのUserDirディレクティブが設定されているところ(370行目あたり)の下に追加します。

<Directory /home/*/public_html>
AllowOverride NONE
Options ExecCGI
Order allow,deny
Allow from all
</Directory>
vi /etc/httpd/httpd.conf
# directory if a ~user request is received.
#
UserDir public_html
(ここに追加)
#
# Control access to UserDir directories. The following is an example

これで、ユーザのホームディレクトリにpublic_htmlというディレクトリを作成し、そこにWebページを保存すれば、そのページは外部に公開されます。この際、ホームディレクトリ、public_htmlのパーミッションはhttpdがアクセスできるようにする必要があります(たとえば755(rwxr-xr-x))。また、Webで公開するファイル、およびそのファイルが置かれているディレクトリのパーミッションもhttpdがアクセスできるようにしとかなければなりません。

CGIが実行できるようにAddHandlerディレクティブのコメントをはずします(870行付近)。

AddHandler cgi-script .cgi

httpd.confを編集したのでApacheを再起動します。

/etc/init.d/httpd restart

実際に表示されるか試してみましょう。以下の作業は一般ユーザで行います。なお、ここでホームディレクトリのパーミッションを755にしますが、これはセキュリティ上良くありません。これの対策方が、この後に出てくる「ホームディレクトリのパーミッション」というところにありますので、必ず参照してください。

chmod 755 ~
cd
mkdir public_html
cd public_html
vi index.html

viでindex.htmlを以下のように編集します。

<html>
<head><title>TEST</title></head>
<body>Foo Bar Baz Hoge</body>
</html>

Webブラウザのアドレスバーに以下のように入力します。

http://localhost:10080/~(ユーザ名)/

たとえばユーザ名がhogeだったら、下のようになります。

http://localhost:10080/~hoge/

Foo Bar Baz Hogeという言葉がちゃんと表示されましたでしょうか。

CGIが動くかどうかもテストしましょう。

mkdir ~/public_html/cgi-bin
chmod 755 ~/public_html/cgi-bin
cd ~/public_html/cgi-bin
vi test.cgi

test.cgiを次のように編集し、保存してviを終了させます。

#!/usr/bin/perl
print "Content-type: text/plain\n\n";
print "$_\t$ENV{$_}\n" for (keys %ENV);

test.cgiは実行ファイルなので、パーミッションを変更します。

chmod 755 test.cgi

Webブラウザのアドレスバーに以下のように入力します(ユーザがhogeの場合)。

http://localhost:10080/~hoge/cgi-bin/test.cgi

現在の設定ではCGIプログラムはApacheを実行するユーザ(今回はhttpd)の権限で実行されます。この場合、CGIプログラムからアクセスされるファイルはhttpdがアクセスできるようになっていなければなりません。パーミッションを緩めればそれだけセキュリティも甘くなってしまいます。また、CGIプログラムの中にはファイルやディレクトリを作るものもあります。その作られたファイルやディレクトリの所有者はCGIプログラムの実行ユーザになってしまうので、一般ユーザが自分のホームディレクトリ下にあるディレクトリやファイルを削除できないという現象が生じてしまいます。ApacheではsuEXECという機能をつかうことによりCGIプログラムの所有者のユーザ権限でCGIを実行させることができます。これにより上の問題は解決されます。

suEXECはデフォルトではインストールされないので./configureのときに明示的にenableにしなければなりません。今回はそのようにしていますのでこのまま作業を続けることが可能です。

suEXECを可能にするためにCGIプログラムのパーミッションを700(rwx------)にします。

chmod 700 ~/public_html/cgi-bin/test.cgi

これでちゃんとCGIが動くか動作確認します。

suEXECについての詳しい情報はhttp://httpd.apache.org/docs-2.0/suexec.htmlを参照してください。

ホームディレクトリのパーミッション

Section titled “ホームディレクトリのパーミッション”

現在、httpdからpublic_htmlにアクセスできるようにするために、ユーザのホームディレクトリのパーミッションは755(rwxr-xr-x)になっています。しかし、この設定だと他のユーザ全てからホームディレクトリの中が見えてしまいます。これではセキュリティ的に良いとは言えません。そこで、httpdはアクセスできるが他のユーザからはアクセスできないようにホームディレクトリの設定を変更します。

ユーザがrootの状態で、以下のコマンドを実行します。

chgrp httpd /home/(ユーザ名)
chmod 750 /home/(ユーザ名)

たとえば、ユーザ名が”hoge”だった場合は、以下のようなコマンドになります。

chgrp httpd /home/hoge
chmod 750 /home/hoge

htmlファイルが見られるか、CGIが実行されるかを確認してください。

上のコマンドを実行すると、ホームディレクトリのパーミッションが750(rwxr-x---)になるので、他のユーザから中を見られることはありません。これだとhttpdもアクセスできなさそうですが、ホームディレクトリのグループIDはhttpdなのでグループhttpdのメンバであるhttpdはアクセス可能です。ホームディレクトリの中のディレクトリやファイルのグループIDはhttpdではないので、ホームディレクトリの中ではhttpdがアクセス可能であるべきファイルのパーミッションは第三者が読めるようになっていなくてはなりません(suEXECを使う場合、CGIプログラムは除きます)。

httpd750.png
+httpdはindex.htmlにアクセス可能ですが、他の一般ユーザもアクセスできてしまいます。
+httpdは/home/hogeにアクセスする権限がないのでindex.htmlを読み込むことはできません。
+httpdはindex.htmlにアクセス可能です。他の一般ユーザは/home/hogeの中身を見ることはできません。

間違えるとLinuxが起動できなくなるので、今回はこの方法を使用しません!

Linuxカーネル2.6からPOSIX ACL(Access Control Lists)という機能が追加されました。これによりファイルやディレクトリへの各ユーザもしくはグループでのアクセス制御を行えるようになります。これを使えば、上のようにホームディレクトリのグループIDをhttpdにすることなくpublic_htmlにアクセスすることが可能になります。

ACLを使用するために、/etc/fstabの1行目を次のように書き換えます。

vi /etc/fstab
LABEL=/ / ext3 defaults 1 1
LABEL=/ / ext3 defaults,acl 1 1

マウントしなおすため、とりあえずリブートしましょう。

reboot

再起動が終了したら、ユーザでログインした後に以下のコマンドを実行します。これでhttpdがホームディレクトリにアクセスできるようになります。

(ユーザでログイン)
setfacl -m u:httpd:rx ~

「ACLを使用する場合」でホームディレクトリのグループをhttpdにしている場合は、ホームディレクトリのグループを自分のものに戻しましょう。この状態ならば、自分のホームディレクトリのグループをhttpdにする必要はありません。

chgrp (ユーザ名) ~

自分のユーザ名がhogeだった場合は次のようなコマンドになります。

chgrp hoge ~

仕組みとしては先の方法と同じで、違いはホームディレクトリへのアクセスをグループID、ACLどちらで与えているかだけです。そのため、ホームディレクトリ中のhttpdがアクセスすべきファイルやディレクトリは第三者が読めるようになっている必要があります(suEXECを使う場合、CGIプログラムは除きます)。

ドキュメントルートとはWebサーバ上でのルートディレクトリのことです。http://www.example.com/index.htmlのindex.htmlファイルが置いてある場所がドキュメントルートです。デフォルトでは/usr/local/httpd/htdocsになっています。ここにファイルを置いてサービスを提供することもできますが、管理面、運営面で都合が悪いです。また、セキュリティ的にも良いとは言えません。そんなわけなので、ドキュメントルートは変更するべきです。ドキュメントルートはhttpd.confのDocumentRootディレクティブ(310行目あたり)で設定されています。今回はドキュメントルートを/home/httpd/public_htmlに設定します。

DocumentRoot "/usr/local/httpd/htdocs"
DocumentRoot "/home/httpd/public_html"

また、httpd.confを見ていくと、httpd.confの330行あたりにあるも変更しなければいけないことがわかります(コメントのところに英語で書いてある)。

<Directory "/usr/local/httpd/htdocs">
<Directory "/home/httpd/public_html">

設定ファイルを変更したのでApacheを再起動します。

/etc/init.d/httpd restart

あとは新しいドキュメントルート/home/httpd/public_htmlにindex.htmlを置くだけです。置いたらWebブラウザでちゃんと表示されるか確認してみましょう。以下の作業はrootで行います。

mkdir -p /home/httpd/public_html
echo "<html><body><h1>TEST</h1></body></html>" > /home/httpd/public_html/index.html
chown -R httpd: /home/httpd