ipv6対応のCloudFront+S3をCloudFormationで作ってみました。
検証環境の構成イメージは下図のとおり。
[MEMO]
- CloudFrontは、下記の独自ドメインでアクセスできるようにします。
- https://blue21.tk・・・ipv4/ipv6対応
- https://www.blue21.tk・・・ipv4のみ
- CloudFrontは、特定のIPアドレスのみリクエストを許可するようにします。(WAFでアクセス制限)
- S3には、静的コンテンツを格納し、CloudFrontからのリクエストのみ許可します。(OAIでアクセス制限)
- ACMとWAFは、CloudFront用なので us-east-1 に作成します。(AWSの制約)
- ACMで証明書を作成し、Route53でDNS検証します。なお、証明書はCloudFrontに登録します。
- Route53のNameServerをドメイン・プロバイダに登録します。
環境構築
## 作業環境(ローカル環境)
構築作業は、WSL2(ubuntu20.04)で実施します。
なお、AWSのリージョンは us-east-1を使用します。
- Windows10
- WSL2(ubuntu20.04)
- docker 19.03.12
- make 4.2.1
- aws-cli 1.17.14
1. aws-cli の設定
aws-cli実行時はプロファイルを指定します。プロファイルの設定は下記のとおり。
- blue21 という名称でプロファイルを作成
- リージョンは us-east-1 を使用し, Output形式は json
- 管理者権限のアクセスキーを使用
2. ソース一式のdownload
環境構築に必要なCloudFormationテンプレートなどは、Bitbucketに登録しています。
Bitbucketの下記URLからダウンロードできます。
レポジトリの内容は以下のとおり。
. ├── README.md ├── bin │ ├── Makefile │ ├── README.md │ ├── cfn_validate.sh │ └── cfn_wait.sh ├── cfn │ ├── Makefile │ ├── README.md │ ├── cfn_cf.yml │ └── cfn_r53.yml ├── htdocs │ ├── index.html │ └── sorry.html └── img ├── image01.drawio └── image01.png
3.独自ドメインの取得
検証用に無料の独自ドメイン(blue21.tk)を取得して、Route53 にパブリックのホストゾーンを作成しました。(参考にした手順は、下記URLを参照)
Route53のホストゾーンは、aws-cliとCloudFormationで作成しました。
aws-cli コマンドをMakefileに記述しているので、cfnディレクトリで下記コマンドを実行するとCloudFormationのスタックを作成します。
make に指定する変数は以下のとおり
- DOMAIN_NAME・・・独自ドメイン名
$ make cfnr53 DOMAIN_NAME=blue21.tk
コマンドが終了すると、
Route53に下図のようなホストゾーンが作成されます。
Route53に下図のようなホストゾーンが作成されます。
Route53のネームサーバをドメイン・プロバイダに登録後、下記コマンドで変更が反映されたことを確認します。
ネームサーバが表示されたらOKです。
ネームサーバが表示されたらOKです。
$ dig blue21.tk @8.8.8.8 NS ; <<>> DiG 9.16.1-Ubuntu <<>> blue21.tk @8.8.8.8 NS ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2465 ;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;blue21.tk. IN NS ;; ANSWER SECTION: blue21.tk. 21588 IN NS ns-1424.awsdns-50.org. blue21.tk. 21588 IN NS ns-1611.awsdns-09.co.uk. blue21.tk. 21588 IN NS ns-499.awsdns-62.com. blue21.tk. 21588 IN NS ns-751.awsdns-29.net. ;; Query time: 20 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Thu Sep 10 09:58:04 JST 2020 ;; MSG SIZE rcvd: 178
4. IPアドレスの確認
CloudFrontにアクセスするクライアント(私の場合は自宅)のIPアドレスを確認します。
下記URLで、ipv4 と ipv6 のIPアドレスを確認できます。
下図は表示例です。
確認したIPアドレスは、後続の手順で使用します。
4.CloudFront+S3+WAF+ACM構築
構築は、aws-cliとCloudFormationで行います。
aws-cliのコマンドはMakefileに記述しています。
cfnディレクトリで、下記のmakeコマンドを実行すると、CloudFormationのスタックを作成します。
make に指定する変数は以下のとおり
- DOMAIN_NAME・・・独自ドメイン名
- HOSTED_ZONE_ID・・・Route53に作成したホストゾーンのID
- ALLOW_CIDR_V4・・・アクセスを許可するパブリックIPアドレス(ipv4)
- ALLOW_CIDR_V6・・・アクセスを許可するパブリックIPアドレス(ipv6)
$ make cfncf DOMAIN_NAME=blue21.tk HOSTED_ZONE_ID=Zxxx ALLOW_CIDR_V4=1.2.3.4/32 ALLOW_CIDR_V6=2001:xxx/128
上記コマンド終了後、
cfnディレクトリで下記コマンドを実行すると、作成したスタック一覧を参照できます。
このコマンドはスタック名に "Blue21" を含むものをリストします。
$ aws cloudformation describe-stacks \ --profile blue21 \ --query 'Stacks[?contains(StackName,`Blue21`)].{StackName:StackName,StackStatus:StackStatus,Desc:Description}' \ --output table ---------------------------------------------------------- | DescribeStacks | +-----------------+------------------+-------------------+ | Desc | StackName | StackStatus | +-----------------+------------------+-------------------+ | CloudFront & S3| Blue21Cf00PoC | CREATE_COMPLETE | | R53 public zone| Blue21R5300PoC | CREATE_COMPLETE | +-----------------+------------------+-------------------+
動作確認
AWS環境確認
Route53のレコードは下図のとおり。
AレコードとAAAAレコードを作成しています。
WAF(v2)は下図のとおり。
CloudFrontは下図のとおり
- オリジンはS3のみ。
- S3バケットにアクセスログを格納します。
- WAFでブロックした場合、WAFは403を返しますが、CloudFrontで503に変更して、エラーページを返すようにしています。
S3バケットは下図のとおり。
なお、S3バケットには2つのディレクトリが存在します。
- cflogs ・・・ CloudFrontのアクセスログ格納
- htdocs ・・・ 静的なWEBコンテンツ格納
サンプルのWEBコンテンツをデプロイ
動作確認用のサンプルページをS3バケットにアップロードします。
aws-cli コマンドをMakefileに記述しているので、
cfnディレクトリで下記コマンドを実行するとアップロードできます。
$ make s3deploy
下記コマンドで、S3バケットの中身をリストできます。
2つの html ファイルがあればOKです。
$ make s3ls aws s3 ls s3://blue21cf00poc-s3bucket-2nwhp37a58d4/htdocs/ --recursive --profile blue21 2020-09-10 16:20:11 212 htdocs/index.html 2020-09-10 16:20:11 214 htdocs/sorry.html
ipv4 でリクエスト
ipv4のみ対応のネットワーク(WSL2のubuntu)から、curlコマンドでCloudFrontにリクエストします。
$ curl https://blue21.tk
CloudFront(https://blue21.tk)にリクエストすると
下図のように CloudFrontアクセスログには ipv4のIPアドレスが記録されます。
CloudFront(https://www.blue21.tk)にリクエストしても、上記と同じようにipv4のIPアドレスがログに記録されます。
ipv6でリクエスト
CloudFront(https://blue21.tk)にリクエストすると
下図のように CloudFrontアクセスログには ipv6のIPアドレスが記録されます。
CloudFront(https://www.blue21.tk)にリクエストすると、ipv4のIPアドレスがログに記録されます。
CloudFrontは ipv6 有効化していますが、www.blue21.tk は AAAAレコードを登録していないので名前解決できず、ipv4のIPアドレスで通信しています。
環境破棄
AWSコンソールで下記のスタックを上から順番に削除します。
- スタック(Blue21Cf00PoC)を削除する前に、S3バケットを空にしないと失敗します
- スタック(Blue21R5300PoC)を削除する前に、ACM用のCNAMEレコードを削除しないと失敗します。
---------------------------------------------------------- | DescribeStacks | +-----------------+------------------+-------------------+ | Desc | StackName | StackStatus | +-----------------+------------------+-------------------+ | CloudFront & S3| Blue21Cf00PoC | CREATE_COMPLETE | | R53 public zone| Blue21R5300PoC | CREATE_COMPLETE | +-----------------+------------------+-------------------+