Apache のアクセス制限

Apache を web server として使用している場合の、コンテンツのアクセス制限について解説します。アクセス制限の方法はいくつもありますが、基本的なモノから説明していきます。また、.htaccess file で使えるアクセス制限命令の多くは config file の中でも似たような使い方が出来ますが、ここでは自由度の高い .htaccess による方法を中心に説明します。なお、ここで書かれているのは自分で使ったものだけで、他のやり方もいくつかあるはずです。


Apache の初期設定

後の章で説明する .htaccess によるアクセス制限を行う場合には、Apache の設定ファイル(3つあるうちの access.conf。Apache 1.3.x の default では、3つまとめて httpd.conf になっています。また FreeBSD の package では apache.conf という名前です。以下では config file と表記します)で .htaccess の使用が許可されている必要があります。これは次のような記述で設定されています。


<Directory /usr/local/etc/httpd/htdocs>
 (中略)
# This controls which options the .htaccess files in directories can
# override. Can also be "All", or any combination of "Options", "FileInfo",
# "AuthConfig", and "Limit"

AllowOverride AuthConfig FileInfo Limit

 (中略)
</Directory>

# で始まっている行はコメントです。AllowOverride で、.htaccess に何を許すかを指定しています。コメントにも書いてある通り Options, FileInfo, AuthConfig, Limit の任意の組み合わせ、または All が指定できます。この例では、<Directory> で指定されている httpd/htdocs に対して AllowOverride Limit AuthConfig FileInfo を指示していますが、他のディレクトリに対する命令が他の部分に書いてあるかも知れません。そちらについても確認して下さい。逆に言えば、特定のディレクトリに対してのみ、.htaccess を有効にする事ができます。

それぞれの引き数には、次のような意味があります。

Options
CGI の実行、シンボリックリンクをたどるかどうか、などの制御を .htaccess で指定する事ができるようになります。
FileInfo
拡張子とファイルタイプの対応の指定や File 名置換などを、.htaccess で指定する事ができるようになります。
AuthConfig
ユーザー認証に関する指定を、.htaccess で指定する事ができるようになります。
Limit
アクセス制限に関する指定を、.htaccess で指定する事ができるようになります。
All
以上の全てを指定したのと同じ。

したがって、アクセス制限を行いたい場合には Limit が、ユーザー認証を行いたい場合にはさらに AuthConfig が指定されている必要があります。もちろん All が指定されていても大丈夫ですが、この場合にはユーザーによってセキュリティホールが作られる恐れがあります。

また、後で出てくるアクセス制限で domain name(の一部)を使用したい場合には、ホスト名を DNS に確認しに行かせる必要があります。これは config file が3つある場合にはさっきとは別の、httpd.conf(FreeBSD の場合には、さっきと同じ apache.conf)の次の行で設定されています。


# HostnameLookups: Log the names of clients or just their IP numbers
#   e.g.   www.apache.org (on) or 204.62.129.132 (off)
# You should probably turn this off unless you are going to actually
# use the information in your logs, or with a CGI.  Leaving this on
# can slow down access to your site.
HostNameLookups off

この "HostNameLookups off" を HostNameLookups on に変更すると、web page を見に来たマシンの domain name を、いちいち確認するようになります。

.htaccess によるアクセス制限

アクセス制限の命令は ".htaccess" という名前のファイルに書きます。基本的には、アクセス制限をかけたい file があるディレクトリにこの file を置きます。

ディレクトリ全体のアクセス制限(設定の確認)

