CloudFront の OAC 機能

# 概要

S3 で公開しているコンテンツを、CloudFront からのアクセスのみに制限するには **[OAI](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html)** という機能で実現していました。

ざっくり言うと、セキュリティ面が強化され、以下の点が強化されたようです。

- AWS Signature Version 4（SigV4） 
- SSE-KMS

https://aws.amazon.com/jp/blogs/news/amazon-cloudfront-introduces-origin-access-control-oac/


# SigV4

1. クライアントが CloudFront に HTTP または HTTPS のリクエストを送信する。
2. CloudFront のエッジロケーションはリクエストを受信する。
   リクエストされたオブジェクトがまだキャッシュされていない場合、CloudFront は OAC 署名プロトコル（SigV4）を使用してリクエストに署名する。
OAC を設定する際、
「リクエストに署名しない」
「リクエストに署名する」
「リクエストに署名する（リクエストに署名するが認証ヘッダーを上書きしない）」
という 3 つの署名動作を選択することができる。

## リクエストに署名しない

- オリジンアクセス制御を使用しないことと同じことになる。

## 署名リクエスト(推奨)

- 受信したリクエストがすでにクライアントアプリケーションによって署名された認証ヘッダーを持っている場合でも、CloudFront は常にクライアントから受信したリクエストに署名する。
- CloudFront はクライアントの認証ヘッダーを削除し、CloudFront のクレデンシャルでリクエストに再署名し、新しい認証ヘッダーを生成してS3オリジンに送信する。
- CloudFront がリクエストに署名することで、クライアントと CloudFront 間のデータ転送が少なくなり、アプリケーションのパフォーマンスが向上する。

### 認証ヘッダーを上書きしない

- 受信リクエストに認証ヘッダーがある場合は上書きしない。
# OAC を設定する（新規）

CloudFront ディストリビューションの、S3 バケットアクセスで、**Origin access contorol settings** があります。
![スクリーンショット 2022-09-03 17.32.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/ea54c974-43d0-bf89-aa08-a3c9a006a8fe.png)

「コントロール設定を作成」を開くと、以下の通り、署名動作を選択できます。
![スクリーンショット 2022-09-03 17.36.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/f46fbabf-2a37-dd8c-b499-54853d676b91.png)

ディストリビューションが作成されたら、「ポリシーをコピー」からコピーし、S3バケットポリシーを更新してあげます。

![スクリーンショット 2022-09-03 18.07.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/03a46c54-60ee-a660-7bdd-83df60275959.png)

```json
{
        "Version": "2008-10-17",
        "Id": "Policy",
        "Statement": [
            {
                "Sid": "AllowCloudFront",
                "Effect": "Allow",
                "Principal": {
                    "Service": "cloudfront.amazonaws.com"
                },
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::XXX/*",
                "Condition": {
                    "StringEquals": {
                      "AWS:SourceArn": "arn:aws:cloudfront::XXX:distribution/XXX"
                    }
                }
            }
        ]
      }
```


# SSE-KMS

- SSE-KMS 暗号化を使用して S3 バケットに保存されたコンテンツを暗号化することを要求する場合、SSE-KMS で暗号化された S3 オブジェクトにアクセスするために OAC を使用することができる。
- CloudFront の IAM サービスプリンシパルが KMS キーにアクセスできるように、KMS ポリシーを設定する必要がある。

## 設定

1.KMS からカスタマーキーを作成する。

https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/create-keys.html

2.S3 で、1.で作成した　SSE-KMS を指定する。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/specifying-kms-encryption.html

3.CloudFront にアクセスできるように、KMSキーポリシーを更新（既存のものに追加）する。

https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/key-policy-overview.html

```json
        {
            "Sid": "AllowCloudFrontServicePrincipalSSE-KMS",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com",
                "AWS": "arn:aws:iam::XXX:root"
            },
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:GenerateDataKey*"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::XXX:distribution/XXX"
                }
            }
        }
```