EC2+Cloudfront+WAFの構成を構築する

はじめに

EC2の単一構成の場合に、Cloudfront+WAFを導入する構成を構築してみる。
今回は、ドメイン管理サービスにRoute53は使用せずに、Cloudflareを利用する。

環境

AWS
  - EC2
  - Cloudfront
  - WAF
  - ACM

準備

以下の準備が完了していること

  • AWSのアカウントが作成されていること
  • EC2が構築されていること

EC2インスタンスの構築

今回はテスト用に作成をしておく。

項目設定値
名前server
OSAmazonLinux2023 AMI
アーキテクチャ64ビット(Arm)
インスタンスタイプt4g.nano
キーペアserver(新規で作成)
セキュリティグループssh,http,https (自分のIPのみ)
ストレージ8GB (gp3)

上記構成で構築を行う。

構築後、確認用のため以下のアプリケーションをインストールしておく。

dnf install -y httpd php

また、固定のIPをつけておきたいため、Elastic IPも付与しておく。 固定IP付与後、EC2のインスタンスにドメインを割り振っておく。

構成図

導入前-構成図

導入前の構成図は以下の通りとなる。
architecture-before.svg

導入後-構成図

導入後の構成図は以下の通りとなる。
architecture-after.svg

※静的コンテンツも動的コンテンツもEC2のインスタンス内にあるという前提となる。

この構成には、以下改善したほうが良い点があるが、一旦ここでは扱わないことにする。

  • ALBを追加して、プライベートサブネットNAT GateWayの構成にしたほうが良い
  • 静的コンテンツはS3などに分離して配置する

作業

まずは、Cloudfrontの設置から行う。
Cloudfrontのディストリビューション作成時に、WAFも同時に作成できるが今回は一つずつ作成して検証をしていく。

Cloudfrontを作成する

1. AWSコンソールより、「Cloudfront」サービスを選択する

create-cloudfront-01

2. ナビゲーションペインの「ディストリビューション」を選択し、「ディストリビューションを作成」を選択する

create-cloudfront-02

3. 設定を変更し、「ディストリビューション」を作成する

設定については以下を変更する。

項目設定値
Origin domainec2-54-178-217-170.ap-northeast-1.compute.amazonaws.com (※1)
プロトコルHTTPのみ (※2)
名前ec2-54-178-217-170.ap-northeast-1.compute.amazonaws.com
Enable Origin Shieldいいえ
オブジェクトを自動的に圧縮Yes
ビューワープロトコルポリシーRedirect HTTP to HTTPS (※3)
許可された HTTP メソッドGET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE (※4)
ビューワーのアクセスを制限するNo
キャッシュキーとオリジンリクエストCache policy and origin request policy (recommended)

後は適当にデフォルトの設定を使用することにした。 エッジロケーションとか料金にかかわる部分についてはちゃんと考えておいたほうがよさそう。

※1
Origin domainについて、オリジンとするEC2サーバのドメイン名となる。
Distribution settings referenceを見ると、EC2サーバの設定については、パブリック IPv4 DNS を指定しているようだが、独自のWebサーバ(通常の設定したドメイン名)でもよさそう。

※2
Cloudfront-オリジン間のプロトコルとなる。httpsで接続させたい場合は、EC2内の証明書とCloudfrontで利用する証明書を一致させないといけないので、また別の手順が必要となる。

※3
ビューワー・・・接続するクライアントのこと。
http and httpsとするとどちらでも接続ができるが、httpsとしたいので、Redirect HTTP to HTTPSにしておく。
HTTPS only でもよいと思うのだが。

※4
GET,HEAD以外に、POSTPUTなども利用できるようにしないと、オリジンへの接続時にアプリケーションの登録更新で正しく動作しないため。
静的コンテンツの場合は、GET, HEADで事足りるが、今回は分離していない構成ということでこれを選択。

create-cloudfront-03

4. ディストリビューションが作成された

create-cloudfront-04

5. ステータスが「有効」になっていればOK

create-cloudfront-05

EC2のセキュリティグループを変更する

CloudfrontからのEC2へトラフィックが流れる形となるので、それ以外からのトラフィックについては拒否しておきたい。
そのため、セキュリティグループをCloudfronthttp/httpsのみのプロトコルのみ許可するように設定をする。

