SSブログ
Linux(Apache) ブログトップ
- | 次の10件

たぶん難しくないApache2・バーチャルホスト編~一粒で二度美味しい?~ [Linux(Apache)]

 DDNSサービスが、DiCE等の優れたソフトウェアのおかげでとても利用しやすくなったことを受けて、自分用のWebサーバを立てている人も徐々に増えているのではないかと思うけども、中には、「用途別に違うドメイン名でサーバを立てたい!」なんて贅沢な(?)悩みを持つ人も出てきているのではないだろうか。
 サーバが複数台あれば、それぞれ立ててしまうという手もあるけども、ご家庭用のブロードバンドルータ等ではネットワーク的に凝ったことが出来なくて…みたいなことで悩まされることもあるかもしれない。

 そこで、Apache2に用意されている「バーチャルホスト」という機能を使うことができるということを紹介しておこう。

 これは、1台のWebサーバに、複数の名前(サーバ名)を割り当てる事ができ、かつそのその名前(サーバ名)ごとに異なる挙動をとらせることが出来るという、大変に便利な機能なのである。

 たとえば、NICが複数あるサーバがあるとして、NICの1番と2番とで異なるコンテンツを見せることが出来るとか、同一のIPアドレスでも異なるFQDN名を付けておけばそのFQDN名ごとに異なるコンテンツを見せることも出来る。
 イメージが沸きにくいかもしれないが、たとえば/etc/hosts(Windowsの場合は C:\WINDOWS\system32\drivers\etc\hosts とかそのへん)に…

192.168.0.10 class-3b.ryoou-gakuen.ac.jp
192.168.0.10 class-1d.ryoou-gakuen.ac.jp
192.168.0.10 teachers-room.ryoou-gakuen.ac.jp

 と記述していたと仮定する。この場合、本来ならどのサーバ名を用いても物理的には同じサーバにアクセスが行くことになる。

 http://class-3b.ryoou-gakuen.ac.jp/
 http://class-1b.ryoou-gakuen.ac.jp/
 http://teachers-room.ryoou-gakuen.ac.jp/

 それぞれ同じドキュメントルートの中にあるindex.htmlあたりが見えちゃったりするはずである…ということね。

 ところが、Apache2の持つ「バーチャルホスト」の設定を適切に行うことで、それぞれ別々のコンテンツを見せることができるのである…という仕組み。

 では、まずその基本編に挑戦してみる。手順としてはそれほど難しくは無い。

 さきほど例示したFQDN名(ホスト名)で、それぞれ異なるindex.htmlが表示できるようにしてみる。
手順としては、
手順1:ホスト名を決定する。必要に応じてDNSに登録したりhostsファイルに記述したりする
手順2:それぞれのホストで表示させるコンテンツを用意する
手順3:ドキュメントルートディレクトリをホスト毎に用意してコンテンツを配置する
手順4:httpd.confにバーチャルホストの設定を記述する
手順5:httpdを起動してテストしてみる

手順1:ホスト名を決定する。必要に応じてDNSに登録したりhostsファイルに記述したりする
 まずはこの作業から。
 DDNSに登録するとか、会社のイントラネットなら社内のDNSサーバに登録するとか、ご家庭内のテストならクライアントPCのhostsファイルにIPアドレスとホスト名を記述するなどする。
 ちなみにここでは、先ほど例示したホスト名とIPアドレスを使用することにする。

192.168.0.10 class-3b.ryoou-gakuen.ac.jp
192.168.0.10 class-1d.ryoou-gakuen.ac.jp
192.168.0.10 teachers-room.ryoou-gakuen.ac.jp

 こんな設定。(IPアドレスは適切に変更する必要があることは言うまでも無い)

手順2:それぞれのホストで表示させるコンテンツを用意する
 コンテンツを用意する。面倒くさいので、index.htmlにぺろっとテキストを書くだけということで。(笑)
 まず、class-3bのindex.htmlから。
[root@kagami class-3b]# cat index.html
<html>
<body>
Konata.Izumi<br>
Tsukasa.Hiiragi<br>
Kagami.Hiiragi<br>
Miyuki.Takara<br>
Minoru.Shiraishi<br>
</body>
</html>

 次に、class-1dのindex.htmlは…
[root@kagami class-1d]# cat index.html
<html>
<body>
Yutaka.Kobayakawa<br>
Minami.Iwasaki<br>
Hiyori.Tamura<br>
Patricia Martin<br>
</body>
</html>

 そして、teachers-roomのindex.htmlは…
[root@kagami teachers-room]# cat index.html
<html>
<body>
Nanako.Kuroi<br>
Hikaru.Sakuraba<br>
Fuyuki.Amahara<br>
</body>
</html>

 と、してみた。

手順3:ドキュメントルートディレクトリをホスト毎に用意してコンテンツを配置する
 で、そのそれぞれのindex.htmlをバーチャルホスト毎にドキュメントルートディレクトリを用意して、それぞれのドキュメントルートに配置することにする。
 ドキュメントルートは、
class-3b … /var/www/html/class-3b
class-1d … /var/www/html/class-1d
teachers-room … /var/www/html/teachers-room
 ということにする。

手順4:httpd.confにバーチャルホストの設定を記述する
 いよいよhttpd.confに設定を記述する。ここで活躍するのは「VirtualHost」ディレクティブである。なお、VirtualHostディレクティブの使用に先立って必要になるディレクティブがある。それは「NameVirtualHost」である。
 ちなみに、今回基本編として紹介しているバーチャルホストは、「名前ベースのバーチャルホスト」に該当する。同一のIPアドレスに複数の名前を割り当てているので、ここで使うNameVirtualHostディレクティブは、1パターンの記述方法のみ用いる。
 VirtualHostディレクティブは、これまでに登場したDirectoryディレクティブやFileディレクティブと同様に、「<VirtualHost (名前)>」と「</VirtualHost>」という2つのディレクティブで囲んだ範囲が有効になる仕組み。

 では、実際のバーチャルホストの定義(1個目)を見てみよう。

NameVirtualHost *:80
<VirtualHost *:80>
ServerName class-3b.ryoou-gakuen.ac.jp
DocumentRoot /var/www/html/class-3b
<Directory /var/www/html/class-3b>
Order Deny,Allow
Allow from All
</Directory>
</VirtualHost>

 DirectoryディレクティブやFileディレクティブの時は、そのディレクティブに続けて記述したディレクトリ名やファイル名が、その囲まれた範囲内で適用される設定の適用先を表していたが、「名前ベースのバーチャルホスト」では、「*:80」と記述している。これは、この後で紹介する2個目・3個目も同じ記述をするので、この記述を持って適用先が決定されるわけではない。
 「名前ベースのバーチャルホスト」では、VirtualHostディレクティブの中にある、「ServerName」ディレクティブによって、どのVirtualHostディレクティブの塊が適用されるかが決まるのである。よって、上記の例では、「http://class-3b.ryoou-gakuen.ac.jp/」でアクセスされたときに、この塊の設定が適用される…ということになる。
 で、このバーチャルホストのドキュメントルートは/var/www/html/class-3bですよ…と宣言している。そして、そのドキュメントルートに対するアクセス許可の設定も、バーチャルホストの設定の中で行っている。

 class-1dやteachers-roomについても同じように設定する。ただし、NameVirtualHostは全体で1個だけあればよい。

NameVirtualHost *:80

<VirtualHost *:80>
ServerName class-3b.ryoou-gakuen.ac.jp
DocumentRoot /var/www/html/class-3b
<Directory /var/www/html/class-3b>
Order Deny,Allow
Allow from All
</Directory>
</VirtualHost>

<VirtualHost *:80>
ServerName class-1d.ryoou-gakuen.ac.jp
DocumentRoot /var/www/html/class-1d
<Directory /var/www/html/class-1d>
Order Deny,Allow
Allow from All
</Directory>
</VirtualHost>

<VirtualHost *:80>
ServerName teachers-room.ryoou-gakuen.ac.jp
DocumentRoot /var/www/html/teachers-room
<Directory /var/www/html/teachers-room>
Order Deny,Allow
Allow from All
</Directory>
</VirtualHost>

 これでよし。

 そんな訳で、今回使用したhttpd.confはこんな感じ。
[root@kagami conf]# cat httpd.conf
ServerRoot      "/etc/httpd"
PidFile         run/httpd.pid
Listen          80
User            apache
Group           apache

ServerName      kagami.hiiragi.com:80

LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_default_module modules/mod_authz_default.so
LoadModule dir_module modules/mod_dir.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule mime_module modules/mod_mime.so

<Directory      />
        Order   Allow,Deny
        Deny from       All
</Directory>

<Files  ~       "^\.ht">
        Deny from       All
</Files>

NameVirtualHost *:80

<VirtualHost    *:80>
        ServerName      class-3b.ryoou-gakuen.ac.jp
        DocumentRoot    "/var/www/html/class-3b"
        <Directory      /var/www/html/class-3b>
                Order   Deny,Allow
                Allow from      All
        </Directory>
</VirtualHost>

<VirtualHost    *:80>
        ServerName      class-1d.ryoou-gakuen.ac.jp
        DocumentRoot    "/var/www/html/class-1d"
        <Directory      /var/www/html/class-1d>
                Order   Deny,Allow
                Allow from      All
        </Directory>
