実現したいことおよび背景
Apacheにて動作しているWebサーバ環境にて
Webアプリケーション側で、REMOTE_ADDR
環境変数を見てアクセス制御していたり
Apacheのログ(%h
)を使ってIPアドレス出力して、それを元に集計したり
アクセス制限したり(fail2banなど)している環境での話。
このような環境で、例えば前段にL7ロードバランサ入れたいとか
プロキシタイプのWAFを入れたい、とかなった場合。
そのままだと、REMOTE_ADDR
環境変数は、Apacheから見て直近のクライアントである
これらプロキシサーバのIPアドレスになってしまい
上記に記載したようなアクセス制限等が正しく動かなくなってしまう。
そこで、 REMOTE_ADDR
を クライアントIPに書き換えるミドルウェアを入れて解決する。
なお、前提として Apache2.2系の話。2.4系は別のものがあるらしいが詳しくは知らない。
mod_rpaf とは
オリジナルは Thomas Eibner という方が作った Apache モジュール。
上述のとおりプロキシサーバを経由するようなシステムにて
クライアントIPを X-Forwarded-For
ヘッダから取得して REMOTE_ADDR
に差し替えるという動作をする。
詳細はこちらの記事に詳しい。
https://heartbeats.jp/hbblog/2012/03/mod-rpaf.html
(本記事ではインストール方法や基本的な使い方には触れないので、この記事を参照してほしい)
ちなみに「rpaf」は「reverse proxy add forward」の略らしい。
なお、オリジナルの方のサイトはすでにアクセスできない状態になっている。
その後、mod_rpafは複数名の方が forkしている模様。
この記事で取り上げるmod_rpaf は、上記 HEARTBEATS 社ブログにある以下のものを指す。
https://github.com/ttkzw/mod_rpaf-0.6
プロキシサーバを複数通す場合の設定
この記事の本題。
プロキシサーバが間に1つしか挟まない場合は
上述HEARTBEATS社のブログにある設定ですべてこと足りる。
だが、複数のプロキシサーバを経由する場合は、もう少し追加の設定が必要になる。
具体的には:
- 経由するプロキシサーバのIPアドレスを
RPAFproxy_ips
に追加- 複数エントリは空白区切りで列挙
-
RPAFrecursive On
の設定を追加
こうすると、REMOTE_ADDR
には、X-Forwarded-For
ヘッダの
複数のIPアドレスを、末尾から順にたどり、
RPAFproxy_ips
に登録されていない 最初のIPを返すようになる。
(設定Offだと、単純に X-Forwarded-For
の末尾のエントリを返す)
例
No | サーバ等 | outboundのIPアドレス |
---|---|---|
1 | クライアントIP | 192.0.2.10 |
2 | プロキシサーバA | 10.0.0.20 |
3 | プロキシサーバB | 172.16.0.30 |
4 | Webサーバ | 192.168.0.40 |
として、1→2→3→4 と経由する場合。
(上記には本質ではないので記載してないが、No2のプロキシはグローバルIPを持っていて
No2~No4 は プライベートネットワークに閉じているとする)
まず、なにも設定しないとWebサーバが受け取るREMOTE_ADDR
、X-Forwarded-For
は以下のようになる。
X-Forwarded-For
: 192.0.2.10,10.0.0.20
REMOTE_ADDR
: 172.16.0.30 (No.3のもの)
次に、mod_rpafを導入、RPAFrecursive
を Off または設定しないと以下のようになる
X-Forwarded-For
: 192.0.2.10,10.0.0.20
REMOTE_ADDR
: 10.0.0.20 (No.2のもの。X-Forwarded-For
の末尾エントリ)
そして、RPAFrecursive On
とRPAFproxy_ips
に 10.0.0.20 172.16.0.30
を設定すると以下のようになる。
X-Forwarded-For
: 192.0.2.10,10.0.0.20
REMOTE_ADDR
: 192.0.2.10 (No.1のもの。X-Forwarded-For
で RPAFproxy_ipsに含まれない、もっとも末尾にあるエントリ)