はじめに
EC2
の単一構成の場合に、Cloudfront
+WAF
を導入する構成を構築してみる。
今回は、ドメイン管理サービスにRoute53
は使用せずに、Cloudflare
を利用する。
環境
AWS
- EC2
- Cloudfront
- WAF
- ACM
準備
以下の準備が完了していること
- AWSのアカウントが作成されていること
- EC2が構築されていること
EC2インスタンスの構築
今回はテスト用に作成をしておく。
項目 | 設定値 |
---|---|
名前 | server |
OS | AmazonLinux2023 AMI |
アーキテクチャ | 64ビット(Arm) |
インスタンスタイプ | t4g.nano |
キーペア | server(新規で作成) |
セキュリティグループ | ssh,http,https (自分のIPのみ) |
ストレージ | 8GB (gp3) |
上記構成で構築を行う。
構築後、確認用のため以下のアプリケーションをインストールしておく。
dnf install -y httpd php
また、固定のIPをつけておきたいため、Elastic IP
も付与しておく。
固定IP付与後、EC2
のインスタンスにドメインを割り振っておく。
構成図
導入前-構成図
導入前の構成図は以下の通りとなる。
導入後-構成図
導入後の構成図は以下の通りとなる。
※静的コンテンツも動的コンテンツもEC2
のインスタンス内にあるという前提となる。
この構成には、以下改善したほうが良い点があるが、一旦ここでは扱わないことにする。
ALB
を追加して、プライベートサブネット
とNAT GateWay
の構成にしたほうが良い- 静的コンテンツは
S3
などに分離して配置する
作業
まずは、Cloudfront
の設置から行う。Cloudfront
のディストリビューション作成時に、WAF
も同時に作成できるが今回は一つずつ作成して検証をしていく。
Cloudfrontを作成する
1. AWSコンソールより、「Cloudfront
」サービスを選択する

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

3. 設定を変更し、「ディストリビューション」を作成する
設定については以下を変更する。
項目 | 設定値 |
---|---|
Origin domain | ec2-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) |
後は適当にデフォルトの設定を使用することにした。 エッジロケーションとか料金にかかわる部分についてはちゃんと考えておいたほうがよさそう。
※1Origin domain
について、オリジンとするEC2サーバのドメイン名となる。Distribution settings reference
を見ると、EC2
サーバの設定については、パブリック IPv4 DNS
を指定しているようだが、独自のWebサーバ(通常の設定したドメイン名)でもよさそう。
- Distribution settings reference
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesDomainName
※2Cloudfront
-オリジン
間のプロトコルとなる。https
で接続させたい場合は、EC2
内の証明書とCloudfront
で利用する証明書を一致させないといけないので、また別の手順が必要となる。
- CloudFrontのオリジンをEC2にしてHTTPS通信を強制する構成について
https://dev.classmethod.jp/articles/how-to-create-cloudfront-ec2-e2e-https-connection/
※3
ビューワー・・・接続するクライアントのこと。http
and https
とするとどちらでも接続ができるが、https
としたいので、Redirect HTTP to HTTPS
にしておく。HTTPS only
でもよいと思うのだが。
※4GET
,HEAD
以外に、POST
やPUT
なども利用できるようにしないと、オリジンへの接続時にアプリケーションの登録更新で正しく動作しないため。
静的コンテンツの場合は、GET
, HEAD
で事足りるが、今回は分離していない構成ということでこれを選択。

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

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

EC2のセキュリティグループを変更する
Cloudfront
からのEC2
へトラフィックが流れる形となるので、それ以外からのトラフィックについては拒否しておきたい。
そのため、セキュリティグループをCloudfront
のhttp
/https
のみのプロトコルのみ許可するように設定をする。
1. 「EC2」サービスからナビゲーションペインより「セキュリティグループ」を選択し、「セキュリティグループを作成」を選択する

2. セキュリティグループを設定する
今回は、80
のみ許可すれば問題ない。
※オリジン間のプロトコルで、https
も許可している場合は、443
も空けておくこと。
Cloudfront
のリストは、マネージドプレフィックスリストという予め用意されているソースがあるため、これを選択する。
- Amazon CloudFront用のAWS マネージドプレフィックスリストを使用したオリジンへのアクセス制限
https://aws.amazon.com/jp/blogs/news/limit-access-to-your-origins-using-the-aws-managed-prefix-list-for-amazon-cloudfront/

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

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

ACM(AWS Certificate Manager)で証明書をリクエストする
Cloudfront
で代替ドメイン名を設定するために(test.k-bushi.com
でアクセスさせるため)、証明書をリクエストする。
※米国東部 (バージニア北部) リージョン (us-east-1) にある必要があるため注意。
1. 「Certificate Manager」サービスを選択する

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

3. 「証明書をリクエスト」を行う
4. リクエスト完了後、ドメインを設定する
以下のドメインを設定する。

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

Cloudfrontで代替ドメイン名を設定する
1. 「Cloudfront」サービスで「ディストリビューション」を選択し、編集をする
「ディストリビューション」→ 先ほど作成したディストリビューションのID部分を選択 → 「編集」を選択する。

動作確認では、Cloudfront
経由でEC2
インスタンスへのアクセスができているかどうかについてを確認する。
2. Alternative domain name (CNAMEs) - optional`を入力、証明書を選択し、変更を保存する

3. ディストリビューションの画面で設定が確認できればOK
後は「デプロイ」ステータス→「最終変更日時」が表示されれば完了している。

DNSレコードを変更する
test.k-bushi.com
がまだEC2
インスタンスへ向いてしまっているので、Cloudfront
へ向くように変更する。
1. 変更するCNAMEレコードの値を確認する
「Cloudfront」→「ディストリビューション」→作成したディストリビューションを選択→「ディストリビューションドメイン名」を確認する。

2. ドメイン管理サービスでCNAMEレコードを追加する
-test IN A [IPアドレス]
+test IN CNAME [Cloudfrontのディストリビューション名]
※元々あったAレコードは削除しておく。

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

できているのでOK! 次はWAFを設定してみる。
WAFの設定
先ほどは設定をしていなかったWAF
をこのステップで設定する。
1. 「Cloudfront」サービスで「ディストリビューション」を選択し、Editをする
「ディストリビューション」→ 先ほど作成したディストリビューションのID部分を選択 → 「Edit」を選択する。

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

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

参考
Distribution settings reference
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesDomainNameCloudFrontのオリジンをEC2にしてHTTPS通信を強制する構成について
https://dev.classmethod.jp/articles/how-to-create-cloudfront-ec2-e2e-https-connection/Amazon CloudFront用のAWS マネージドプレフィックスリストを使用したオリジンへのアクセス制限
https://aws.amazon.com/jp/blogs/news/limit-access-to-your-origins-using-the-aws-managed-prefix-list-for-amazon-cloudfront/代替ドメイン名 (CNAME) を追加することによって、カスタム URL を使用する
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html独自ドメインでCloudFront にアクセスできるようにする
https://qiita.com/kanadeee/items/752e20af5b071ef0e011
おわりに
EC2
+Cloudfront
+WAF
という構成を構築してみた。EC2
をオリジンにしたことはなかったので、意外と学びがあった。
また、WAF
についてだが、個別のページと作るともっと複雑な手順だった気がするがCloudfront
で設定するWAF
はすごい簡単だった…。WAF
のサービスページだと、ルールの設定とかも細かく決めれたような気がするのだが。