Apache 2.4 系で IP アドレスなどのアクセスブロックをする方法


いつもは Nginx を使っているのですが、先日、超久しぶりに、オープンソース CMS concrete5 のサイトで、 Apache 案件があり、なおかつロードバランサー配下で IP 制限をかけてほしいという難題がきました。

concrete5 であれば、使用しているフレームワークの Symfony 側で、ロードバランサーの判断をしているので IP 制限を柔軟に設定できるのですが、非 CMS 領域でも IP 制限をかけてほしいと言われました。

後日のための備忘録メモです。

以前の Apache でサポートされていた

Order Deny,Allow
Deny from all
Allow from XXX.XXX.XXX.1
Allow from XXX.XXX.XXX.2

みたいなルールは Apache 2.4 系では Deprecated (廃止) になったので、

.htaccess や Apache config の Directory 内に新しく記述する方法のサンプルを集めました。

サンプルと解説

SetEnvIf Remote_Add "^192\.168\.255\.1$" loadbalancer
SetEnvIf X-Forwarded-For "^127\.0\.0\.1" allowed_access
SetEnvIf X-Forwarded-For "^127\.0\.0\.1" allowed_access
SetEnvIf X-Forwarded-For "^127\.0\.0\.2" allowed_access

<RequireAny>
    <RequireAll>
        Require env loadbalancer
        Require env allowed_access
    </RequireAll>
    Require ip 10.0.0.1
    Require ip 10.0.0.1/16
    <RequireAll>
        Require ip 192.168.0.0/28
        Require not ip 192.168.0.2
    </RequireAll>

    <RequireNone>
        Require ip 10.0.0.10
    </RequireNone>
</RequireAny>

1行目: loadbalancer 環境変数設定

このIPアドレスはロードバランサーなので loadbalancer 環境変数を 1 or true にセットする。

基本的に、1行1条件だが、RequireAny の中に RequireAll や RequreNone があれば、それらのカッコ範囲を1条件として考える。

2~4行目: ロードバランサーを介したアクセスの大元の IP アドレスで allowed_access 環境変数設定

一般的なロードバランサーは、アクセス大元の IP アドレスを X-Forwarded-For ヘッダーに格納する。その X-Forwarded-For に格納された IP アドレスが特定のものであれば、allowed_access 環境変数を 1 or true にセットする。

ロードバランサーによって、ヘッダー名が変わってくる。さくらインターネットであれば、 X-Sakura-Forwarded-For となっているので、盛りているレンタルサーバーによっては気をつけること。

5,21行目: RequireAny

RequireAny の間にある条件を一つでもクリアしていたらTrue = アクセス可能。

7~10行目: RequireAll

この間は、すべて条件に合致していないと、ダメ。

Require env loadbalancer は、環境変数 loadbalancer が存在すること。Require env allowed_access は、環境変数 allowed_access が存在すること。

つまり、ロードバランサーのアクセスであれば、上記に設定した IP アドレスからのアクセスでないと行けない。

11~12行目: アクセス元の IP の制限

Require ip 10.0.0.1: 10.0.0.1 からの直接アクセスだけ受け付ける。
Require ip 10.0.0.1/16: のようにCIDRブロックを指定することもできる。

13~16行目: RequireAll 内で Yes and Not

Require ip 192.168.0.0/28: 192.168.0.0/28 の範囲の IP アドレスでかつ
Require not ip 192.168.0.2: 192.168.0.2 からのアクセスではないこと。

この not は RequireAll の中じゃないと使えない。

18~20行目: RequireNone

RequireAll の反対。どれにもマッチしなければ 1 (True) となる。
10.0.0.10 からのアクセスだとNG。

以上です。

Require には ipenv の他にも user, group なども使えるらしいです。

2.4 になって、結構複雑な IP 制限をかけられるな〜。Nginx っぽくなってきたなーと思ったのでした。

参考記事

https://httpd.apache.org/docs/2.4/ja/howto/auth.html
http://blog.matsumoto-r.jp/?p=3482
https://qiita.com/ngyuki/items/779ea21eec2ae6c450d5
https://qiita.com/KurosawaTsuyoshi/items/d9579c9c68666f086e68