config file の設定が確認できたら、いよいよ .htaccess を書いてみましょう。まずは最も単純な、.htaccess を置いてあるディレクトリに対する全てのアクセスを禁止するパターンです。まずはアクセス制限をかけるディレクトリ(ちゃんとアクセス出来るに .htaccess という名前の、次のような内容のファイルを作ります。


order deny,allow
deny from all

注:後の説明で出てくる allow は、ここでは省略されています。

これが出来たら、ブラウザからそのディレクトリにアクセスしてみましょう。"forbidden" という返事が返ってくれば成功です。うまく行かなかった場合には、Apache の初期設定をもう一度確認してみて下さい。

domain name または IP address によるアクセス制限

特定の domain からのアクセスを制限するためには、deny や allow を使って相手を指定します。次のような .htacccess では、inu-u.ac.jp domain と dog.co.jp domain からのアクセスだけを許可します。


order deny,allow
deny from all
allow from .inu-u.ac.jp .dog.co.jp

最初の order 行では、deny と allow がどういう順番で書いてあるかを宣言しています。ただし、order deny,allow,deny などと、3つ以上を並べる事は出来ません。そして deny from all で一旦全てのマシン (all) からのアクセスを禁止します。さらに allow from inu-u.ac.jp dog.co.jp で inu-u.ac.jp または dog.co.jp という文字列を domain name に含むマシンからのアクセスを許可しています。つまりこの場合、wan.inu-u.ac.jp, canine.inu-u.ac.jp, hund.dog.co.jp, canine.wanwan.dog.co.jp などからのアクセスは、全て許可されます。

domain name ではなく IP address で制限する場合も同様です。ただし IP address の場合には、次の4通りの書き方が出来ます。

IP address
130.34.152.134 のように、ある IP address をモロに書きます。
IP address の一部
130.34.152 のように、ある IP address の先頭から 3 byte を書きます。この場合、130.34.152.* 全体を指定した事になります。
IP address/netmask
130.34.152.0/255.255.255.192 のように、IP address と subnet mask をペアにして指定します。この場合には 130.34.152.0-63 を指定した事になります。
IP address/CIDR specification
130.34.152.0/26 のように、network address 部分の bit 数を指定する。この場合には 130.34.152.0-63 を指定した事になります。

domain name による指定と IP address による指定は混在させる事が出来ます。したがって、次のような allow 行(または deny 行)の指定が可能です。


order deny,allow
deny from all
allow from 130.34.152/26 130.34.152.192/255.255.255.192 .dog.co.jp

念のため、今までとは逆に特定のマシンからのアクセスのみを拒否したい場合の、.htaccess の例をあげておきます。


order allow,deny
allow from all
deny from 130.34.152/26 130.34.152.192/255.255.255.192 .dog.co.jp

order で指定した順番が逆になっている事、先に allow で全てのアクセスを許可した後に deny で特定のドメインからのアクセスを拒否している事に注意!

ファイル名によるアクセス制限

ディレクトリ全体にではなく、ディレクトリの中の特定のファイルだけにアクセス制限をかけるためには、.htaccess の記述に によるファイル名指定を追加します。例えば、wanwan.html に対するアクセスを全て禁止するためには、次のように記述した .htaccess を wanwan.html と同じ directory に置きます。


<Files wanwan.html>
order deny,allow
deny from all
allow from 130.34.152/26 130.34.152.192/255.255.255.192 .dog.co.jp
</Files>

これで、.htaccess と同じディレクトリにある wanwan.html にはアクセスが出来なくなります。同じディレクトリにある他のファイル(例えば index.html)には影響はありません。

Files に書くファイル名は、<Files *.html> というような書き方も出来ます。* は任意の文字列にマッチし、この場合は ".html" で終わる全てのファイルに対する指示になります。また <Files ~ "\.(gif|jpe?g|png)$">> のように ~ を付ける事によって、より拡張された正規表現を使う事も出来ます。この場合は .gif .jpeg .jpg .png のいずれかで終わるファイル名にマッチします。Apache 1.3.x では、"Files ~" の代わりに "FilesMatch" を使う事が出来ます。

なお Apache 1.3.x では、Files や FilesMatch に複数のファイル名を渡す事が出来ません。つまり <Files wanwan.html wan.html> などと書くと、Server Internal Error が発生します。

ID と password によるユーザー認証

UserFile と GroupFile

ID と password によりユーザー認証を行うためには、.htaccess 以外に UserFile と GroupFile を用意する必要があります。UserFile には user 名と暗号化された password を、GroupFile には group 名と user 名を、それぞれコロンで区切って書きます。UserFile と GroupFile の内容は、例えば次のようになります。

UserFile:

inu:sa3tHJ3/KuYvI
dog:oe54LuLkJSHoc
UserFile:
hund: inu dog

この例では、inu, dog という二人の user がいて、二人とも hund という group に属しています。password の暗号化については、Apache の動いているマシンで次のようなコマンドを実行すればできます。


% perl -e 'print crypt("password", "sa"), "\n"'
sa3tHJ3/KuYvI

"password" がパスワードの文字列、"sa" は任意の2文字です。"sa3tHJ3/KuYvI" が暗号化された password です。

UserFile と GroupFile は、任意の場所に任意の名前で置く事が出来ます。例えば /www/etc/userfile/www/etc/groupfile などです。ただし htdocs 以下に置くと通常のドキュメントとして読まれてしまうので、htdocs の外に置くべきです。

.htaccess での認証の指示

.htaccess でユーザー認証を指示するためには、例えば次のように記述します。


AuthUserFile /www/etc/userfile
AuthGroupfile /www/etc/groupfile
AuthName "Restricted Access Area"
AuthType Basic

Satisfy any
order deny,allow
deny from all
require user inu

最初の4行では、ユーザー認証に必要な情報を宣言しています。AuthUserFileAuthGroupfile では、さっき作った UserFile と GroupFile の場所を指定します。次の AuthName は、この .htaccess ファイルで指示した認証方法の名前です。任意の名前を付ける事ができます。この名前は、他の認証をクリアしたマシンと区別するために、この認証をクリアしたマシンに対するラベルとして使われます。最後の AuthType は認証機構の種別を指定しますが、現在の Apache では Basic 以外の選択肢はありません。

次の Satisfy では anyall のいずれかを指定できます。これは後ろに出てくる requireallow(ここでは省略されていますが)の関係を示します。any では requireallow のいずれかの条件を満たした時、all では requireallow の両方の条件を満たした時に、アクセスを許可する事になります。

oreder, deny については .htaccess によるアクセス制限の章で説明したのと同じです。

最後の require ではアクセスを許可する相手を指定します。ここでは inu という user にアクセスを許可しているので、dog という user はこのディレクトリにアクセスする事ができません。require では、group 単位で user を指定する事も出来ます。上の .htaccess の中で require 行を

require group hund

と書くと、hund という group に属する user、つまり inudog に対してアクセスを許可する事になります。

次にもう少し複雑な .htaccess の例を示します。


AuthUserFile /www/etc/userfile
AuthGroupfile /www/etc/groupfile
AuthName "Restricted Access Area"
AuthType Basic

<Files wanwan.html>
Satisfy all
order deny,allow
deny from all
allow from .dog.co.jp
require user inu
</Files>

この .htaccess では Satisfy all で require と allow の両方の条件を満たす事が求められています。したがって wanwan.html というファイルには、dog.co.jp domain にあるマシンからアクセスし、しかも inu という user の password を正しく入力した場合に限ります。

より詳細なアクセス制限(mod_rewrite の利用)

mod_rewrite は、本来ブラウザから指示された URL を内部的に書き換えるためのモジュールです。このモジュールはさまざまな環境変数を参照できるため、例えばある domain から Netscape Navigator version 2 で /index.html にアクセスした場合には、代わりに /mozzilla/index.html を見せる、とか、proxy を経由したアクセスに対しては常に /worning.html だけを見せるなどという事が出来ます。

mod_rewrite を利用するためには、このモジュールがコンパイルされて正しいディレクトリに install されていなければなりません。

mod_rewrite を使う環境の確認

まず mod_rewrite を使える環境になっているかどうか、確認しましょう。config file の中に、次のような行がそれぞれあるかどうかを確認して下さい。


LoadModule rewrite_module     libexec/apache/mod_rewrite.so

AddModule mod_rewrite.c

これらの行がない(別々の場所にあるはずですが)場合には、mod_rewrite を利用する事はできません。

mod_rewrite の設定

mod_rewrite の命令は、config file にも .htaccess にも書く事が出来ます。ただし .htaccess を /~dareka のような URL でアクセスできるディレクトリに置く場合には、少し異なった形式になります。これは後で説明します。

mod_rewrite の書式は、概ね次のような構造になっています。

  1. rewrite 機能を on にする。
  2. rewrite の対象とする相手の条件(IP address など)を指定する。
  3. どのような書き換えを行うかを指示する。

次の例では、IP address の上位 3 byte が 130.34.157、もしくはドメイン名に dog.co.jp が含まれるようなマシンからのアクセスに対して、URL の書き換えを行っています。


RewriteEngine on
RewriteCond %{REMOTE_ADDR}  130\.34\.152\.134
RewriteRule /admin/spool/index.html /spool/hoge.html

ただし .htaccess に記述する場合はちょっとだけ書き方が違っています。これは .htaccess は特定の(.htaccess が置かれた)directory の中身に対する指示だからで、/admin/spool/.htaccess で上記と同じ意味の命令を書くには


RewriteEngine on
RewriteCond %{REMOTE_ADDR}  130\.34\.152\.134
RewriteRule index.html /spool/hoge.html

のように RewriteRule 行の最初のファイル名の directory 部分を省略します。

1 行目の ResriteEngine on が rewrite 機能を on にする指示です。2行目の RewriteCond は、書き換えの対象にする相手の条件を指定します。%{} の中は、条件に当てはまるかどうかを確認する環境変数の名前です。2行目では REMOTE_ADDR つまりクライアントの IP address について条件をチェックする事になります。その後ろのスペースに続いてが条件式となります。上の例では 130.34.152.134 という IP address を持ったクライアントに対して書き換えを行います。そして3行目の ResriteRule で具体的な書き換えの内容を示し、/admin/spool/index.html というファイルの要求に対して /spool/hoge.html と書き換える(このファイルを見せる)事になります。

RewriteCond で参照できる環境変数(%{...} の中に指定できるもの)には、主に次のようなものがあります(良く使いそうなモノを pickup しました)。

HTTP ヘッダ
HTTP_USER_AGENT ブラウザの種類、version などの情報
HTTP_REFERER リンクをたどって来た場合のリンク元の URL
HTTP_PROXY_CONNECTION
HTTP_FORWARDED
HTTP_VIA
etc...
proxy を使用したアクセスの場合に設定されます。(必ずではない)
接続環境など
REMOTE_ADDR クライアントの IP address
REMOTE_HOST クライアントの domain name
REMOTE_USER 認証された user の名前(パスワード認証の後)
REQUEST_METHOD GET/POST のどちらが使われたか
SCRIPT_FILENAME CGI の file の、サーバー上での full path
PATH_INFO URL 上の path
QUERY_STRING GET の場合の変数部分 (URL encoded)
AUTH_TYPE 認証機構の種別

これらの変数の値に対する条件式には、正規表現を使う事も出来ます。

最後の RewriteRule の行では、具体的な書き換え内容を指示します。RewriteRule の直後にあるのが元の URL で、この path が要求された場合に最後のパートのファイルを返します。この「元の URL」でも正規表現が使えます。

また RewriteRule 行の最後にオプションを [ ] で囲んで追加する事が出来ます。複数のオプションを追加する場合には、カンマで区切ります。主なオプションには

F (forbidden)
アクセスを拒否
C (chained with next rule)
次の RewriteRule と連結します。つまり、この行で URL が一致しなければ次の RewriteRule はスキップされます。一致した場合は C オプションがない場合と同じ挙動になります。
NC (no case)
大文字と小文字を区別しないようにします。
S=num (skip next num rules)
num には整数が入ります。この行で URL が一致した場合に、続く num 個の RewriteRule をスキップします。
があります。

これらを総合すると、次のような RewriteRule 行がありえます。

RewriteRule /index.*.html /index.html
/index-en.html, /index-j.html などの要求に対して index.html を返す
RewriteRule /himitsu/.* /index.html
/himitsu ディレクトリ以下のファイル要求に対して、全て /index.html を返す(事実上、/himitsu についてのアクセス制限となる)
RewriteRule /himitsu/.* /index.html [NC]
RewriteRule /himitsu/.* / [F]
/himitsu ディレクトリ以下のファイル要求に対して Forbbiden を返す

この他にも「こんな場合はどうすんだ?」なんてのがあれば、お気軽にお知らせ下さい。(具体例が思い付かなかった)

/~dareka での設定

良くある設定(そして Apache の default でもある)では、/home/dareka/public_html 以下にあるファイルに、例えば http://host.name/~dareka/index.html などという URL でアクセスできます。また http://host.name/cgi-bin/hoge.cgi でアクセスできる cgi などは、実際には htdocs/cgi-bin/hoge.cgi にはありません。

これは apache の Alias 機能を使った結果です。本来なら htdocs 以外にある file へはアクセスできないはずなのですが、この Alias 機能を使う事によって別名(/~dareka など)を付けて便利にしている訳です。

Alias を使って access されるファイルに対して rewrite_mod を使う場合は、もう一つ別の命令を使う必要があります。RewriteBase という命令です。これは URL の Alias 相当部分を固定して、Alias 機能による file 名の読み替えによる影響を cancel するためです。

RewriteBase を使った場合、.htaccess の記述は次のようになります。


RewriteEngine on
RewriteCond %{REMOTE_ADDR}  130\.34\.152\.134
RewriteBase /~dareka
RewriteRule index.html /spool/hoge.html

このように RewriteBase を設定すると RewriteRule 行の "index.html" に /~dareka が 補完されます。つまりこの例では、http://host.name/~dareka/index.html というファイル要求に対して http://host.name/spool/hoge.html というファイルを返します。

上記の例のように path の先頭が "/" で始まる(つまり絶対 path が使われている)時には RewriteBase による path の補完は行われませんが、RewriteRule 行の "/" を消して


RewriteRule index.html spool/hoge.html

のようにすると、spool/hoge.html でも RewriteBase による path の補完が適用されます。つまり、http://host.name/~dareka/index.html というファイル要求に対して http://host.name/~dareka/spool/hoge.html(すなわち /home/dareka/public_html/spool/hoge.html)というファイルを返すことになります。


正規表現

mod_rewrite の正規表現では、次の文字が特殊文字としてそれぞれ意味を持ちます。
表現意味
.任意の一文字
[abc]a, b, c のうちの、どれか一文字
[^abc]a, b, c の以外の、どれか一文字
string1|string2string1 または string2
?直前の文字の0回または1回の出現ab?c → ac または abc
*直前の文字の任意回(0回でも良い)の出現ab*c → ac, abc, abbc, abbbc, ...
+直前の文字の任意回(1回以上)の出現ab+c → abc, abbc, abbbc, ...
(abc)グループ化して変数に格納(abc)hoge(def)hoge → $1=abc, $2=def
^行頭
$行末
\ここに出て来た表現を、その文字そのものとして扱う\? → ?
!行頭に付けて、「... でないもの」と一致!hoge → hoge 以外の全ての文字列

これだけでは分かりにくいと思うので、いくつか例示します。

^Mozilla.*
Mozilla/2.02 (Macintosh..., Mozilla/4.0 (compatible..., ...
130.34.152.1[123]
130.34.152.11, 130.34.152.12, 130.34.152.13
130.34.152.12[^3456789]
130.34.152.120, 130.34.152.121, 130.34.152.122
.*\.dog.co.jp$
hoge.dog.co.jp, are.dog.co.jp, dore.sore.dog.co.jp, ...
.*dog.co.jp$
hoge.dog.co.jp, inudog.co.jp, ...
.*\.i?nu-u.ac.jp
hoge.inu-u.ac.jp, hoge.nu-u.ac.jp, ...
.*\.i+nu-u.ac.jp
hoge.inu-u.ac.jp, hoge.iinu-u.ac.jp, hoge.iiinu-u.ac.jp.com, ...
!.*\.dog.co.jp
dog.co.jp domain 以外全部
([12]34)\.56\.7\.$1
134.45.7.134, 234.45.7.234
カッコの中に対応した文字列が $1 として使われるので、134.45.7.234, 234.45.7.134 は当てはまらない事に注意

もっと詳しく!

ここでは「何はともあれ、とりあえずアクセス制限をかけたい!」という追い詰められた人:)を対象に解説しました。したがって、より細かなオプションや設定、なぜこう書かないといけないのか、という情報については余り触れていません。より詳細な情報が欲しい方は、次の web page などを参考にすると良いでしょう。

JAPACHE HTTP Server Project
Apache のマニュアルなどの日本語訳を行っているプロジェクトです。特に rewrite_mod については、詳細な解説や、すぐに役立つ実例集などが参考になります。
環境変数のお話
HTTP で使われる各種の環境変数についての解説です。環境変数は数が多すぎて、ここでは説明できなかったので、参考にして下さい。

ご意見ご感想は「けいじわん」(WebBBS)へ
satodai@dog.intcul.tohoku.ac.jp