ELB配下のEC2のうち、1つだけをIPアドレス制限する
月花です。
またAWSでハマってあれやこれややったので備忘録です。
やりたかったけどできなかったこと
ELB配下に複数のEC2インスタンスがあり、うち1つだけをIPアドレス制限する。
セキュリティグループでできると勘違いしていたのだが、実際はELBからEC2の通信を許可している以上、ELBにアクセスできればEC2にアクセスできるため、セキュリティグループの変更では不可能だった。
また、該当のELBにEIPを紐付け、Route53から飛ばすことで、違うURLとはなるが、1基だけIPアドレス制限をしようとしたが、AWSにおいて証明書はELBかCloudFrontにしか結びつかないため、HTTPS接続ができなかった。
図にするとこうなっているためだ。
クライアント <--HTTPS--> ELB(証明書あり) <--HTTP--> EC2(証明書なし)
Apacheの設定を変更する
実際には.htaccessでやったが、httpd.confでやっても同じことと思われる。
X-Forwarded-For
筆者は全然知らなかったが、こういう名前のHTTPヘッダフィールドが存在する。
内容としては、クライアントのIPアドレスが入っている。
まさに、冒頭のような構成で、実際には負荷分散システムのIPアドレスでアクセスされてしまう際に使われるものだ。
一般的な負荷分散システムであれば、この値を引き渡してくれるらしい。
今回は、この値をホワイトリストとすることで解決した。
CIDR記法と正規表現
さきほどのX-Forwarded-Forの値をホワイトリストとして指定するにあたって、
xxx.xxx.xxx.xxx/26
といった、いわゆるCIDR記法は受け付けてくれない。
なので、このCIDR記法の範囲にあるIPアドレス全てを指定しなければならない。
ところがそれでは億劫なので、正規表現に変換してやる。
筆者は下記のサイトを使って変換した。
d.xenowire.net
このサイトで、許可したい正規表現を作って、それを指定する。
実際に記述する
先程の正規表現を使って、まずはホワイトリストの1件1件を定義する
SetEnvIf X-Forwarded-For "123\.45\.78\.(9[4-9]|[7-9][0-9]|1[0-1][0-9]|12[0-7])" allowed_ip1 SetEnvIf X-Forwarded-For "12\.3\.45\.(6[4-9]|[7-9][0-9]|1[0-1][0-9]|12[0-7])" allowed_ip2
2件あるならばこんな感じ。
「allowed_ip〜」の部分はエイリアスなので、好きな名前をつけよう。
そして、まず全てのアクセスを拒否、次に先程定義したものを許可する。
Order Deny,Allow Deny from All Allow from env=allowed_ip1 Allow from env=allowed_ip2
一連の流れとしては、
SetEnvIf X-Forwarded-For "123\.45\.78\.(9[4-9]|[7-9][0-9]|1[0-1][0-9]|12[0-7])" allowed_ip1 SetEnvIf X-Forwarded-For "12\.3\.45\.(6[4-9]|[7-9][0-9]|1[0-1][0-9]|12[0-7])" allowed_ip2 Order Deny,Allow Deny from All Allow from env=allowed_ip1 Allow from env=allowed_ip2
こうなる。
今回は.htaccessに書いたので、ディレクトリの指定はしていないが、httpd.confに書くときは、ディレクトリの指定が必要になる場合もある。
おわり。