</VirtualHost>

<VirtualHost    *:80>
        ServerName      teachers-room.ryoou-gakuen.ac.jp
        DocumentRoot    "/var/www/html/teachers-room"
        <Directory      /var/www/html/teachers-room>
                Order   Deny,Allow
                Allow from      All
        </Directory>
</VirtualHost>

TypesConfig     /etc/mime.types
DirectoryIndex  index.html
AddDefaultCharset       off
MimeMagicFile   conf/magic

 なお、Apache2でバーチャルホスト名として使用するだけなら、サーバ側の/etc/hostsにホスト名を記述する必要はまったく無い。

手順5:httpdを起動してテストしてみる
 ここまで完了したら、さっそくserver httpd startしてみよう。(あるいはserver httpd restart)
 http://class-3b.ryoou-gakuen.ac.jp/
 http://class-1d.ryoou-gakuen.ac.jp/
 http://teachers-room.ryoou-gakuen.ac.jp/
 と、それぞれのURLでアクセスすると、表示内容が変化することが確認できるだろうか。

 同一のIPアドレスであるが、httpのプロトコル中に規定されている、「Host」ヘッダに記述されているホスト名を見て判別しているのであった。

 なお、ものすごく古いブラウザあるいは、wgetやcurlコマンド、あるいはtelnetで直接httpポートにアクセスし、Hostヘッダを送信しなかった場合にどうなるのであろうか??Hostヘッダが無ければ、Apacheは「どのサーバ名に対する処理を行えばよいかわからない」はずである。

 実験してみる。Telnetコマンドでhttpポートに直接アクセスしてみる。
[root@kagami conf]# telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
GET /
<html>
<body>
Konata.Izumi<br>
Tsukasa.Hiiragi<br>
Kagami.Hiiragi<br>
Miyuki.Takara<br>
Minoru.Shiraishi<br>
</body>
</html>

Connection closed by foreign host.

 telnetコマンドで、Webサーバの80番ポート(httpのポート)に接続し、「GET /」というコマンドだけを送信している。これで、ドキュメントルートの下にあるindex.htmlが取得される。
 中身を見てみると、どうやら「class-3b」の内容であるように見える。

 実は、Hostヘッダが無かったり、または全てのVirtualHostディレクティブに「マッチしなかった」場合には、一番最初に現れたVirtualHostディレクティブの内容が適用されるという仕様になっているのであった。
 その証拠に、「class-1d」と「class-3b」とのVirtualHostのブロックを入れ替えてhttpdを起動してみた後に、同じくtelnetで直接アクセスを行うと…
[root@kagami conf]# service httpd restart
httpd を停止中:                                            [  OK  ]
httpd を起動中:                                            [  OK  ]
[root@kagami conf]# telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
GET /
<html>
<body>
Yutaka.Kobayakawa<br>
Minami.Iwasaki<br>
Hiyori.Tamura<br>
Patricia Martin<br>
</body>
</html>