1. 「EC2」サービスからナビゲーションペインより「セキュリティグループ」を選択し、「セキュリティグループを作成」を選択する

create-sg-01

2. セキュリティグループを設定する

今回は、80のみ許可すれば問題ない。
※オリジン間のプロトコルで、httpsも許可している場合は、443も空けておくこと。

Cloudfrontのリストは、マネージドプレフィックスリストという予め用意されているソースがあるため、これを選択する。

create-sg-02

3. 「EC2」サービスから「インスタンス」を選択し、セキュリティグループを変更する

対象のインスタンスを選択し、「アクション」→「セキュリティ」→「セキュリティグループを変更する」を選択する。

create-sg-03

4. 作成したセキュリティグループをアタッチし、「保存」を選択する

create-sg-04

ACM(AWS Certificate Manager)で証明書をリクエストする

Cloudfrontで代替ドメイン名を設定するために(test.k-bushi.comでアクセスさせるため)、証明書をリクエストする。

※米国東部 (バージニア北部) リージョン (us-east-1) にある必要があるため注意。

1. 「Certificate Manager」サービスを選択する

request-certificate-01

2. 「証明書をリクエスト」を選択する

request-certificate-02

3. 「証明書をリクエスト」を行う

  1. 「パブリック証明書をリクエスト」を選択し、「次へ」 request-certificate-03

  2. 「完全修飾ドメイン名」に「test.k-bushi.com」を入力し、他はデフォルトのまま「リクエスト」を選択する
    request-certificate-04

4. リクエスト完了後、ドメインを設定する

以下のドメインを設定する。

request-certificate-05

5. 発行済みとなれば完了

request-certificate-06

Cloudfrontで代替ドメイン名を設定する

1. 「Cloudfront」サービスで「ディストリビューション」を選択し、編集をする

「ディストリビューション」→ 先ほど作成したディストリビューションのID部分を選択 → 「編集」を選択する。

setting-alternative-domain-name-01

動作確認では、Cloudfront経由でEC2インスタンスへのアクセスができているかどうかについてを確認する。

2. Alternative domain name (CNAMEs) - optional`を入力、証明書を選択し、変更を保存する

setting-alternative-domain-name-02

3. ディストリビューションの画面で設定が確認できればOK

後は「デプロイ」ステータス→「最終変更日時」が表示されれば完了している。

setting-alternative-domain-name-03

DNSレコードを変更する

test.k-bushi.comがまだEC2インスタンスへ向いてしまっているので、Cloudfrontへ向くように変更する。

1. 変更するCNAMEレコードの値を確認する

「Cloudfront」→「ディストリビューション」→作成したディストリビューションを選択→「ディストリビューションドメイン名」を確認する。

change-cname-record-01

2. ドメイン管理サービスでCNAMEレコードを追加する

-test IN A [IPアドレス]
+test IN CNAME [Cloudfrontのディストリビューション名]

※元々あったAレコードは削除しておく。

change-cname-record-02

EC2+Cloudfront構成の疎通確認

これでようやく確認できるようになったので、test.k-bushi.comにアクセスをしてみる。

ec2-cloudfront-01

できているのでOK! 次はWAFを設定してみる。

WAFの設定

先ほどは設定をしていなかったWAFをこのステップで設定する。

1. 「Cloudfront」サービスで「ディストリビューション」を選択し、Editをする

「ディストリビューション」→ 先ほど作成したディストリビューションのID部分を選択 → 「Edit」を選択する。

setting-waf-01

2. 「セキュリティ保護を有効にする」とし、設定を変更し「Save Changes」を選択する

「セキュリティ保護を有効にする」を押すと、オプションが選べるようになる。
今回は下記の設定とした。

setting-waf-02

3. 設定が反映されていれば完了

setting-waf-03

参考

おわりに

EC2+Cloudfront+WAFという構成を構築してみた。
EC2をオリジンにしたことはなかったので、意外と学びがあった。
また、WAFについてだが、個別のページと作るともっと複雑な手順だった気がするがCloudfrontで設定するWAFはすごい簡単だった…。
WAFのサービスページだと、ルールの設定とかも細かく決めれたような気がするのだが。

Hugo で構築されています。
テーマ StackJimmy によって設計されています。