CloudFront→ELB→EC2構成におけるIPアドレスのアクセス制御
AWSでCloudFront → ELB → EC2の構成を採用する場合に、IPアドレスによるアクセス制御を行う方法を説明します。
方法1: EC2上のWebサーバによるアクセス制御
CloudFrontやELBはリクエストを受けると x-forwarded-for
ヘッダにクライアントのIPアドレスを付与します。
このヘッダを利用してIPアドレスによるアクセス制御を実現できます。
CloudFrontとELBを組み合わせる場合は下記のようなヘッダを受け取ります。
クライアント ↓ CloudFront ↓ x-forwarded-for: <クライアントのIPアドレス> ELB ↓ x-forwarded-for: <クライアントのIPアドレス>, <CloudFrontエッジのIPアドレス> EC2
クライアントがヘッダを偽装した場合も考慮しておきましょう。もし、クライアントが x-forwarded-for
ヘッダを付けてアクセスした場合は下記のようになります。
クライアント ↓ x-forwarded-for: <クライアントが付けた内容> CloudFront ↓ x-forwarded-for: <クライアントが付けた内容>, <クライアントのIPアドレス> ELB ↓ x-forwarded-for: <クライアントが付けた内容>, <クライアントのIPアドレス>, <CloudFrontエッジのIPアドレス> EC2
したがって、 x-forwarded-for
ヘッダをカンマで区切って右から2番目の要素を取得すると、クライアントのIPアドレスを取り出すことができます。
Apacheを利用している場合は SetEnvIf
で正規表現を指定してIPアドレスをチェックします。例えば、 10.20.30.40
に対してアクセスを許可するには下記の設定になります。
<Directory "/var/www/html"> SetEnvIf x-forwarded-for "(:?^| )10\.20\.30\.40, [\d.]+$" permit_staging Order Deny,Allow Deny from all Allow from env=permit_staging </Directory>
Apache 2.4からはmod_remoteipモジュールが利用できますが、ヘッダの右から2番目の要素といった指定はできないようです。 クライアントがヘッダを偽装するケースを考慮すると、現時点では正規表現が安全と思います。
CloudFrontやELBが付与する x-forwarded-for
ヘッダの仕様は下記を参照してください。
方法2: WAFによるアクセス制御
CloudFrontにWAF(Web Application Firewall)のルールをアタッチすることで、IPアドレスによるアクセス制御を実現できます。 ただし、CloudFrontからELBにアクセスできるようにセキュリティグループを開けておく必要があります。 かなり広いIPアドレスブロックを開けておく必要があるため、攻撃者からELBに直接アクセスされるリスクがあります。