Connection closed by foreign host.

 表示内容が入れ替わっていることが判る。ここではtelnetコマンドでアクセスしているが、wgetやcurlコマンド、あるいはブラウザでIPアドレスを指定してアクセスした場合(http://192.168.0.10/ みたいな感じ)でも同じことが確認できる。

たぶん難しくないApache2・初期設定編その5~その他の設定項目~ [Linux(Apache)]

 さて。「初期設定編」の最後に、その他の設定項目について説明しておく。

 ごくごく小規模なWebサーバとして使用するのであれば、あまり気にする必要は無い。が、イントラネットサーバ等で多くのアクセスが見込まれるケースなどでは、設定しておくと良いかもしれない…という設定項目になっている。

Webサーバプロセスの起動数に関する設定
 個人的に使うWebサーバとか、小さな社内ネットワークなどで使う際にはあまり気にする必要も無い項目だが、httpd.confの中にhttpdの起動数に関する設定を盛り込むことが出来る。多くのアクセスが集中する事が予想される場合などには設定しておくことが推奨される。
 関連するディレクティブは以下のとおり。

ServerLimit … 設定可能なサーバプロセス(※)の最大値
MaxClients … 同時に応答できるクライアント数の最大値
MixSpareServersMaxSpareServers … クライアントからの接続要求を待っている(≒アイドル状態にある)子プロセスの最小値と最大値
StartServers … Apacheを起動した際に同時に起動する子プロセスの数
MaxRequestsPerChild … 1個の子プロセスが、クライアントからのリクエストにいくつ答えたら子プロセスを終了させるかの値

 個人的に使っているとか、イントラネットでも小さな組織でそれほどアクセスが多くないケースなどでは、これらのパラメータはデフォルトの状態でもまったく問題にならないだろう。
 ちなみに、yumやrpmでApache2をインストールした場合、「prefork」というモジュールが標準で組み込まれた状態になっている。これは、同時に処理できるリクエストは1プロセス=1セッション(要求)という状態のものであり、たとえば5人のユーザーが同時に接続してきた場合、5プロセスが必要になるということになる。1プロセスあたりでは1個のスレッドしか動作しないことになるので、多くのアクセスが見込まれる際にはその数に応じたプロセス数が起動することになるのである。

 ほとんどの場合は、「ServerLimit」と「MaxClients」ディレクティブあたりを調整することになるだろう。256本の同時接続要求を超える場合は、MaxClientsを大きくすることになる。なお、MaxClientsをとても大きくする場合は、ServerLimitも増やさなければならないかもしれない。このあたりのパラメータの増減については、オライリーの書籍などをきちんと読んで設定することを強くオススメする。

たぶん難しくないApache2・初期設定編その4の補足~CGIの置き場所問題~ [Linux(Apache)]

 さて。「その4」でCGIを実行できるようにしたものの、あの設定内容ではCGIに対するURLは http://server/cgi-bin/hoge.pl とかいう感じで、ディレクトリとかの下でCGIを実行できるようにはなっていなかった。まあ、formタグでアクセスしてきている人から見えない形でCGIを実行させるのであれば、基本的にそれでも困らないとは思うのだけども、実際にはそうはいかないかもしれない。
 また、動かしたいCGIの種類が沢山あって、 /var/www/cgi-bin 配下にベタで置くとごちゃごちゃして判りにくくなるので、CGIごとにサブディレクトリを作ってその下に置きたいとか、そういう要望も出てくることもあるかもしれない。

 そこで、CGIの置き場についていくつかのアプローチを補足しておきたいと思う。

① 個別に ScriptAlias を記述する方法
 たとえば、directoryA と directoryB とでCGIを実行したい場合。具体的には、 http://server/directoryA/cgi-bin/cgi1.pl と http://server/directoryB/cgi-bin/cgi2.pl というようなURLにした場合。このようなケースで、CGIを動かすディレクトリが多くないようならば、「ScriptAlias」ディレクティブを個別に記述する方法もある。

ScriptAlias /directoryA/cgi-bin/ /var/www/cgi-bin/directoryA
ScriptAlias /directoryB/cgi-bin/ /var/www/cgi-bin/directoryB

 たとえばこんな感じ。また、URLとしてはディレクトリが分かれていても、CGI置き場は同じディレクトリでも構わないよというのであれば、

ScriptAlias /directoryA/cgi-bin/ /var/www/cgi-bin
ScriptAlias /directoryB/cgi-bin/ /var/www/cgi-bin

 こんな風にしてしまう手もある。
 ディレクトリが1個とか2個とか3個とか、あまり多くないようならこの手でCGIの置き場を設定するのが安全だと思われる。

② 正規表現を用いて指定する方法
 基本的な発想は①と同じ。ただ、URLに記述されるディレクトリがあっちこっち大量にあるよという場合は、いちいちScriptAliasディレクティブを書くのが面倒に感じられるかもしれない。そんな場合は正規表現を用いてしまうと楽になる。
 正規表現を用いて指定する場合は、ディレクティブも微妙に変化し、「ScriptAliasMatch」というディレクティブを用いる。 http://server/ナントカカントカ/cgi-bin/cgi.pl というURLで使いたい!という場合は

ScriptAliasMatch .*/cgi-bin/(.*) /var/www/cgi-bin/$1

 とか指定すれば、URLに「cgi-bin」が現れればCGIとしてScriptAliasMatchディレクティブによってcgi-binディレクトリにあるCGIが検索対象となる。
 また、cgi-binディレクトリの下にサブディレクトリを作ってCGIの置き場所を変えることもできる。

③ ドキュメントルートからのディレクトリツリーにCGIを置く方法
 それでもやっぱり、ドキュメントルートからのディレクトリツリーの中にCGIを置きたいというケースもあると思う。これまで紹介したような、ScriptAliasあるいはScriptAliasMatchといったディレクティブでドキュメントルート配下のディレクトリを指定する方法でも良いのだけども、ドキュメントルート配下のディレクトリにCGIを置いて実行したい場合には別の方法がよく用いられるので、それを紹介しておきたい。

 たとえば、CGIを実行したいURLを http://server/directoryA/ だと仮定する。このとき、ドキュメントルートからのディレクトリだと /var/www/html/directoryA になることは判ると思う。
 CGIの実行を許可する指定は、これまで同様に

<Directory /var/www/html/directoryA>
Order Deny,Allow
Allow from All
Options +ExecCGI
</Directory>

 と、基本形は変わらず。ただし、このままではどのファイルがCGIなのかApacheは知らないままなので、「このディレクトリにあるナントカカントカ.plはCGIですよ~」などと知らせてやる必要がある。その際に使用されるディレクティブは「AddHandler」ディレクティブである。これによって指定された拡張子のついたファイルは、「ハンドラ」と呼ばれる処理名に関連付けられるようになる。
 たとえば、ここで使用する「cgi-script」というハンドラの場合、そのファイルをクライアントにダウンロードさせて表示するという動作をせず、CGIとしてサーバ側で処理を行うようになる。
 使用方法は、「AddHandler (ハンドラ名) (拡張子)...」となる。拡張子「.pl」を持つファイルをCGIとして宣言する場合は、「Addhander cgi-script .pl」ということになる。(拡張子は複数あって良い)

<Directory /var/www/html/directoryA>
Order Deny,Allow
Allow from All
Options +ExecCGI
AddHandler cgi-script .pl
</Directory>

 こんな感じ。
 で、このディレクトリにCGIを置くと http://server/directoryA/CGI.pl みたいな感じでCGIが実行できるようになる。難しくは無いでしょ?

 ※cgi-scriptハンドラについて補足※
 ところで、「cgi-script」ハンドラって、『script』ってつくだけに、PerlとかRubyとかあの辺専用な訳?Cとかでゴリゴリ書いたCGIプログラムはどうすいればいいのよ?

 みたいな質問が出そうなので、補足しておきます。ハンドラ名は「cgi-script」ですが、スクリプト専用というわけではないので、Cでゴリゴリ書いたCGIプログラムも、AddHandlerでハンドラに割り当ててやれば問題なくCGIとして動作させることができる。
 以下のようにC言語で超簡単なCGIを作ってみる。
[root@kagami tmp]# cat test_c.c
#include        <stdio.h>

int     main( int , char ** );

int     main( int argc , char **argv )
{
        printf( "Content-type: text/html\n\n" );
        printf( "Return knee-length socks.\n" );
}

 で、これをコンパイルして実行してみる。
[root@kagami tmp]# gcc -o test_c.cgi test_c.c
[root@kagami tmp]# ./test_c.cgi
Content-type: text/html

Return knee-length socks.

 問題なく実行できている。ファイルの種類を確認しておこう。
[root@kagami tmp]# file test_c.cgi
test.cgi: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

 ちゃんと、バイナリーの実行ファイルになっていることがわかる。
 では、これを /var/www/html/directoryA/ にコピーして、httpd.confを微妙に修正する。修正のポイントは、拡張子「.pl」に続けて、「.cgi」もCGIであることを通知するのである。
<Directory /var/www/html/directoryA>
Order Deny,Allow
Allow from All
Options +ExecCGI
AddHandler cgi-script .pl .cgi
</Directory>

 これでApacheを再起動してCGIにアクセスしてみよう。 http://server/directoryA/test_c.cgi で「Return knee-length socks. 」というテキストが表示されれば成功。

たぶん難しくないApache2・初期設定編その4~変幻自在のコンテンツ(CGI)~ [Linux(Apache)]

 今度はサーバでCGIを動かすことが出来るように設定してみよう。なお、CGIを使用するに当たっては、CGIプログラム、あるいはCGIスクリプトの内容については特に注意深くデバッグをしておかなければならない。さもなければ、Apacheの設定をどれだけ慎重に施してもCGIプログラム、あるいはCGIスクリプトがセキュリティ上のアキレス腱になってしまうからである。
 なお、このblogではCGIプログラム、あるいはCGIスクリプトの作成については原則的に言及しない。なぜなら、そこまで責任を取れないからである。(大笑)

 それでは、CGIを動かす設定について、解説を加える。


 CGIを動かすことも、基本的にそれほど難しい訳ではない。ただ少しばかり直感的でないため、混乱しやすいだけなのである。まずは一番簡単な基本形の理解から入ろう。

手順1:CGIプログラム、あるいはCGIスクリプトを作成する
手順2:CGIプログラム、あるいはCGIスクリプトの配置場所を作成する
手順3:httpd.confに、「手順2」で作成した配置場所の指定を記述する
手順4:CGIを動作させたいディレクトリに、CGIの実行を許可する
手順5:実際にCGIが動作するかどうかチェックする

手順1:CGIプログラム、あるいはCGIスクリプトを作成する

 なにはなくとも、CGIプログラムを作成するところから。テスト用CGIとして、ひとまずperlで以下のようなプログラムを作成し、これで実験することにする。
[root@kagami conf]# cat /tmp/test.pl
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "JAM took a sailor blouse away.\n";

 「chmod +x /tmp/test.pl」で実行権を付けた状態でこれを実行すると…
[root@kagami conf]# /tmp/test.pl
Content-type: text/html

JAM took a sailor blouse away.

 このような実行結果が出力されることになる。

手順2:CGIプログラム、あるいはCGIスクリプトの配置場所を作成する

 CGIプログラムやCGIスクリプトは、一般的にはダウンロードさせたくないだろう。もともとサーバ側で実行するためのものであって、クライアントに用はないはず。そこで、ドキュメントルートの外側に、CGIを配置するディレクトリを作成する。(内側にあってもいいんだけどね…)
 ここでは、とりあえず /var/www/cgi-bin ディレクトリにCGIを配置することにしよう。「mv /tmp/test.pl /var/www/cgi-bin/test.pl」とでも実行してCGIもそこに配置する。
[root@kagami conf]# ls -la /var/www/cgi-bin/
合計 12
drwxr-xr-x 2 root root 4096 11月 27 16:30 .
drwxr-xr-x 6 root root 4096 11月 20 12:06 ..
-rwxr-xr-x 1 root root   96 11月 27 16:24 test.pl

 これでよし。

手順3:httpd.confに、「手順2」で作成した配置場所の指定を記述する

 cgi-binディレクトリの存在は、まだApacheが認識できていないので、これを認識させる必要がある。ここで登場するディレクティブは「ScriptAlias」である。一般的には、「ScriptAlias /cgi-bin/ /var/www/cgi-bin/」という記述になるだろう。

 さらに、CGIを配置したディレクトリに対するアクセス許可の設定も必要となる。ドキュメントルートの外側に配置した場合、明示的なアクセス許可の設定をしなければ、ルートディレクトリに対して行った、アクセス拒否の設定が引き継がれてしまう。このために、「Directory」ディレクティブでCGIディレクトリに対する許可を別途作成することとなる。
<Directory      /var/www/cgi-bin>
        Order   Deny,Allow
        Allow from      All
</Directory>

 このような設定を記述する。



手順4:CGIを動作させたいディレクトリに、CGIの実行を許可する

 通常の状態では、CGIの動作は一切許可されない。そこで、CGIの実行許可を明示的に行う必要がある。このために使用するディレクティブは「Options」である。一般的には、「Options +ExecCGI」という記述になるだろう。(なお、ケースによっては「+」記号を省略しても構わない)

手順5:実際にCGIが動作するかどうかチェックする

 それでは、実際のhttpd.confを見てみよう。なお、「その3」シリーズで記述を加えた認証まわりの設定はばっさり省略していることに注意されたし。また、モジュールの宣言も追加されていることにも注意。(ベースとなるhttpd.confは「その2」の末尾にあるものを使っている)

 それから、今までに説明していないディレクティブ「TypesConfig」が登場している。これはmod_mimeモジュールが使用するファイル「mime.types」の保存場所を指定するのだが、デフォルトの状態(記述を省略した状態)だと、conf/mime.typesが指定されているとみなされてしまうが、困ったことにCentOSでは保存場所が/etc/mime.typesに移動しているので、このサンプルにあるとおりの指定をしなければならないのであった…。まあ、魔法の呪文だと思って書き加えておいてやって欲しい。
[root@kagami conf]# cat httpd.conf
ServerRoot      "/etc/httpd"
PidFile         run/httpd.pid
Listen          80
User            apache
Group           apache

ServerName      kagami.hiiragi.com:80
DocumentRoot    "/var/www/html"

LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_default_module modules/mod_authz_default.so
LoadModule dir_module modules/mod_dir.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule alias_module modules/mod_alias.so
LoadModule cgi_module modules/mod_cgi.so
LoadModule mime_module modules/mod_mime.so

<Directory      />
        Order   Allow,Deny
        Deny from       All
</Directory>

<Directory      /var/www/html>
        Order   Deny,Allow
        Allow from      All
        Options +ExecCGI
</Directory>

<Directory      /var/www/cgi-bin>
        Order   Deny,Allow
        Allow from      All
</Directory>

<Files  ~       "^\.ht">
        Deny from       All
</Files>

TypesConfig     /etc/mime.types
ScriptAlias     /cgi-bin/       /var/www/cgi-bin/
DirectoryIndex  index.html
AddDefaultCharset       off
MimeMagicFile   conf/magic

 ここでは、ドキュメントルートにCGIの実行権をつけてみた。よって、test.plを実行する場合は、 http://server/cgi-bin/test.pl としてアクセスしてみると、ブラウザに「JAM took a sailor blouse away. 」などとちょろっと表示されるはずである。

※CGIが実行できずに陥りやすい罠※
 このblogではすでに述べたとおりCGIの中身については守備範囲外としている。が、一般的に陥りやすい問題を紹介しておくので、CGIが実行できない場合に参考にしてもらいたい。

チェックポイント1:CGIに実行権限が無い
 CGIプログラム、あるいはCGIスクリプトに実行権限が無いことがよくある。一般的にApache(httpd)はnobodyやapacheアカウントで実行され、その権限でCGIプログラム、あるいはCGIスクリプトにアクセスしてくるので、ファイルのオーナーにだけ実行権限を付けているような場合は実行できないことが多い。
[root@kagami conf]# ls -la /var/www/cgi-bin/
合計 12
drwxr-xr-x 2 root root 4096 11月 27 16:30 .
drwxr-xr-x 6 root root 4096 11月 20 12:06 ..
-rwxr-xr-x 1 root root   96 11月 27 16:24 test.pl

 上記のように、「読み取り権」と「実行権」がきちんと付与されている事を確認する。

 なお、間抜けな例としては、そもそもcgi-binディレクトリにアクセス権が無いなんてこともある。ディレクトリやファイルのパーミッションについてはよくチェックしておくように。

チェックポイント2:シェバングの記述が無いか間違っているか、またはそれが正確にファイルの「先頭」でない
 「シェバング」とは、ファイルの先頭行に配置される、「#!」で始まる行のこと。実行されるファイルが何らかのスクリプトファイルである場合、そのスクリプトファイルを正しく理解できるコマンドが何であるかをシェルインタプリタに通知する役割を担っている。
 たとえば、一般的なシェルスクリプトなら、シェバングは
#!/bin/sh

 とか、
#!/bin/bash

 とかいう具合になる。perlスクリプトであれば、
#!/usr/bin/perl

 と書くのが「一般的」である。
 「一般的」ではあるが、perlの場合、もしかしたら他のディレクトリにインストールされていることもたまにあるようなので、whichコマンドなどで正確な所在を確認しておく。
[root@kagami conf]# which perl
/usr/bin/perl

 こんな具合に。
 で、たとえばWindowsな環境で開発されたCGIをそのままUNIX/Linux環境に持ち込むと、このシェバングが「#!c:/perl/bin/perl」とか当たり前のように記述されていてUNIX/Lnux環境では実行できないことになる。ここを正しく修正する。

 また、シェバングは『厳密にファイルの先頭』でなければならない。スクリプトの先頭にタイトルとかコピーライトとか誇らしげに書きたい気持ちは良くわかるが、そんなものを差し置いてとにかく最初にはシェバングから書き出さなければならないのであった。変な空白や改行もなしに、とにかく正しくシェバングを記述するように。

チェックポイント3:改行コードの変換がおかしくなっていないか?
 UNIX/Linux上でviとか使ってガリガリCGIを書いている人にはあまり発生しない問題だが、Windows上のエディタを使い、ftpなどでファイルをサーバ上に配置している場合に生じる恐れがある問題。
 CGIスクリプトは「テキストファイル」なので、WindowsとUNIX/Linuxとの間で文字コードや改行コードの変換を行う必要が生じる。ftpのモード設定が正しくない場合、これが正しく行われずに問題を引き起こすことがある。

チェックポイント4:「Content-type: text/html」の出力をしていない、タイプミスがある、出力直後の改行が1個しかない
 先のCGIスクリプトのサンプルをよ~く見てもらうと判ると思うが、「print "Content-type: text/html\n\n";」と、「\n」(改行コード)が2個入っているところが重要。1個しかないとInternal Server Error等となったりする。空白の入れ方や記号の使い方等についても、1字1句間違えることなく指定しなければならない。

チェックポイント5:そもそもCGIにバグがある…
┐(´ー`)┌

たぶん難しくないApache2・初期設定編その3の補足2~「ダイジェスト認証」の場合~ [Linux(Apache)]

 さて。前々アーティクルではBASIC認証を使用した。手軽に使えるし、まあ個人的に使うとかイントラネット内部だけでの使用という程度であるなら、これでもさしたる不都合は無いと思う。ただ、少しでも本格的にWebサーバを運用しようとなると、BASIC認証では不安が残る。
 というもの、認証用のIDとパスワードが平文で流れてしまうので、その筋の人がちょちょいと悪さをしようものならば、たちまちIDとパスワードがブッコ抜かれてしまうという問題がBASIC認証にはあるのであった。

 そこで導入されたのが「ダイジェスト認証」という仕組み。これは、BASIC認証の時にはIDとパスワードをそのまま流していた(厳密には、Base64でエンコードされているので、人間の見た目的にはそのままでは何が書かれているのか判読は不可能だが、簡単にデコードできる代物なので、実質的には「そのまま」流れていると考えてよい)が、ダイジェスト認証では、IDとパスワードを「ハッシュ化」しておくるので、複合化してIDとパスワードを割り出すことが難しくなっている。(しかし、まったく出来ないという訳でもないらしい…詳しいことはよくわからないので興味があるようなら各自で調べてもらいたい

 このダイジェスト認証も、BASIC認証と大体同じような感覚で使用できるので、こちらの設定方法についても説明しておく。

 BASIC認証からの変更点としては、まずはじめに「AuthType Basic」と記述したディレクティブを「AuthType Digest」と書き改めるところから始まる。これで認証方式としてはダイジェスト認証が使用することが宣言される。
 続いて、「AuthBasicProvider」ディレクティブは使用せず、変わりに「AuthDigestProvider」を使用する。引数はfileで変わらないけど。
 「AuthUserFile」と「AuthName」、「Require」はそのまま。ただし、「AuthName」で指定している「認証領域」の文字列は、この後IDとパスワードを作成する際に必要となるのであまりに変な物とか選ぶと後悔します。なぜなら、AuthNameが変更されてしまうと、IDとパスワードを保存しているファイルを最初から作り直すハメになるからである。

 というわけで、BASIC認証とダイジェスト認証とを並べて記述したhttpd.confの内容を例示するとこんな感じ。
<Directory      /var/www/html/auth_contents>
        AuthType        Basic
        AuthBasicProvider       file
        AuthUserFile    auth/userauth
        AuthName        "Takamiya Shrine"
        Require         valid-user
</Directory>

<Directory      /var/www/html/auth_digest>
        AuthType        Digest
        AuthDigestProvider      file
        AuthUserFile    auth/userdigest
        AuthName        "Takamiya Shrine"
        Require         valid-user
</Directory>

 上側のブロックがBASIC認証、下側のブロックがダイジェスト認証。
 なお、BASIC認証で用いるパスワードファイルと、ダイジェスト認証で用いるパスワードファイルとは共用できないので、別々に用意する必要がある。また、上記の例でダイジェスト認証用のパスワードファイルを作成する際のコマンド例は、
[root@kagami conf]# htdigest -c /etc/httpd/auth/userdigest "Takamiya Shrine" kagami.hiiragi
Adding password for kagami.hiiragi in realm Takamiya Shrine.
New password:
Re-type new password:

 こんな具合になる。AuthNameで使用した「認証領域」を引数に指定している所を要チェック。また、認証領域に空白が入っている場合は当然のことながらダブルクォーテーションなどで囲む必要があることは言うまでも無い。さらに、htpasswdコマンドと同様、「-c」オプションの指定には気をつけること。




 あ、モジュールの組み込みも必要。

LoadModule auth_digest_module modules/mod_auth_digest.so

 これが必要。なおBASIC認証を使わないでダイジェスト認証だけ…ということなら

LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_default_module modules/mod_authz_default.so

 こういう具合に指定することになろう。(要するにBASIC認証のモジュールだけ抜く感じで)

たぶん難しくないApache2・初期設定編その3の補足1~「関係者」の範囲を詳しく~ [Linux(Apache)]

 さて。前のアーティクルで「Satisfy」ディレクティブについてさらりと紹介したが、詳しい内容を割愛したので、ここで解説を加えておく。

 このディレクティブは、Allowディレクティブ(とセットに使われるDenyやOrderディレクティブなども含まれる)で指定されるアクセス許可の範囲と、Requireディレクティブで指定されるアクセス許可の範囲との組み合わせ方について指定するディレクティブとなっている。

 たとえば。
ケース1:
 重要な情報なので、他部門からのアクセスは厳禁。社外からのアクセスももってのほか!社内のネットワーク、しかも自部門のIPアドレスからアクセスを許容するが、その中でも特に認証が通った利用者だけアクセス可能に!

 この場合は、
 if ( アクセス元は自部門のネットワークか? ){
  /* アドレスOK */
  if ( 認証が通ったか? ) {
    /* 認証OK */
    アクセスが許可される
  } else {
    /* 認証NG */
    ダメです!
  }
 } else {
  /* アドレスNG */
  ダメです!
 }

 とまあ、こんな感じのフローになるだろう。要するに、アドレスのチェックと認証のチェックが両方同時に満たされる必要がある場合。(AND条件)このようなケースでは、以下のような記述が必要となる。
Order Deny,Allow
Deny from All
Allow from (許可したいネットワーク)
Require (認証を通すユーザー)
Satisfy All

 「Satisfy All」の指定によって、ネットワーク的な条件と認証の条件と両方を満たさなければアクセスできないコンテンツが出来上がる。

 一方で…

ケース2:
 重要な条件なので、認証された人にしか見せないようにしたい。ただし、自部門のネットワークからアクセスしてきた人には認証を省略して見せるようにしたい。(だって…面倒くさいとかブーブー文句言われるんだもの…)みたいなケース。

 このような場合は、AllowとDenyで制御される範囲からは認証無しで。その他のネットワークからは認証された人だけアクセスできるようにしたい…ということになる。

Order Deny,Allow
Deny from All
Allow from (許可したいネットワーク)
Require (認証を通すユーザー)
Satisfy Any

 今度はこのように、「Satisfy Any」と記述する。こうすると、ネットワークの条件をみたすまたは認証が通るアクセスについてはコンテンツへのアクセスが許可されるようになる。(今度はOR条件)

 なお、前アーティクルでは特に「Satirfy」ディレクティブは使用していないが、このような場合デフォルトでは「Satisfy All」が指定されているものとみなされる。前アーティクルの場合は、

 ネットワークはどこからでも良い なおかつ 認証が通った場合

 という条件でアクセスが許可されている。ネットワーク的な条件は無いに等しいので、認証が通るか通らないかだけでアクセス制御が行われているということになる。

たぶん難しくないApache2・初期設定編その3~関係者以外立ち入り禁止~ [Linux(Apache)]

 これまでの設定作業で、どうにか「普通のWebサーバ」らしくなった気がするところまではこぎつけた。
 今度は、様々な「お好み」カスタマイズをしていくことにしよう。

 続いての設定内容は、許可された人だけがコンテンツへのアクセスができるようにする、いわゆる「認証」の仕組みを取り組んでいく。

 自宅でサーバを立てる理由の一つに、『仲間内だけでこっそりと、しかし自由に使える空間が欲しい』なんてこともあるだろう。あるいは、会社の部門内にサーバと立てたとして、他部門あるいは関係者にだけ閲覧を許可したい部分も出てくるのではないかと思う。
 すでに、IPアドレスやドメイン名(FQDN)でアクセスを許可・不許可とする仕組みがあることは紹介した。しかし、DHCPが運用されている環境では難しかったり、インターネットを経由してアクセスしてくる友人のIPアドレスがどれかなんてわかろうはずも無い。(いや、ちゃんと調べればわかるのだが…)

 そこで、「ID」と「パスワード」を発行し、この組み合わせの正しかった人だけに対してアクセスを許可する「(ユーザー)認証」によって、個人を識別し、その人がコンテンツへのアクセス権限を持つのかどうかを調べる方法を採用することになる。

 手順としては以下のような感じになるだろうか。
手順1:アクセスを制限するコンテンツを配置するディレクトリを決定する
手順2:認証を行うために必要な設定を導入する
手順3:認証時に使用するIDとパスワードを作成する
手順4:Apacheを起動してテストしてみる

手順1:アクセスを制限するコンテンツを配置するディレクトリを決定する

 ドキュメントルートの下に、アクセスを制限するコンテンツを配置するディレクトリを作成するところから始まる。まあ、普通に「mkdir」コマンドでディレクトリを作成すればよい。
 なお、「このサーバの全てのコンテンツには認証が必要です」という場合は、ドキュメントルートそのものに認証を導入することになるので、特に別途ディレクトリを用意する必要は無い。

手順2:認証を行うために必要な設定を導入する

 続いて、httpd.confにその設定を導入しよう。なお、(ユーザー)認証の仕組みとしてはいくつかの機構が用意されているが、ひとまずここではIDとパスワードとをファイルで管理するBASIC認証について解説することにしよう。

 ここで活躍するディレクティブは、ざっと以下のとおり。
AuthType Basic … 認証の仕組みを宣言する。ここでは「BASIC認証を使います!」と言っている
AuthBasicProvider file … BASIC認証時の、IDとパスワードを判別する仕組みを宣言する。ここでは「ファイルに保存されているものを使います!」と言っている
AuthUserFile (ファイルのパス名) … 上記で宣言した、IDとパスワードを記録したファイルの保存場所を指定する。
AuthName "(任意の文字列)" … 「認証領域」の名前を指定する。ブラウザのIDとパスワードを入力するダイアログに表示されることになり、利用者がどのIDとパスワードを入力すればよいか判断できるようにする。(タテマエ)
Require … どの認証済みユーザーがコンテンツへのアクセスを許可されるのかを指定する。認証された全てのユーザー(AuthUserFileディレクティブで指定されたファイルの中に記録されている全てのIDとパスワード)に対して許可する場合は「Require valid-user」と記述し、認証されたユーザーの中でも特定のユーザーにだけ許可したい場合は、そのIDを列挙する。「Require user userA userB userC ....」みたいな具合に。

また、注意すべきディレクティブとして忘れてはならないのは、既出の「Allow」「Deny」「Order」の他に加えて
Satisfy … AllowディレクティブとRequireディレクティブと両方が指定されている場合のアクセスポリシーを指定する。詳細は別途解説する。

 上記のディレクティブを、認証を必要とするコンテンツを配置しているディレクトリに対して設定を行うこととなる。

 ドキュメントルートが /var/www/html であり、認証を要求したいコンテンツが格納されているディレクトリが、 /var/www/html/auth_contents であるとしよう。この場合、
  ①ドキュメントルート配下、あるいは、auth_contents以外のディレクトリには自由にアクセスを認める
  ②ドキュメントルート配下ではあるが、auth_contentsディレクトリの下からは認証を要求する。
 という動作を指定することになる。

 ドキュメントルートに対する動作の指定がすでにある。
<Directory      /var/www/html>
        Order   Deny,Allow
        Allow from      All
</Directory>

 これに続けて、認証を要求するディレクトリに対する動作の指定を記述しよう。
 まず、忘れないうちにディレクトリを作成して… 「mkdir /var/www/html/auth_contents
<Directory      /var/www/html>
        Order   Deny,Allow
        Allow from      All
</Directory>

<Directory      /var/www/html/auth_contents>
	AuthType	Basic
	AuthBasicProvider	file
	AuthUserFile	auth/userauth
	AuthName	"Takamiya Shrine"
	Require 	valid-user
</Directory>

 こんな具合に書き足す。
 ちなみに、/var/www/html/auth_contentsに対してAllowとかDenyとか特に書いていないが、この場合はその親ディレクトリ「/var/www/html」に対する指定がそのまま引き継がれる。(つまり、AuthナントカとかRequireとかの指定が追加されるイメージ)

 AuthUserFileは、相対パス指定で記述しているが、これはすでに説明したとおり「サーバルート」からの相対パス指定になるので、実際に配置される場所は /etc/httpd/auth/userauth というフルパス名になる。(/etc/httpd/authというディレクトリはまだ存在しないので、 mkdir /etc/httpd/auth とか実行して作成する必要がある)
 なお、よく言われることであるが、AuthUserFileで指定されるファイルはドキュメントルートの配下に置くべきではない。可能な限り避けること。

手順3:認証時に使用するIDとパスワードを作成する

 次に、認証で使用するIDとパスワードを作成する。Apache2に標準添付の「htpasswd」というコマンドを使用する。使い方は、「htpasswd ファイル名 作成・編集するID」となる。
 ただし、はじめてIDを作成する(まだIDとパスワードを保存しているファイルが存在しない)場合には、「-c」オプションを指定しなければならないので注意を要する。
 また、さらに気をつけなければならないのは、すでにIDとパスワードが保存されているファイルがあるのに「-c」オプションをつけてしまうと、既存のファイルは破棄され、新しく1から作成されてしまうのである。「上書きしますか?」みたいな親切な質問はしてこないので厳重に注意すべし。

 というわけで、まず最初の一人目のアカウントを作成する。コマンドは「htpasswd -c /etc/httpd/auth/userauth tadao.hiiragi」と実行。
[root@kagami conf]# htpasswd -c /etc/httpd/auth/userauth tadao.hiiragi
New password:
Re-type new password:
Adding password for user tadao.hiiragi

 これでファイルが作成される。ちなみに中身はこんな感じ。
[root@kagami conf]# cat /etc/httpd/auth/userauth
tadao.hiiragi:FkvD.5oGaIm76

 二人目以降は「-c」を付けないで実行する。
[root@kagami conf]# htpasswd /etc/httpd/auth/userauth miki.hiiragi
New password:
Re-type new password:
Adding password for user miki.hiiragi
[root@kagami conf]# htpasswd /etc/httpd/auth/userauth inori.hiiragi
New password:
Re-type new password:
Adding password for user inori.hiiragi
[root@kagami conf]# htpasswd /etc/httpd/auth/userauth matsuri.hiiragi
New password:
Re-type new password:
Adding password for user matsuri.hiiragi

 こうして作成されたIDとパスワードのファイルはこんな具合になるだろう。
[root@kagami conf]# cat /etc/httpd/auth/userauth
tadao.hiiragi:FkvD.5oGaIm76
miki.hiiragi:f8VEXD0xp4dXI
inori.hiiragi:oipbVWsVT4qN6
matsuri.hiiragi:YykHU/0cnfbu2
kagami.hiiragi:BbchUr3onsYwQ
tsukasa.hiiragi:CJDK3zJn6qNPU


手順4:Apacheを起動してテストしてみる

 …と、起動したいところであるが、モジュールの読み込み指定がまだ済んでいないので、このままではまだ起動できない。今回追加したディレクティブで使用するモジュールの宣言は以下のとおり。

LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authz_user_module modules/mod_authz_user.so

 この記述も書き足してやる必要がある。
 また、auth_contentsディレクトリの中に適当なhtmlファイルを置いてやる。中身はなんでも良い。

 これでhttpdをスタートしてチェックできる。
[root@kagami conf]# apachectl -t
Syntax OK
[root@kagami conf]# service httpd start
httpd を起動中:                                            [  OK  ]

 このとき、 http://server/ とだけ指定すれば特に認証などを求められることなくアクセスできるが、 http://server/auth_contents/ とか指定すると、IDとパスワードの入力を求められるダイアログが開くだろう。ここでは、htpasswdコマンドで作成したIDのどれかを入力し、対応するパスワードを入力することで、認証が行われ、許可されたコンテンツにアクセス出来るようになる。

 以上で、BASIC認証を使った、アクセス制御が可能となった。
 ここまでに作成したhttpd.confは以下のようになったはず。
ServerRoot      "/etc/httpd"
PidFile         run/httpd.pid
Listen          80
User            apache
Group           apache

ServerName      kagami.hiiragi.com:80
DocumentRoot    "/var/www/html"

LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_default_module modules/mod_authz_default.so
LoadModule dir_module modules/mod_dir.so
LoadModule mime_magic_module modules/mod_mime_magic.so

<Directory      />
        Order   Allow,Deny
        Deny from       All
</Directory>

<Directory      /var/www/html>
        Order   Deny,Allow
        Allow from      All
</Directory>

<Directory      /var/www/html/auth_contents>
        AuthType        Basic
        AuthBasicProvider       file
        AuthUserFile    auth/userauth
        AuthName        "Takamiya Shrine"
        Require         valid-user
</Directory>

<Files  ~       "^\.ht">
        Deny from       All
</Files>

DirectoryIndex  index.html
AddDefaultCharset       off
MimeMagicFile   conf/magic


たぶん難しくないApache2・初期設定編その2~普通のWebサーバらしく~ [Linux(Apache)]

 さて。これまでに設定した内容で、雰囲気的にWebサーバとして振舞っているような気がする設定は完了しているのだが、どう贔屓目に見てもまだまだ「足りない子」であることは否めない。(笑)そこで、今度は「ちゃんとできる子」に調ky…じゃないしつけを施したいと思う。


 試してもらった人なら、ツッコミどころが判っていると思うのだけども、

  1.「 http://server/ 」ではエラーになる。「 http://server/index.html 」といちいちファイルまで指定しなければならない
  2.ブラウザによっては日本語の文字がどう選択しても化け化けになる(ブラウザによっては普通に表示されちゃう)
  3.バイナリファイルをダウンロードするとファイルがなぜか壊れる

 と、なかなかの「足りない子」っぷりを発揮していると思う。(笑)
 これはひとえにhttpd.confに設定が足りないからに他ならない。ここでは、これらの問題を解決してゆきたいと思う。

 1.ファイル名を省略したら、「index.html」が表示されるようにする

 http://server/  とか、 http://server/directory/  とか指定すれば、なにがしかのhtmlページが表示されるのが、世の一般的なWebサーバとしての常識的な振る舞いであろうということは誰もが認めるところだと思う。そこで、目下調ky…じゃない設定中のWebサーバにもそれらしく振舞ってもらおうじゃないか。

 この場合には、「DirectoryIndex」ディレクティブを使用する。このディレクティブで、URLにディレクトリまでが指定されている場合に表示させる(ダウンロードさせる)ファイルを指定することができる。
 使い方は実に簡単で、httpd.confに

DirectoryIndex index.html

 とか書けばよい。
 ちなみに、このディレクティブには複数のファイル名を列挙することが出来る。例えば、「DirectoryIndex index.html main.html」とか書けば、そのディレクトリに「index.html」があればそれを表示させ、index.htmlが無い場合に、「main.html」があればそれを表示…ということになる。
 なお、このディレクティブにはCGIを指定することも可能で、CGIの動作環境が適切に用意されhttpd.confにも適切に指定されていれば、「DirectoryIndex index.cgi」とか指定することも可能だ。

 なお、詳細は後日別アーティクルで紹介するが、ディレクトリやロケーションごとにファイル名を変えることも可能である。


2.文字コードを正しく認識させる。

 賢いブラウザであれば、ブラウザ側が勝手にフォローしてくれるので困った事態にならなかったと思うが、そうでないブラウザもまだ多いんじゃないかと思うので、サーバとして文字コードを正しく認識するように、設定を追加しよう。
 ま、「あいきゃんすぴーくいんぐりっしゅおんりー」みたいなガイジンさんには無用の長物かもしれないが、そんな人はこんなblog読まないはずなので以下略。

 まず、apache2のバージョンによっては、htmlファイル内のmetaタグでどんな言語設定をしようとも、そんなの無視して英語だ!と宣言してしまう挙動をする困ったちゃんがいるので、この動作を抑止する。(apacheの2.2系以降は抑止された状態になっている…はず
 「AddDefaultCharset off」というディレクティブを追加する。これで、なんでもかんでも英語化されてしまうことを抑止できる。(2.2以降はすでにこの設定になっている)


3.ファイルのMIMEタイプを正しく認識させる

 ファイルの内容に応じて、「MIME(マイム)タイプ」という情報をWebサーバ側に設定しておくことで、クライアントの振る舞いを規定することができるのだが、逆を言えばこの指定が無ければクライアントはトンチンカンな挙動をしてしまうかもしれない。(クライアント側のブラウザが賢ければ何事も無かったかのように振舞うかもしれない)

 で、サーバ側にMIMEタイプを正しく認識させる必要性に迫られるのだが、これが簡単な話ではないのだ。(いや、簡単に解決させるのであるが…)というのも、「MIMEタイプ」はすでに大量に存在する上に、次々と新しいものが作られているからやっかいなのである。つまり、Webサーバの管理者はそれらをいちいちメンテナンスしていかないと、サーバの利用者からいろいろ文句を言われてしまうかもしれない…ということなのである。

 が、世の中にはありがたい人がいて、それを簡単に解決するようにその仕組みを準備してくれたのである。それが「mod_mime_magic」というモジュール。
 yumでapacheをインストールすると、httpd.confと同じディレクトリに「magic」というファイルが作成されていたことに気がついただろうか。これをhttpd.confの中から読み込ませてやると、これらの問題がいとも簡単に解決してしまうのであった。ありがたやありがたや…

 で、その記述はたったの1行。「MimeMagicFile conf/magic」と書くだけ。これでたいていのファイルは正しくダウンロードできるようになる。もし、オリジナルのファイルを配布したい場合は、「AddType」ディレクティブや「AddEncoding」ディレクティブをhttpd.confの中に追記することで対応可能となる…が、このblogを見に来る人がそこまで要求するとも思えないので詳細な解説はここでは割愛する。(笑)

#どうしても今すぐやりたいならzipで圧縮するとかして対応すれば、小難しいことは必要ないはず。

そんな訳で、ここまでに完成したhttpd.confを以下に示そう。
[root@kagami conf]# cat httpd.conf
ServerRoot      "/etc/httpd"
PidFile         run/httpd.pid
Listen          80
User            apache
Group           apache

ServerName      kagami.hiiragi.com:80
DocumentRoot    "/var/www/html"

LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_default_module modules/mod_authz_default.so
LoadModule dir_module modules/mod_dir.so
LoadModule mime_magic_module modules/mod_mime_magic.so

<Directory      />
        Order   Allow,Deny
        Deny from       All
</Directory>

<Directory      /var/www/html>
        Order   Deny,Allow
        Allow from      All
</Directory>

<Files  ~       "^\.ht">
        Deny from       All
</Files>

DirectoryIndex  index.html
AddDefaultCharset       off
MimeMagicFile   conf/magic

たぶん難しくないApache2・初期設定編その1~お触りはダメよ!~ [Linux(Apache)]

 httpd.confの設定に入る前に、最初に大切な用語の意味を整理しておく。

 「サーバルート」(ServerRoot)とは、Apacheが使用するさまざまなファイルが保存されているディレクトリツリーの「てっぺん」を意味する。httpd.confの中等で、相対パスで記述することがあるが、その時はこの「サーバルート」を基点にしてのパス指定になっていることに注意すべし。
 たとえば、先の『最小のhttpd.conf』の中にあった、「PidFile run/httpd.pid」という記述。これはサーバルートと組み合わせることで、実際には /etc/httpd/run/httpd.pid というフルパス名になるのである。

 「ドキュメントルート」(DocumentRoot)とは、実際に外部に公開するhtmlファイルとか画像ファイルとかのドキュメントデータを保存しているディレクトリの「てっぺん」を意味する。
 たとえば、ドキュメントルートが /var/www/html に指定されているとして、 http://server/index.html というファイルをアクセスしてきた場合、実際に提供されるファイルは原則的に /var/www/html/index.html ということになるし、 http://server/directoryA/page.html だったとしたら、実際に提供されるファイルは原則的に /var/www/html/directoryA/page.html ということになる。
 ちなみに、いちいち「原則的に」と強調しているのは、この原則論はあとから曲げることができるからであ~る。

 「ディレクティブ」という言葉が出てくることとなる。これは、それぞれの「設定項目(設定名)」のことを言っていると思ってもらってよいと思う。(厳密には違う…といわれるのだけども)たとえば、サーバルートを指定する部分は「ServerRootディレクティブ」というし、Apacheが接続を待ち受けるポート番号を指定する部分は「Listenディレクティブ」ということとなる。



 ざっくりと用語の説明をしたところで、いよいよhttpd.confの内容に入る。

 設定項目として記述したい内容としては、
  防御のための指定
  便利に使うための指定
  その他の指定
 と、おおざっぱに3種類に分かれると思う。
 まずは、「防御のための指定」を先の『最小のhttpd.conf』に書き足していこうと思う。

 『Webサーバを公開する』といっても、そこには当然見せてもよいファイル見せたくないファイルとが存在する。Webコンテンツデータは前者だろうし、サーバの設定ファイルなどは後者だろう。あるいは、特定の人には見せてもよいが、その他の人には見せたくないファイルもあるだろう。関係者・関係部門だけがアクセスできるWebコンテンツとか。そういった、アクセスの許可・不許可の設定が特に重要になるのだが、そんなのはお構いなしに、とにかく見せたくないファイル(ディレクトリ)について、一様に防御してしまう設定をまずは導入しようと思う。

 ①まず、サーバ全体を一旦「とにかく全部アクセス禁止!」にしてしまう。
 ドキュメントルートの中に公開したいWebコンテンツデータを保存するのだが、裏を返せばドキュメントルートの”外”は公開したくないということになろうか。そのため、

 全体を不許可
 ↓
 でもドキュメントルートの下だけは許可

 という形でガードすることとなる。
 『全体』を不許可  ということだが、ドキュメントルート(ここでは/var/www/html)は許可ということなので、『全体』とはサーバのファイルシステムの「てっぺん」を指定する。つまり…

 「/

 これが『全体』を意味することになる。ルートディレクトリに対する指定を記述するディレクティブは、「<Directory>」ディレクティブを用いる。これは「</Directory>」とセットで用い、この2つのディレクティブで囲まれた範囲内が、その指定されたディレクトリと、サブディレクトリに対して影響を及ぼすこととなる。

<Directory  (指定したいディレクトリ)>
  「指定したいディレクトリ」に及ぼしたい設定内容
    :
    :
</Directory>

 こんな具合。
 で、今回活躍する、「アクセス許可」「アクセス不許可」を指定するディレクティブは
  Allow from
  Deny from
 前者が「許可」。後者が「不許可」を指定する。
 fromに続けて単独のIPアドレス、IPアドレスの範囲、単独のドメイン名、ドメイン名の一部などを記述します。
 また、IPアドレスなどの代わりに「All」を記述すると、「全部」を指定したこととなります。つまり、「Allow from All」ならば「どこからのアクセスもすべて許可」だし、「Deny from All」なら「どこからのアクセスすべて不許可」ということに。

 ルートディレクトリに対するアクセス制御は「全部不許可」なので、

<Directory  />
  Deny from All
</Directory>

 という記述をすればよいことがわかると思う。なお、同一のディレクトリに対してDenyとAllowと両方を組み合わせてアクセス制御をする場合には、「Order」ディレクティブの指定が重要になってくるが、どちらか片方しか記述しないのであれば、とりあえずOrderディレクティブについては意識しなくてもさしたる問題になることはないはず。
 気になるようなら、

<Directory  />
  Order Allow,Deny
  Deny from All
</Directory>

 とでもしておけばよいだろう。


 ②続いて、ドキュメントルート配下を「アクセス許可」にする。
 ルートディレクトリからアクセス禁止にしたままでは、ドキュメントルートまでアクセス禁止の状態になってしまいWebサーバとして用を成さないので、ドキュメントルートの下はアクセスを明示的に許可しなければならなくなる。

 ドキュメントルート、すなわち /var/www/html の下にあるファイル、サブディレクトリは許可ということなので、

<Directory  /var/www/html>
  Allow from All
</Directory>

 という記述を行う。
 で、問題になるのはコレを記述する位置。くれぐれも、「<Directory  />」ディレクティブの中に入れ子にしてしまわないように!ドキュメントルートに対するアクセス許可は、ルートディレクトリに対するアクセス不許可の指定の外側に記述する。つまりこんな感じ。

<Directory  />
  Order Allow,Deny
  Deny from All
</Directory>

<Directory  /var/www/html>
  Allow from All
</Directory>

 これで、ルートディレクトリ配下は全部アクセス禁止だが、ドキュメントルートだけは許可という状態にできる。

 さて。これでドキュメントルートの中にある公開したいファイルだけをアクセス許可にする設定ができた…と思いたいところだが、残念なことにまだリスクが残っている。
 今はまだ使わないし意識していないが、「.htaccess」というファイルの存在がある。このファイルは、本来httpd.confの中で指定すべき設定項目を、ディレクトリ単位で設定を外出し出来るもので、多くの場合はアクセス認証の設定とか、CGIの動作とか、部分的にアクセス制御を変更したりするために用いられる。
 ドキュメントルートの中で動作の細かな変更を行うので、普通はドキュメントルートの中に置かれるのであるが、一般的には公開したくないファイルなのである。

 ドキュメントルートは公開する → でも、.htaccessは公開したくない

 難儀な存在である…。

 そこで、今度はファイル単位のアクセス制御を行う必要が生じる。(さっきはディレクトリ単位であった)用いるディレクティブは「<Files>」である。ちなみにこれも「</Files>」とペアで用いる。
 .htaccessをアクセス禁止にする場合は

<Files  .htaccess>
  Order Allow,Deny
  Deny from All
</Files>

 と、なるのであるが、一般的によく用いられる指定方法としては

<Files  ~  "\.ht">
  Order Allow,Deny
  Deny from All
</Files>

 という方式。正規表現を用いて、「.htナントカ」というファイルはアクセス禁止よ!  という指定にしている。(これは後で登場する、Basic認証のパスワードを記述したファイルもまとめてアクセス禁止にしたい場合などを想定しているのだと思う)

 ちなみに、このFilesディレクティブも、Directoryディレクティブと同様に入れ子にせず、並べて記述するように。

 そんな訳で、今回とりあえずhttpd.confに追加したい指定はざっと以下のとおりとなる。

<Directory  />
  Order Allow,Deny
  Deny from All
</Directory>

<Directory  /var/www/html>
  Allow from All
</Directory>

<Files  ~  "\.ht">
  Order Allow,Deny
  Deny from All
</Files>

 まずは全体的にアクセス禁止!!
 ↓
 でもドキュメントルートの下はアクセス許可
 ↓
 ただし「.htナントカ」はどこにあってもアクセス禁止!!

 という指定が行われることが理解できるだろうか。

 さっそくこの記述を、前回紹介した『最小のhttpd.conf』に追記してみよう。
[root@kagami conf]# cat httpd.conf
ServerRoot      "/etc/httpd"
PidFile         run/httpd.pid
Listen          80
User            apache
Group           apache

ServerName      kagami.hiiragi.com:80
DocumentRoot    "/var/www/html"

<Directory      />
        Order   Allow,Deny
        Deny from       All
</Directory>

<Directory      /var/www/html>
        Allow from      All
</Directory>

<Files  ~       "\.ht">
        Order   Allow,Deny
        Deny from       All
</Files>

 ちなみに、httpd.confを記述したら書式などをチェックする方法があるので、忘れずに使うようにしたい。方法は、「apachectl -t」だ。記述ミスなどがあればだいたいはこれで事前にチェックできる。(文法的なチェックしかしてないようなので、すべてのミスがコレでチェックできるわけではない)

[root@kagami conf]# apachectl -t
Syntax error on line 11 of /etc/httpd/conf/httpd.conf:
Invalid command 'Order', perhaps misspelled or defined by a module not included in the server configuration

 と、エラーになった。「Order」ディレクティブを処理できるモジュールが足りないと言っている。

 実は、今回追加した、Allow、Deny、Orderディレクティブを正しく処理させるためには、Apacheの基本機能(coreモジュール)だけでなく、ソレ用のモジュールを別途読み込むように仕向ける必要があるのであった。
 登場するのは「mod_authz_host」というモジュール。

 Apacheは数多くの機能を持っているのだが、それは「モジュール」という形で提供されている。不要な機能を「全部入り」という形で実現しようとするとメモリを馬鹿食いするなど、弊害も大きいので、本当に基本的な機能だけをApache本体(httpd本体)に組み込み、その他の機能の大半はモジュールで提供している。
 今回のアクセス制御の機能も、「その他の機能」としてモジュールで提供されているのであった。

 というわけで、httpd.confに、「mod_authz_hostを読み込みなさい」という指定も必要になるのであった…

LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_default_module modules/mod_authz_default.so

 具体的には、この2行。実は、最初の1行だけでもよかったりするのだが、後々2行目が絡んできたりするので、今はこの2行を書き加えておくことをオススメする。

 これを書き加えたら、再度apachectl -tを実行してみよう。

[root@kagami conf]# apachectl -t
Syntax OK
[root@kagami conf]# service httpd start
httpd を起動中:                                            [  OK  ]
[root@kagami conf]# ps -ef | fgrep httpd
root      1804     1  0 18:29 ?        00:00:00 /usr/sbin/httpd
apache    1805  1804  0 18:29 ?        00:00:00 /usr/sbin/httpd
apache    1806  1804  0 18:29 ?        00:00:00 /usr/sbin/httpd
apache    1807  1804  0 18:29 ?        00:00:00 /usr/sbin/httpd
apache    1808  1804  0 18:29 ?        00:00:00 /usr/sbin/httpd
apache    1809  1804  0 18:29 ?        00:00:00 /usr/sbin/httpd
root      1812  1377  0 18:29 pts/0    00:00:00 fgrep httpd

 Apacheを起動するところまでやっている。
 これでドキュメントルートにあるコンテンツデータを安全に公開できる状態になっている。

 お好みに応じてファイルを置くとかしてアクセスして試してみて欲しい。



 次のアーティクルでは、現状、微妙に不便なところを直す設定を入れてみることにする。

たぶん難しくないApache2・インストール編 [Linux(Apache)]

 OpenVPN編がまだ終わっていないけども、調べ物に手間取っているので(笑)、次のお題「Apache2」に入っちゃおうかな。(笑)

 パソコンがアフォみたいに安くなったり、インターネット接続も光とかでぶっとくなっちゃったり、ダイナミックDNSサービスが使いやすくなったりで、「自宅にWebサーバを立てる」ということに対する敷居もずいぶんと低くなった今日この頃。
 ISPのホームページサービスとか、レンタルサーバを使って自分のWebサイトを作って公開している人とか、仲間内で気軽に使える空間を持っている人もそれなりにいると思うのだが、いろいろ制限があったりするので「自由に使えるサーバが欲しいなあ」と考える人もぼちぼちいるのではないかと思う。

 個人的には、セキュリティ的な観点から、十分な知識もないままにWebサーバを外部(インターネット)に公開することはオススメしないが、それでも「ど~しても」やりたいという人もいると思うので、ここでもいくつかのノウハウを紹介したいと思う。

 まあ、イントラネットとかで部門やチームの情報発信に…という程度の利用もあるかもしれないしね。



 さて。何はなくともサーバを用意する。このblogでもCentOSのセットアップについては紹介済みなので、サーバの用意についての紹介はそちらを参照してもらいたい。
 Webサーバにする手前、ntpくらいはインストールしておこう。sambaはいらない。
 また、ページのデータをサーバにコピーするため、ftpを使う人も多いと思うので、ftpdを入れておく。最小のセットアップではftpdは入ってこないので、vsftpdをさくっとインストールしておこうか。(お好みでproftpdとかでもいいと思うけど…)
[root@kagami ~]# yum search ftpd
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * addons: www.ftp.ne.jp
 * base: www.ftp.ne.jp
 * extras: www.ftp.ne.jp
 * updates: www.ftp.ne.jp
===================================== Matched: ftpd ======================================
vsftpd.i386 : vsftpd - 非常に安全な Ftp デーモン

 ということなので、yum install vsftpdを実行。デーモンを自動起動するため、chkconfig vsftpd onを実行し、さらに初回は手動で起動することになるので、service vsftpd startと実行しておこう。
 psコマンドでデーモンプロセスの起動を確認できればOK。
[root@kagami ~]# yum install vsftpd
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 (途中省略)
Installed:
  vsftpd.i386 0:2.0.5-16.el5

Complete!
[root@kagami ~]# chkconfig vsftpd on
[root@kagami ~]# service vsftpd start
vsftpd 用の vsftpd を起動中:                               [  OK  ]
[root@kagami ~]# ps -ef | fgrep ftpd
root      1519     1  0 11:55 ?        00:00:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
root      1522  1377  0 11:56 pts/0    00:00:00 fgrep ftpd


 次に、Webサーバをインストールする。世の中にはいくつか存在するが、ここでは「Apache2」を使用する。yumでインストールできるのだが、うっかりyum search apacheとか実行しようものなら、いろんなものがドバーっと表示されてびっくりするので注意されたし。(笑)
 実は、yum search httpdで見たほうがわかりやすかったりする。(笑)
[root@kagami ~]# yum search httpd
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * addons: ftp.iij.ad.jp
 * base: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
===================================== Matched: httpd =====================================
mod_ssl.i386 : Apache HTTP Server 用 SSL/TLS モジュール
system-config-httpd.noarch : Apache 設定ツール
centos-ds.i386 : CentOS Directory, Administration, and Console Suite
httpd.i386 : Apache HTTP Server
httpd-devel.i386 : Apache HTTP サーバー用の開発ツール。
httpd-manual.i386 : Apache HTTP サーバーのドキュメント。
mod_dav_svn.i386 : Subversion サーバー用の Apache サーバーモジュール。

 というわけで、「Apache HTTP Server」が必要なので、「httpd.i386」(あるいは「httpd.x86_64」とか)をインストールする。これ以外にも「mod_」で始まる追加モジュールがあるのだが、ひとまずここでは使用しないので、「httpd」だけをインストールするだけでよい。
 yum install httpdを実行しよう。
[root@kagami ~]# yum install httpd
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * addons: ftp.jaist.ac.jp
 * base: ftp.jaist.ac.jp
 * extras: ftp.jaist.ac.jp
 * updates: ftp.jaist.ac.jp
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package httpd.i386 0:2.2.3-31.el5.centos.2 set to be updated
--> Processing Dependency: libapr-1.so.0 for package: httpd
--> Processing Dependency: libaprutil-1.so.0 for package: httpd
--> Running transaction check
---> Package apr.i386 0:1.2.7-11.el5_3.1 set to be updated
---> Package apr-util.i386 0:1.2.7-7.el5_3.2 set to be updated
--> Processing Dependency: libpq.so.4 for package: apr-util
--> Running transaction check
---> Package postgresql-libs.i386 0:8.1.18-2.el5_4.1 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

==========================================================================================
 Package                 Arch         Version                       Repository       Size
==========================================================================================
Installing:
 httpd                   i386         2.2.3-31.el5.centos.2         updates         1.2 M
Installing for dependencies:
 apr                     i386         1.2.7-11.el5_3.1              base            123 k
 apr-util                i386         1.2.7-7.el5_3.2               base             76 k
 postgresql-libs         i386         8.1.18-2.el5_4.1              updates         196 k

Transaction Summary
==========================================================================================
Install      4 Package(s)
Update       0 Package(s)
Remove       0 Package(s)

Total download size: 1.6 M
Is this ok [y/N]: y
Downloading Packages:
(1/4): apr-util-1.2.7-7.el5_3.2.i386.rpm                           |  76 kB     00:00
(2/4): apr-1.2.7-11.el5_3.1.i386.rpm                               | 123 kB     00:00
(3/4): postgresql-libs-8.1.18-2.el5_4.1.i386.rpm                   | 196 kB     00:00
(4/4): httpd-2.2.3-31.el5.centos.2.i386.rpm                        | 1.2 MB     00:00
------------------------------------------------------------------------------------------
Total                                                     2.8 MB/s | 1.6 MB     00:00
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing     : apr                                                                1/4
  Installing     : postgresql-libs                                                    2/4
  Installing     : apr-util                                                           3/4
  Installing     : httpd                                                              4/4

Installed:
  httpd.i386 0:2.2.3-31.el5.centos.2

Dependency Installed:
  apr.i386 0:1.2.7-11.el5_3.1                     apr-util.i386 0:1.2.7-7.el5_3.2
  postgresql-libs.i386 0:8.1.18-2.el5_4.1

Complete!


 インストールが済んだら、chkconfigしてserviceして…と行きたいところだが、初期設定をする必要があるので、まだここでは起動の準備は行わない。

 yumでインストールした場合の初期設定についは、/etc/httpd/conf/httpd.conf、あるいは/etc/httpd/conf.d/*.confを使用する。一般的に、「/etc/httpd/conf」はApache本体の設定を、「/etc/httpd/conf.d」は追加モジュールの設定を記述するのがセオリーになっている。(気にしない人もいる)

 軽く、/etc/httpd/conf/httpd.confの中身を覗いてみておいて欲しいが、1000行近い巨大なファイルでうんざりする。(笑)ご丁寧にコメントが記述されているので設定項目が1000個もあるわけではないが、ぱっと身でどれが必要でどれが不要なのかさっぱりわからん!と思ってしまうかもしれない。(笑)

 ちなみに、「ど~しても書かなきゃいけない内容」ってのは、実はこんだけしかないのである。(笑)
[root@kagami conf]# cat httpd.conf
ServerRoot      "/etc/httpd"
PidFile         run/httpd.pid
Listen          80
User            apache
Group           apache

ServerName      kagami.hiiragi.com:80
DocumentRoot    "/var/www/html"

 最低、これだけ記述すればhttpdは起動して何らかのhtmlファイルが見えたりするのである。
 ただ、これだけでは、あまりにも不便だったり、セキュリティ的にどうなの!?みたいなことがあるので、適宜必要な設定を追加してそれなりに使えるように調ky…ゲフンゲフン…設定してやる必要があるのである。(笑)

 次のアーティクルでは、このhttpd.confについてもうちょっと掘り下げて説明したいと思う。
- | 次の10件 Linux(Apache) ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。