S3+CloudFront+WAFでIP制限した静的Webサイトを構築してみた

Adways Advent Calendar 2018 9日目の記事です。

http://blog.engineer.adways.net/entry/advent_calendar_2018


 

こんにちは!クラウドCoEの遠藤です。

re:Invent 2018で最もテンションあがった発表はAWS Transit Gatewayです。
多対多のVPC接続は今後クラウド利用が拡大していくにあたり、必要となる場面が出てくると思うので今から妄想が止まりません。
さて今回は残念ながらネットワークとは関係ないのですが、「静的Webサイトを公開したい!」との要望を受けて急遽AWSで環境構築したのでご紹介します。

要件

  • 安くてすぐに公開できる環境ほしい → クラウドやね、S3でいけそう
  • HTTPSアクセス → CloudFront+ACMでいけそう
  • まずはコンテンツの確認等したいでIP制限かけて限定公開 → Bucketポリシー or WAFでいけそう
  • 本番公開時はSNSからのアクセスがスパイクする可能性アリ → CloudFrontでいけそう

S3+CloudFront+WAF(+Route53+ACM) という王道構成に行きつきました。

構成

f:id:AdwaysEngineerBlog:20181212214548p:plain

今回はRoute53とACMの設定についての記載は割愛します。

下記記事でACM発行について非常にわかりやすく説明されています。

http://blog.serverworks.co.jp/tech/2017/12/04/acm-dns/

証明書発行確認のメール不要&更新作業不要は素敵過ぎますね。

構築順序

事前準備(今回割愛部分)

  • ドメイン発行
  • ACMでSSL証明書発行
  • バケットに設置するコンテンツの準備(html等)

今回やること

  1. S3に静的Webサイトを作成する
      a. バケットの作成
      b. バケットポリシーの定義
      c. Static Web Site Hostingを有効にして確認
      d. Static Web Site Hostingを無効

  2. CloudFront Destributionを設定する
      a. 1で作成したバケットをOriginに設定
      b. ACMで作成した証明書を設置

  3. WAFでルールを作成し、CloudFrontに適用
      a. Web ACL作成
      b. condition作成
      c. rule作成

  4. アクセス確認

1.S3に静的Webサイトを作成する

S3バケットの基本的な設定は以下になります

f:id:AdwaysEngineerBlog:20181212214857p:plain

今回はバージョン管理にGitLabを利用する予定なのでバージョニング機能は無効

最終的にCloudFrontから配信するため、S3で必ずしもホスティングする必要はないのですが

アップしたコンテンツの確認をしておきたいので一時的に静的ウェブホスティングを有効化

f:id:AdwaysEngineerBlog:20181212214944p:plain

一時的に特定IPからアクセスできるようにバケットポリシーを手動修正

(後々、CloudFrontからのアクセスのみ受け付けるように設定を変更します)

f:id:AdwaysEngineerBlog:20181212215008p:plain

上記で発行されたエンドポイント(http://xxx.s3-website-xxx.amazonaws.com )にアクセスし、正しくWebページが正しく動作していることを確認しておく

コンテンツの表示確認ができたら、静的ウェブホスティングを無効化


 

2.CloudFront Destributionを設定する

[Create Distribution] でCloudFrontを作成

f:id:AdwaysEngineerBlog:20181212215113p:plain

当然Webで。

f:id:AdwaysEngineerBlog:20181212215143p:plain

Origin Domain Name はサジェストされるので先ほど作成したS3バケットを選択

Origin IDはOrigin Domain Name 入れると自動ではいります

Restrict Bucket Access をYesにして Origin Access identity をCreate a New Identityに変更

Grant Read Permissions on BucketをYesにして、CloudFrontからのアクセスのみ受け付けるS3バケットポリシーに更新(この時既存のバケットポリシーに追加される形になるので不要なポリシーは削除しておく)

f:id:AdwaysEngineerBlog:20181212215250p:plain

今回ACMで発行したSSL証明書を設置するため、Viewer Protocol Policy はRedirect HTTP to HTTPSに変更

全体公開するまではコンテンツ差し替えが発生するので、今回は Object Caching をCustomizeに変更し、全てのTTLを0にすることでキャッシュ無効化(本番公開時は適切な値に変更)

f:id:AdwaysEngineerBlog:20181212215337p:plain

Alternate Domain Names (CNAMEs) にSSLでアクセスするドメイン名を指定する 注:指定しないと「ERR_SSL_VERSION_OR_CIPHER_MISMATCH」と言われ怒られます

SSL Certificate を Custom SSL Certificateに変更し、ACMで作成しておいたSSL証明書を指定

Default Root Object を DocumentRootの適切なファイル(index.html等)にしておく

StatusがDeployedになったらCloudFrontドメインのとSSLURLでアクセス可能なことを確認しておく。


 

3.WAFでルールを作成し、CloudFrontに適用

f:id:AdwaysEngineerBlog:20181212215454p:plain

Web ACL name を設定

AWS resource Associate で先ほど構築したCloudFrontを指定

f:id:AdwaysEngineerBlog:20181212215557p:plain f:id:AdwaysEngineerBlog:20181212215815p:plain

IP match conditions を作成し、許可 or 拒否したい任意のIPアドレスを定義する。

f:id:AdwaysEngineerBlog:20181212215848p:plain

Create rule からルール名を指定し、Add conditions で該当させたい条件を指定

今回は指定したIPアドレスからのアクセスなので originate from an IP address in になる。

f:id:AdwaysEngineerBlog:20181212215937p:plain

ルールに一致した際の振る舞い(Allow)とそれ以外の振る舞い(Block)を指定してWAFの設定完了

ちなみに今回は単純なIPアドレスの制限でしたが、当然ルール次第で様々な保護がかけられます。

最後に、想定した動作をしているかWebサイトにアクセスして確認!

まとめ

今回はAWSにおける静的Webサイトの王道パターンを紹介させていただきました。
実装1時間強。久しぶりにAWSを触ったにもかかわらず、あっという間でした。
CloudFormation等利用すればさらに早く便利になることでしょう。
たったこれだけで可用性の高いWebサイトが建てられて、CDN配信おまけにWAF機能が使えるなんてクラウド様々です。

re:Invent 2018ではLambdaがALBやCustom Rutimeをサポートしたり、Firecrackerが発表されたりとサーバレスがアツいですね。
是非今後も追いかけていきたいと思います。

参考:

AWSにおける静的コンテンツ配信パターンカタログ(アンチパターン含む)
cloudfront-s3-での-ip-アドレスベースのアクセス制限設定をする


 

次は須藤さんの記事です。

http://blog.engineer.adways.net/entry/advent_calendar_2018/10