おとといのエントリ「Apache 2.4にしたらコンテンツがForbiddenになった。そして直した」で「直した」と書いたけれど適当すぎたのでマジメに見なおしてみた。
参考
- mod_authz_core - Apache HTTP Server: https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html
- Apache 2.4 Require - どさにっき: http://ya.maya.st/d/201202c.html#s20120226_1
まず「Upgrading to 2.4 from 2.2 - Apache HTTP Server」を見ると2.2から2.4の変更で
2.2 configuration:
Order deny,allow
Deny from all
2.4 configuration:
Require all denied
になったり、
2.2 configuration:
Order allow,deny
Allow from all
2.4 configuration:
Require all granted
は分かったけれど、この場合はどういうことなんだろう。
2.2 configuration:
Order Deny,Allow
Deny from all
Allow from example.org
2.4 configuration:
Require host example.org
特定のIPアドレスやホストのアクセスを許可する事は分かったけれど、たとえばこういう感じで書いていた特定のIPアドレスやホストのアクセスを許可しない場合はどうしたらいいのだろう。
2.2 configuration:
Order Allow,Deny
Allow from all
Deny from example.org
Require Directiveを見ると、
Require [not] entity-name [entity-name] ...
否定は「not」とつければいいのかーということで、こういう風に書いてみた。
Require all granted
Require not host example.org
しかし、設定ファイルをチェックするとSyntax Errorが出る。
# apachectl configtest
AH00526: Syntax error on line 34 of /etc/apache2/sites-enabled/hoge.conf:
negative Require directive has no effect in <RequireAny> directive
Action 'configtest' failed.
The Apache error log may have more information.
どういう意味なのかな?と考えたけれど、 < RequireAll|Any|None> のディレクティブを省略した場合は < RequireAny> ディレクティブで囲まれた状態とみなされるそう。で、Anyだとどれかの選択になるので all grantedとnotだとnotの意味がなくって条件が成り立たない。ということだそう。
ということで上のアクセス制限を < RequireAll> できちんと囲んで書くとこうなる。
<RequireAll>
Require all granted
Require not host example.org
</RequireAll>
拒否の判定をする < RequireNone> ディレクティブと組み合わせた書き方だとこんな感じ。 < RequireNone> ディレクティブの中に書くときは、拒否の否定になるのでnotは不要。
<RequireAll>
Require all granted
<RequireNone>
Require host example.org
</RequireNone>
</RequireAll>
面倒だなーと思ったけど、振り返ってみると < RequireAny> がデフォルトということはマッチするものだけアクセスを許可、それ以外はアクセス拒否になるので、特定のホストやIPアドレスのみの許可だとこんな風に書ける。
Require host example.org
おおー!例に戻ってきた! なるほど、こういう意味だったのか!
まとめてみるとこんな感じ。
- 特定のホストやIPのみのアクセスを許可する場合は、 Require だけでOK。
- 特定のホストやIPのアクセスを拒否する場合は、きちんと < RequireAll> ディレクティブを書いてから書く。