herokuでhtaccessを使ってIPアドレスによる制限を設定する

herokuにて構築しているapacheアプリにて、特定のIPからしかアクセス出来ないようにするために、
htaccessにて制限をかけようとしてたのだけど、どうも上手くいかなくてハマったのでメモ。

通常だと、以下のようになる。

1
2
3
order deny,allow
deny from all
allow from 124.xx.xxx.xxx

この場合、制御は、拒否→許可、の順番で、
まず全て拒否して、124.xx.xxx.xxxからのアクセスのみ許可、という流れ。

しかし、herokuではこれでは上手くいかなかった。

というのも、herokuではサーバー側で負荷分散するためにロードバランサが使用されている。
(dynoが1の場合でも振り分けはされないけれど利用はされているみたい)
これによって、実際にアプリに到達するIPアドレスが、アクセス元のIPアドレスからロードバランサを経由したものに変わってしまう。
しかもそのIPは都度、変わってしまうよう。

これだとIPアドレスによる制限がかけられないのだけど、それを解決する仕組みとして、
X-FORWARDED-FOR という方法があるらしい。
X-Forwarded-For – Wikipedia

それを利用する事で、アクセス元のIPアドレスをロードバランサやプロキシを挟んだとしてもそのままアプリに通知する事が出来るようになるよう。

実際のコードは以下。

1
2
3
4
5
SetEnvIf X-Forwarded-For 124.xx.xxx.xxx allowip

order deny,allow
deny  from all
allow from env=allowip

allowipは変数名なのでなんでもよい。
こうやって記述することで、heroku上でも指定のIPアドレスのみ許可してやることが出来た。

指定のIPアドレスのみ拒否する場合も書き方は同じ。

1
2
3
4
5
SetEnvIf X-Forwarded-For 124.xx.xxx.xxx denyip

order allow,deny
allow from all
deny from env=denyip

複数指定する場合は、変数を複数定義してやるだけで大丈夫だった。

1
2
3
4
5
6
7
SetEnvIf X-Forwarded-For 124.xx.xxx.xxx allowip1
SetEnvIf X-Forwarded-For 196.xx.xxx.xxx allowip2

order deny,allow
deny  from all
allow from env=allowip1
allow from env=allowip2

また、これはロードバランサ利用に限った話ではないけれど、IPアドレスの範囲指定をした場合には、
CIDR(サイダー)形式での表記で書いてやると実現可能。
以下のツールで厳密な範囲指定をしてやることが出来る。

2つのIPアドレス範囲を厳密にCIDR化ツール | IPV46

参考

ロードバランサーやプロキシー経由でも.htaccessでのIPアドレスを制限したい場合
2つのIPアドレスの範囲をCIDRに厳密に変換するってどういう事? | IPV46


ちなみに、herokuアプリから外にアクセスする際のIPアドレスの固定方法は以下を参考に。
[heroku]QuotaGuard Staticを使ってHerokuでのIP固定を試してみる

   このエントリーをはてなブックマークに追加