S3 + CloudFront で静的サイトホスティング時にAWS WAFで IPアドレス制限をする
西藤です。
静的なコンテンツで構成されるサイトを高い耐久性と高速なコンテンツ配信するためには S3 + CloudFront という構成が使えます。
今回はそこにセキュリティ制限を組み合わせるための方法を記事にしてみます。
想定シナリオ
今回の記事において想定するシナリオは以下のようになります。
- 静的サイトホスティングを S3 + CloudFront にて実現する。
- サイトの訪問者をIPアドレスで制限したい。
というもので、たとえば「会社のオフィスのIPアドレスからのみ見ることができるドキュメントを S3 + CloudFrontで公開したい」というような場面を想定します。
では、以下に書いてきます。
1. S3で静的サイトホスティングの設定
最初に、S3上にコンテンツをおいて静的サイトホスティングを実装します。
S3バケットを作成して、

index.htmlをアップロード。(今回は検証なのでこのindex.htmlのみ)

S3の静的サイトホスティングの設定をします。
※あとでCloudFrontの設定の際に使うので、静的サイトホスティングのエンドポイントを控えておきます。

そして静的サイトホスティングのエンドポイントにアクセスすると無事、サイトが表示されます。
(厳密にはデフォルトのままでは表示されず、アクセス制御関連の設定もしているのですが、今回は割愛致します)

2. CloudFrontの設定
次に、S3 で構成された静的サイトホスティングに対する CloundFrontを設定致します。
Create Distribution でDistribution の作成をします。
作成画面では、Origin Domain Name の欄に先ほどの静的サイトホスティングのエンドポイントを記載します。
※入力欄にカーソルを置くと、AWSアカウント内にあるS3バケットの一覧が表示されますが、それは静的サイトホスティングのエンドポイントではないので、先ほど控えたエンドポイントを直接記載するようにします。

今回は検証なので、あとは他の入力欄はデフォルトの設定で Distribution を作成します。
グローバルに展開されるサービスなので、 Statusが Completedになるまでには時間がかかります。

そして、DistributionのDomain Nameにアクセスして、先ほどの静的サイトホスティングの内容が表示されていれば、 S3 + CloudFront での静的サイトホスティングは実現できています。


上記の要領で静的サイトホスティングを構築し、DistributionのDomain Nameを関係者間で共有すれば、静的サイトホスティングの上でドキュメント共有は実現できます。
しかしながら、そのURLが関係者以外に渡った時には、その第三者によるアクセスを防ぐことができません。
そこで、以下の手順で「指定のIPアドレスからしかアクセスできない」という制限を設定します。
3. AWS WAFの設定
AWS WAF and AWS Shield の管理画面にアクセスします。初期画面は以下の通りになります。
今回は Go to AWS WAF の画面を開きます。

すると、 AWS WAFの画面になりますので、 Configure web ACL をクリックして設定を開始します。

次に、概要説明が出ます。Nextを押して、次の画面に進みます。

Step 1: Name web ACL
ここから設定に入ります。
最初に作成する Web ACLの名前の設定と関連づけるAWSリソースの選択を求められます。
今回は
Web ACL name を s3-cloudfront-test
そして、先ほど設定したCloudFront のDistributionに適用したいので、
Region で Global(CloudFront) を選択し、
AWS resource to associate に該当の CloudFront のDistribution を指定します。
(CloudWatch用の metric name の記入欄もありますが、自動入力に任せます)

Step 2: Create conditions
Web ACL の名前を定義しましたら、次は「どんな条件をかけるか」の設定です。
画面内には Cross-site scripting match conditions Geo match conditions などさまざまな項目が表示されています。
今回は「会社のオフィスのIPアドレスからのみ見ることができるドキュメントを S3 + CloudFrontで公開したい」というシナリオですので、IP match conditions の条件を作成します。

すると IP match condition の作成画面が出ますので、必要事項を入力します。
その中で IPアドレスを指定する欄がありますので、今回は会社のIPアドレスを指定します。
※CIDR表記となりますので。注意が必要です。

設定ができましたら、 IP match condition created successfully と表示されますので、画面下の Nextを押して次に進みます。

Step 3: Create rules
条件を決めたら、その条件を使ってどのように機能するか rule を決めます。Create ruleを押します。
(conditionの次にruleがあって、、、混乱しそうなところですが・・・)

Ruleの名称を定義して、 Add conditions 以下でRuleの内容を定義します。
今回は
「
ip-match-conditionに含まれるIPアドレスからのアクセス(originate from an IP address in)に合致する(does)」
という意味で以下のように定義します。

そして、その設定が終わったら
If a request matches all of the conditions in a rule, take the corresponding actionにて
「ルール内の条件に合致するリクエストに対するアクション」を指定します。(IPアドレスにマッチしたらアクセス許可したいのでAllow)
If a request doesn't match any rules, take the default actionでは
「いずれのルールにも合致しない時の、デフォルトのアクション」を指定します。(指定のないIPからのアクセスはさせたくないので、 Block all requests that don't match any rules)

そうすると、このようになり、「指定のIPアドレスからのリクエストは許可、それ以外ば拒否」という設定ができあがります。
Review and createを押して、内容を確認し、設定を確定しましょう。
CloudFrontの表示確認
以上の設定が完了したら、再度CloudFrontのDomain Nameにアクセスしてみます。
許可のないIPアドレスからは拒否されるはずです。

許可されたIPからのアクセス
問題なく表示されます。

許可されていないIPからのアクセス
リクエストがブロックされたことを示すメッセージが表示されます。

まとめ
以上が、S3 + CloudFront での静的サイトホスティング時にIPアドレス制限をかける方法となります。
S3 + CloudFront はサーバーを構築しなくても、静的なウェブサイトのホスティングができる強力な組み合わせですので、セキュリティ制限も組み合わせたい時に、今回の記事が役に立てば幸いです。
