AWS CLIで Web サイトを構築、管理、運用する(11日目)

11日目です！
セキュリティ系をまたやります。

今回は地理的制限！
指定した国や地域のみ
AWS WAF でルールを組んだり CloudFront で設定できたりします。

今回は CloudFront で日本からのアクセスのみ認めるような設定を入れてみます！

# 11日目の要約
日本からのアクセスだけできるようにするよ！

# AWS CLI の準備
このあたりをみて、好きなバージョンとお使いのOSにあった環境設定をしてくださいね。
なんなら、 AWS CloudShell で実行するのも楽でよいと思います。
この記事シリーズは、AWS CloudShell で実行し、実行例を載せています。

バージョン１
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv1.html

バージョン２
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2.html

# 概要
CloudFront の地理的制限機能で日本からのアクセスだけをできるようにするよ！

# さあ、やってみよう！
## CloudFormation ディストリビューション設定を取得する
ここ最近6日目の記事を参照！とばっかりやっていたので、改めて取得から編集、設定の流れをなぞっていきます。

現在の設定情報をもとに、変更を加えるので、 cloudfront get-distribution-config コマンドを実行します。

```sh
aws cloudfront get-distribution-config --id <CloudFront の Distribution ID> > distribution_geo_tmp.json
```

ファイルに書き込みが行えたら、次に、必要な部分だけ抽出して更新用の元ファイルにします。jq コマンドを使うので、必要に応じてインストールしてください。AWS CloudShell であれば標準でインストール済みです。

```sh
cat distributionconfig_geo.json | jq .DistributionConfig > distribution_geo.json
```

また、get-distribution-config の出力内容のうち、 Etag の値が必要なので確認しておきます。

```sh
cat distribution_geo_tmp.json | grep ETag
```

以下のように出力されます。

```json
    "ETag": "**************",
```

distribution_geo.json　を編集し、GeoRestriction の更新をします。
未設定の場合は、以下のようになっています。

```json
      "GeoRestriction": {
         "RestrictionType": "none",
         "Quantity": 0
      }
```

以下のように設定します。

```json
      "GeoRestriction": {
         "RestrictionType": "whitelist",
         "Quantity": 1,
         "Items": [
            "JP"
         ]
      }
```

設定内容を簡単に説明します。

* RestrictionType
 * whitelist : Items で指定した国や地域かのアクセスのみ許可する
 * blacklist : Items で指定した国や地域からのアクセスを拒否する
* Quantity : Items で定義している個数
* Items : 国や地域のコード(?)日本ならJP。南極大陸ならAO、米国ならUSといった具合。

さらに、本ファイルに対して、以下のように頭と末尾に情報を入力します。

```json:distribution_geo.json_頭
{
"DistributionConfig": {
  "CallerReference": 

（省略）
```
1行目に波括弧({)があるので、その2行目に対して、 “DistributionConfig”: { を追加します。
次に末尾です。

```json:distribution_geo.json_末尾
(省略)
  "WebACLId": "arn:aws:wafv2:us-east-1:************:global/webacl/waf/********-****-****-****-************",
  "HttpVersion": "http2",
  "IsIPV6Enabled": true
 }
}
```

末尾に閉じ波括弧(}）を追加します。

## CloudFront の設定を変更する
準備ができたら、 cloudfront update-distribution コマンドを実行して、設定変更を行います。

```sh
aws cloudfront update-distribution --id <CloudFront Distribution ID> --cli-input-json file://distribution_geo.json --if-match 確認したETag の値
```

コマンド実行に成功すると、Distribution の内容が記された json が返されます。

# 動作確認
※10日目で設定したAWS WAF のルールの内、Anonymous IP list が有効だと　CloudShell からのアクセスが HTTP 403 で防がれてしまうので、解除しています。

## 日本からのアクセス
東京リージョン(ap-northeast-1)の CloudShell からいつものように curl を実行します。

```sh
curl https://<ドメイン名>
```

日本からのアクセスなので問題なくコンテンツが取得、出力されます。

```HTML
<!DOCTYPE html>
<html lang="ja">
<head>
  <title>Advent calendar 2021</title>
</head>
<body>
  <h1>Hello world!!</h1>
  <h2>Advent calendar 2021 DAY 3</h2>
</body>
</html>
```

...いまだに DAY 3 なのでいい加減直さないと・・・

## 米国からのアクセス(日本以外からのアクセス)
北部バージニアリージョン(us-east-1)の CloudShell から同じように curl を実行します。

```sh
curl https://<ドメイン名>
```

日本以外からのアクセスなので期待通り、HTTP 403 が返りアクセスが拒否されます。

```HTML
<html lang="ja">
<meta charset="UTF-8">
<head>
  <title>えらーです m9('ω')</title>
</head>
<body>
  <h1>残念〜！</h1>
  <h2>アクセスできませーん！</h2>
</body>
</html>
```

# まとめ
思いのほか簡単に地理的制限をかけられることにびっくりしました！
明日は AWS WAF のルールでも試してみようかと思います。
※その際は、CloudFront側を止めて動作検証してみます。

* 今回使ったコマンド
 * cloudfront get-distribution-config
 * cloudfront update-distribution