Access forbidden!
要求されたディレクトリへのアクセス権限がありません。 インデックスドキュメントが存在しないか、 ディレクトリの読み込みが許可されていません。
XAMPP のバージョンアップ後、localhost (サーバー機)以外のローカルネットワーク上のコンピュータやスマホからアクセスできなくなりました。面倒だったので、長らく古いバージョンを使っていましたが、そろそろ...というわけで、
最初はファイヤーウォールを疑っていたが全然改善せず、
上のメッセージを "C:\xampp\apache"
フォルダで grep 検索したところ、
"C:\xampp\apache\error\HTTP_FORBIDDEN.html.var"
に含まれていることがわかりました。
ということは、どうやら XAMPP からのエラーメッセージだろう...
つまり.....Apache からメッセージが送られている!
=ファイヤーウォールではなく、Apache の設定?.....
あれこれ情報を探し回った挙げ句、何時間も費やした愚行をくり返さないためにメモを残します。
この作業の結果、ネットワーク上のパソコンとスマホ1台からアクセス成功!
(他のスマホ2台はアクセス失敗だが、こちらは別の問題があるのかな、と)
全てアクセスできるようになりました!
1. Apache 2.4の設定(conf系)
認証・許可設定のところで重大な変更がいくつかあったため、Apache 2.2向けの設定ファイルを 2.4 に転用する前に、変更が必要になる場合がある。
(Apache 2.4 のドキュメントには、こう書かれていました!)
※ ここでいう「設定ファイル」とは、「httpd.conf」系のファイルや「.htaccess」などのこと。つまり、「ノーチェックで転用するな」ということ。
最初の失敗は、ここでした。2.2 用の設定を、ノーチェックで 2.4 に転用していました。
2.Order,Deny,Allow型と、Require型の混在
mod_access_compat モジュールが従来の Order,Deny,Allow
型のアクセスコントロールを引き続き可能にするが、2.4 で導入された mod_authz_core モジュール等で提供される「 Require
型と混在」させることは、予期せぬ動作を引き起こす恐れがあるので、技術的には可能ではあるものの、おすすめできないらしい。
Why httpd denies access ..... Because mod_access_compat directives take precedence over the mod_authz_host one in this configuration merge scenario.
mod_access_compat モジュールのディレクティブ(Order,Deny,Allow
)は、mod_authz_host のそれ(Require
)に優先する)
第2の失敗はここでした。ネットの情報を見て、やみくもにRequire all granted
を付け足しても解決しなかったのはそのせいです。しかし、どこにもOrder
,Deny
,Allow
が見当たらないのです!(これは後で解決します。)
参考までに、Require
ディレクティブの例を置いておきます。
mod_authz_core モジュールによる、Require ディレクティブの用法
mod_authz_host モジュールによる、Require ディレクティブの用法
失敗例も書いておきます。
Require local ip 192.168
Require local
Require ip 192.168
3. .htaccess ファイルが読み込まれない場合がある
.htaccess による設定変更を可能にする AllowOverride
ディレクティブの既定値(デフォルト)が、2.4(正確には2.3.9以降) では「None」に変更されたので、適切な <Directory>
セクション内で上書きしてやる必要がある。
※ XAMPP では <Directory "C:/xampp/htdocs">
セクション内で、
「AllowOverride All
」と上書きされているようだが、念のため、各バージョンごとに再確認する必要があろう。
4.ノーチェックで転用された古い httpd.conf 系ファイルや、古い .htaccess ファイル、あるいはノーチェックで上書きされたそれらの設定が悪さをしている場合がある
第3の失敗は、ここでした。Apache 2.2 用の古い .htaccess ファイルを "C:/xampp/htdocs"
にノーチェックでコピーしていました。
しかも、ここに「Order
系のディレクティブ」が書き込まれていたため、そのサブディレクトリに Require all granted
を書いても、親ディレクトリである "C:/xampp/htdocs"
からの「Order
」系の子ディレクトリへの継承が優先されていたのです!
関連するディレクティブの注意点を書いておきます。
4.1. AllowOverride
ディレクティブを置くセクション
AllowOverride
ディレクティブによって、アクセスコントロールを .htaccess ファイルで上書きできるようにできるが、この AllowOverride
ディレクティブは、各<Directory>
セクション内でしか設定することができないので、<DirectoryMatch>
, <Location>
, <Files>
などのセクションでは無効になってしまう。
4.2. AllowOverride
ディレクティブの設定値
AllowOverride
ディレクティブの設定値によっては、.htaccess ファイル内で使えるディレクティブを限定することができる。
-AllowOverride AuthConfig
… Require
系のディレクティブを .htaccess ファイルで使えるようにできる。
-AllowOverride Limit
… Order
, Deny
, Allow
ディレクティブを .htaccess ファイルで使えるようにできる。
4.3. AuthMerging
ディレクティブによる統合1
AuthMerging
ディレクティブにより、上位セクションから継承された許可設定と、そのセクションでの新たな許可設定とを、「一時的に統合」させることができる。(デフォルトは、AuthMerging Off
= 統合させない=上書きする)
(https://httpd.apache.org/docs/2.4/ja/mod/mod_authz_core.html#authmerging)
-AuthMerging And
… 上位セクションから継承された許可設定と、そのセクションでの新たな許可設定とを、あたかも <RequireAll> ~ </RequireAll>
で囲ったようになる。
-AuthMerging Or
… 上位セクションから継承された許可設定と、そのセクションでの新たな許可設定とを、あたかも <RequireAny> ~ </RequireAny>
で囲ったようになる。
※
<RequireAll> ~ </RequireAll>
… 全てが満たされれば「OK」
<RequireAny> ~ </RequireAny>
… いずれか1つが満たされれば「OK」
<RequireNone> ~ </RequireNone>
… いずれか1つが満たされれば「NG」=全てがNGなら「OK」
なお、これらで囲われていないのに複数の Require
ディレクティブが1つのセクションで使われた場合、暗黙のうちに、<RequireAny>
の中に入れられる。(いずれか1つが満たされれば「OK」となる。)
When multiple Require directives are used in a single configuration section and are not contained in another authorization directive like
<RequireAll>
, they are implicitly contained within a<RequireAny>
directive. (https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#Require)
下記の例(Apacheのドキュメントから丸写しです)では、アクセスできるのは、次の通り。
デイレクトリ | アクセスできるユーザー |
---|---|
/www/docs | グループ alpha |
/www/docs/ab | グループ alpha か beta |
/www/docs/ab/gamma | グループ gamma (デフォルトで上書きされる) |
<Directory "/www/docs">
AuthType Basic
AuthName Documents
AuthBasicProvider file
AuthUserFile "/usr/local/apache/passwd/passwords"
Require group alpha
</Directory>
<Directory "/www/docs/ab">
AuthMerging Or
Require group beta
</Directory>
<Directory "/www/docs/ab/gamma">
Require group gamma
</Directory>
4.4.(重要)各セクション(における設定)が、どのように統合1されるか
(https://httpd.apache.org/docs/2.4/en/sections.html#merging)
CSSのカスケード順位と同様かそれ以上に、
ディレクティブが適用される優先順位は大変重要です。
なぜなら、アクセス可否=サーバーのセキュリティに関わるからです。
そういうわけで、少しややこしいですが、なるべく詳しく書いておきます。
1.<Directory>
セクション
最初に、<Directory>
(正規表現を含まないもの)と、.htaccess (このファイルが置かれているディレクトリが AllowOverride
によって許可されていれば、<Directory>
の設定を上書きする)が同時に統合される。
※<Directory>
~ </Directory>
で囲まれたセクションの中にあるディレクティブは、そのディレクトリ、そのサブディレクトリ、とそれらに含まれるファイルに適用される。(ただし、ディレクトリのコンテキストで使うことを許可されているディレクティブに限る。)(https://httpd.apache.org/docs/2.4/en/mod/core.html#directory)
2.<DirectoryMatch>
(正規表現)セクション
次に、<DirectoryMatch>
と <Directory "~">
(正規表現を含むもの)が統合される。
3.<Files>
セクション
その次に、<Files>
と <FilesMatch>
が同時に統合される。
※<Files>
セクション中のディレクティブは、そのファイルがどのディレクトリ中にあるかにかかわらず、同じ名前のファイルすべてに適用されるが、特定のディレクトリ中のファイルだけに適用するために、<Directory>
セクションの中に <Files>
セクションを入れ子にすることができる。
(https://httpd.apache.org/docs/2.4/en/mod/core.html#files)
4.<Location>
セクション
さらにその次に、<Location>
と <LocationMatch>
が同時に統合される。
※<Location>
セクション中のディレクティブは、マッチするURLにだけ適用される。<Location>
セクションは、完全にファイルシステムの外で動作する。(そのため、)<Location>
セクションをファイルシステムへのアクセスコントロールに使うべきではない。異なるURLがファイルシステムの同じ場所にたどり着く可能性があるため、そのようなアクセスコントロールはすり抜けられる可能性がある。
(https://httpd.apache.org/docs/2.4/en/mod/core.html#location)
Locationセクションの例1(下記)
結果 | URL |
---|---|
○ | /private1 |
○ | /private1/ |
○ | /private1/file.txt |
× | /private1other |
<Location "/private1">
# ...
</Location>
Locationセクションの例2(下記)…スラッシュが後につく
結果 | URL |
---|---|
× | /private2 |
○ | /private2/ |
○ | /private2/file.txt |
× | /private2other |
<Location "/private2/">
# ...
</Location>
5.<If>
セクション
最後に、<If>
セクションに含まれるものが統合される。
【注意点】
● <Directory>
セクションと異なり、上の各1~5のグループの内部では、設定ファイル中に出てきた順番によってセクションが処理される。例えば、/foo/bar
へのリクエストが <Location "/foo/bar">
と <Location "/foo">
の2つのセクションにマッチする時、この2つのセクションが設定ファイルに現れる順に評価される。
● <Directory>
セクションは、ディレクトリの最も短い構成要素から、最も長いものへという順に処理される。
例えば、<Directory "/var/web/dir">
は、
<Directory "/var/web/dir/subdir">
の前に処理される。
●多数の <Directory>
セクションが、同じディレクトリに適用される場合は、設定ファイルの順に処理される。(訳注:「設定ファイルに現れる順に処理される。」ということでしょう。)
● Include
ディレクティブによってインクルードされた設定は、あたかも、Include
ディレクティブの場所にそれらがあるかのように扱われる。
● <VirtualHost>
セクションの中は、バーチャルホストの外の対応するセクションの後で適用される。これによって、バーチャルホストがメインサーバーの設定を上書きできるようになる。
●サーバーへのリクエストが mod_proxy によって提供される時は、<Proxy>
コンテナは、処理順に <Directory>
に取って代わる。
4.5.モジュールと設定セクションの関係
(https://httpd.apache.org/docs/2.4/en/sections.html#relationship-module-configuration)
この項目のリンクには、mod_rewrite のようなモジュールが及ぼす影響について、書かれてあります。<Location>
セクションを使わなければ特に必要無いでしょう。
4.6.有用な例
(https://httpd.apache.org/docs/2.4/en/sections.html#merge-examples)
次の例では、各ディレクティブの適用順は、A→B→C→D→E の順です。
<Location "/">
E
</Location>
<Files "f.html">
D
</Files>
<VirtualHost *>
<Directory "/a/b">
B
</Directory>
</VirtualHost>
<DirectoryMatch "^.*b$">
C
</DirectoryMatch>
<Directory "/a/b">
A
</Directory>
次の例では、<Location>
セクション(の設定)が最後に適用されるため、すべてのアクセスが許可されてしまいます。
セクション(の設定)が統合される順番はと~っても重要です。
<Location "/">
Require all granted
</Location>
# おっと! この後の <Directory> セクションは何の効果もありません。
# なぜなら、<Location> セクションが最後に適用され、すべてのアクセスが許可されてしまうからです!
<Directory "/">
<RequireAll>
Require all granted
Require not host badguy.example.com
</RequireAll>
</Directory>
5.終わりに
新バージョンのドキュメントは、ちゃんと読まないとダメですね。
5.1. 最終結果
さて、こうした奮闘の結果、
他のパソコン1台と、古いスマホ1台がXAMPPサーバーにアクセスできました。
しかし、同じルーターへ同じWi-Fi接続している
残り2台のスマホについては、どうやら各端末の「名前解決(DNS)」が問題との感触です。 ← 「サーバーが見つかりません」
どちらも、インターネットには接続できるので、通信はできるようです。
どうしたものかなあ...
全て、アクセスできるようになりました!
5.2. DNSサーバーの設定
残りのスマホがアクセスできなかった原因は、
DNSサーバーの設定でした。
今回のXAMPPバージョンアップは、「Windowsパソコンのリカバリー」に伴うものでした。
そのため、XAMPPの設定はコピペをしたのが原因でしたが、DNSサーバーの設定は保存していなかったため、一からテキトーに入力したのが災いしました。
DNSサーバーは、「簡易版(BlackJumboDog)」を使っているためか、設定の仕方がよくわかりませんでした。
Before - After をまとめると、こうなります。
結果 | サブドメインを設定 | 登録ドメイン | 備考 |
---|---|---|---|
× | www | private.test | 単独 |
○ | private | test | |
○ | www | private.test |
ちなみに、Windowsパソコンからアクセスできたのは、「hosts」ファイルを使っていたからDNSサーバーは無関係だったのでしょう。
古いスマホからアクセスできたのは、「古かったから」?