0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Apache】<Directory>とHostヘッダー制御によるIP制限を比較検証

Posted at

Webサーバーを運用していると、特定のディレクトリやドメインに対してIPアドレスベースのアクセス制限をかけたい場面がよくあります。Apacheでは、<Directory>ディレクティブを使った传统的なIP制限と、SetEnvIfRequireを組み合わせたHostヘッダーベースの柔軟なIP制限が利用できます。

しかし、もしこの二つの設定が同じディレクトリに対して重複して記述されていたら、一体どのような挙動になるのでしょうか?片方の設定がもう片方を上書きするのか、それとも両方が考慮されるのか。

今回は、この疑問を解消すべく、実際のApache設定ファイルを使って検証を行いました。

検証対象のApache設定

※ドメインとIPアドレスは例示用のものに変換しています。

以下が今回の検証の元となる設定ファイルです。一つのVirtualHosttest.example.com(公開用)とdev-test.example.com(開発用)という二つのドメインが割り当てられています。

この設定には、2種類のIP制限が記述されています。

  1. ドキュメントルートへのIP制御 (Order deny,allow): ディレクトリ /var/www/html/test-site 全体に対して、特定のIP (192.0.2.1127.0.0.1) のみを許可する設定です。
  2. HostヘッダーごとのIP制御 (SetEnvIfRequire):
    • test.example.com へのアクセスは、環境変数 IS_PUBLIC_HOST が設定され、IPに関係なく全員に許可されます。
    • dev-test.example.com へのアクセスは、環境変数 IS_INTERNAL_HOST が設定され、指定されたIPのみが許可されます。
<VirtualHost *:80>
    ServerName test.example.com
    ServerAlias dev-test.example.com

    DocumentRoot "/var/www/html/test-site"
    ErrorLog "logs/test-site-error.log"
    CustomLog "logs/test-site-access.log" combined

    <Directory "/var/www/html/test-site">
        AllowOverride None
        Options Indexes FollowSymLinks

        # ① ドキュメントルートへのIP制御
        Order deny,allow
        Allow from 192.0.2.1/255.255.255.255
        Allow from 127.0.0.1/255.255.255.255
        Deny from all

        # ② Host ヘッダーごとのIP制御
        SetEnvIf Host "^test\.example\.com$"    IS_PUBLIC_HOST
        SetEnvIf Host "^dev-test\.example\.com$" IS_INTERNAL_HOST

        <RequireAny>
            # 条件A:「IS_PUBLIC_HOST」なら全員許可
            Require env IS_PUBLIC_HOST

            # 条件B:「IS_INTERNAL_HOST」かつ IPが一致すれば許可
            <RequireAll>
                Require env IS_INTERNAL_HOST
                <RequireAny>
                    Require ip 192.0.2.1
                    Require ip 127.0.0.1
                </RequireAny>
            </RequireAll>
        </RequireAny>
    </Directory>
</VirtualHost>

この設定では、test.example.com は全員に許可しつつ、ディレクトリ全体ではIPを制限するという矛盾した状態になっています。この重複がどう影響するのかを見ていきましょう。


検証1:HostヘッダーごとのIP制限のみでテスト

まず、本来の挙動を確認するため、①のドキュメントルートへのIP制御をコメントアウトし、②のHostヘッダーごとのIP制御のみが有効な状態でテストします。

期待される挙動

  • test.example.com: どのIPアドレスからでもアクセスできる (200 OK)。
  • dev-test.example.com: 許可されたIP (192.0.2.1) からのみアクセスでき、それ以外のIPからはアクセスが拒否される (403 Forbidden)。

実行結果

許可されたIP (192.0.2.1) からのアクセス

# 現在のグローバルIPを確認
$ curl ifconfig.me
192.0.2.1

# 公開用ドメインにアクセス
$ curl -I test.example.com
HTTP/1.1 200 OK
...

# 開発用ドメインにアクセス
$ curl -I dev-test.example.com
HTTP/1.1 200 OK
...

許可されていないIP (192.0.2.2) からのアクセス

# 現在のグローバルIPを確認
$ curl ifconfig.me
192.0.2.2

# 公開用ドメインにアクセス
$ curl -I test.example.com
HTTP/1.1 200 OK
...

# 開発用ドメインにアクセス
$ curl -I dev-test.example.com
HTTP/1.1 403 Forbidden
...

結果は期待通りでした。Hostヘッダーによる制御が正しく機能し、test.example.comはオープンに、dev-test.example.comはIP制限がかかっていることが確認できました。


検証2:ドキュメントルートとHostヘッダーのIP制限を両方有効にしてテスト

次に、最初の設定に戻し、①と②の両方のIP制限が有効な状態でテストします。

期待される挙動

Apacheの評価順序から、まずディレクトリ全体にかかっている①のOrder deny,allowが評価されると推測されます。この時点で許可されていないIPは弾かれるため、②のRequire env IS_PUBLIC_HOST(全員許可)という条件は評価される前にアクセスが拒否されるはずです。

つまり、どのドメインにアクセスしても、許可されたIPからしかアクセスできないと予想されます。

実行結果

許可されたIP (192.0.2.1) からのアクセス

# 現在のグローバルIPを確認
$ curl ifconfig.me
192.0.2.1

# 公開用ドメインにアクセス
$ curl -I test.example.com
HTTP/1.1 200 OK
...

# 開発用ドメインにアクセス
$ curl -I dev-test.example.com
HTTP/1.1 200 OK
...

許可されていないIP (192.0.2.2) からのアクセス

# 現在のグローバルIPを確認
$ curl ifconfig.me
192.0.2.2

# 公開用ドメインにアクセス
$ curl -I test.example.com
HTTP/1.1 403 Forbidden
...

# 開発用ドメインにアクセス
$ curl -I dev-test.example.com
HTTP/1.1 403 Forbidden
...

予想通り、許可されていないIPからのアクセスは、test.example.com(全員許可のはず)であっても403 Forbiddenとなりました。これは、より広い範囲(ディレクトリ全体)に適用されるOrder deny,allowの制限が優先されたためです。


結論

今回の検証から、<Directory>ディレクティブでIP制限をかけた場合、その中でHostヘッダーごとにIP制限を緩和するような設定(全員を許可するなど)を記述しても、それは無効になるということが分かりました。

つまり、最初の設定ファイルにあった二つのIP制限の記述は重複しており、実質的にはドキュメントルートへのIP制限のみが機能している状態でした。
Hostヘッダーごとの制御(特に公開用ドメインを全員に許可する部分)は意図通りに動作しないことが確認できます。
参考になったら幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?