Amazon S3 セキュリティとバックアップのベストプラクティス

# はじめに
**AWS内にデータを保管**する際、多くのケースで**S3が第一の選択肢**となるかと思います。

一方で、データ保管には**セキュリティやバックアップの設定が不可欠**であり、適切に設定しないと**データの窃取・消失リスクが増大**してしまいます。

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/dc8bab3b-95a6-8333-1dbd-24fee60fb9ad.png">

本記事では、上記リスクを下げるために役立つ**S3のセキュリティとバックアップ機能をまとめ**た上で、[**公式ベストプラクティス**](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/security-best-practices.html)**の実践方法を整理**しました！

「S3を何となく使っているけど、適切に設定できているか不安」という方に、ぜひご一読頂ければと思います。

# 概要
本記事は、以下の3節から構成されます

- [**S3のセキュリティ機能**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#s3のセキュリティ機能)
- [**バックアップとバージョン管理**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#バックアップとバージョン管理)
- [**ベストプラクティスの実践**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ベストプラクティスの実践)

順を追って解説します

# S3のセキュリティ機能
S3は大容量データを保管するという性質上、当然**機密情報が含まれる**ケースを想定しなければなりません。

例えば、[2021年に巷を騒がせた免許証流出事件](https://www.itmedia.co.jp/news/articles/2108/12/news139.html)も、(S3かは不明ですが)クラウドストレージで保管されていた機密情報への不正アクセスに起因しており、より厳しいセキュリティ対策が必要であることが記事中でも結論づけられています。

このような機密情報を守るためにS3は**以下のセキュリティ機能**を持ち、**適切な活用によりセキュリティ強度を高める**事ができます。

|名称|概要|
|---|---|
|[**ポリシーによるアクセス制御**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ポリシーによるアクセス制御)|バケットに**アクセスできるユーザーやアプリケーションを制限**する|
|[**ACLによるアクセス制御**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#aclによるアクセス制御)|バケットやオブジェクトに**アクセスできるAWSアカウントを制限**する|
|[**データの暗号化**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#データの暗号化)|バケットに格納されたオブジェクトを**暗号化**する|
|[**ブロックパブリックアクセス**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ブロックパブリックアクセス)|**インターネットからのアクセス**を禁止する|
|[**署名付きURL**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#署名付きurl)|**時間制限**付きで**外部にオブジェクトを公開するURL**を発行|
|[**CORS**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#cors)|オリジン以外のドメインからのデータ取得を許可する|
|[**S3のアクセスアナライザー**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#s3のアクセスアナライザー)|**外部からのアクセスが可能**なセキュリティリスクの高い**バケットを検知**|
|[**アクセスログの記録**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#アクセスログの記録)|アクセスログを**S3サーバーログ**や**CloudTrail**で記録|

それぞれ詳細を解説します

## ポリシーによるアクセス制御
**ポリシー**(IAMポリシー)とは、**AWS上の各サービスに対するアクセス条件**を設定するための仕組みです。

詳細は以下のIAMの記事を参照頂きたいですが、**S3で使用されるポリシーは下記3種類**に大別されます

https://qiita.com/c60evaporator/items/0121399880625cc1de51

|名称|概要|S3での主な用途|
|---|---|---|
|**アイデンティティベースのポリシー**|**アクセスする側**(ユーザー、ロール)にアタッチするポリシー|S3全体に対するアクセス権限を付与したい場合|
|**バケットポリシー** (リソースベースのポリシー)|**アクセスされる側**(S3バケット)にアタッチするポリシー(**1個**のみアタッチ可)|バケットごとに細かくアクセス制御を実施したい場合|
|**S3アクセスポイント**|**アクセスされる側**(S3バケット)にアタッチするポリシー(**複数**アタッチ可)|ユーザーごとに各バケットへのアクセス制御を変える等、バケットポリシーより更に詳細にアクセス制御を実施したい場合|

なお、[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-basics)によると**アイデンティティベースとリソースベース**(バケットポリシー, S3アクセスポイント)両方のポリシーが設定された場合、**両方のポリシーで許可されている主体のみがアクセスを許可**されます。

また、[後述のように](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#バケットポリシー-リソースベースのポリシー)バケットポリシー非設定時はバケット所有者のAWSアカウントのみアクセスが許可されるので、**バケットへのアクセス**には**以下のポリシー設定**が必要となります

- **バケット所有者のAWSアカウント**からバケットにアクセスする場合: **アイデンティティベース**のポリシーの設定が必要
- **上記以外**からバケットにアクセスする場合: **アイデンティティベースとリソースベース両方**のポリシーの設定が必要

それぞれ解説します

### ・アイデンティティベースのポリシー
アクセスする側(**ユーザー、ロール**)**にアタッチするポリシー**であり、一般的にS3全体(全てのバケット)に対するアクセス権限を付与したい場合に使用される事が多いです。
(アクセスできるバケットを制限する事もできますが、管理が大変となるためこの用途ではリソースベースのポリシーを使用した方が無難です)

アイデンティティベースのポリシーは、設定が簡単な**AWS管理ポリシー**(S3では`AmazonS3FullAccess`(フルアクセス)や`AmazonS3ReadOnlyAccess`(読取専用)がよく使用されます)と、自由度の高い**カスタマー管理ポリシー**に分けられますが、詳細は以下の記事をご参照ください

https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの分類

### ・バケットポリシー (リソースベースのポリシー)
アクセスされる側(**S3バケット**)**にアタッチするポリシー**であり、一般的に**バケットごとに細かくアクセス制御を実施したい場合**に使用される事が多いです。

例え話とはなりますが、「Windowsのフォルダへのアクセス権を与える際に、フォルダを右クリックしてアクセスできるユーザを指定」や「Linuxでフォルダへのアクセス権限をchmodコマンドで変更」する場合に近いと解釈すれば、イメージしやすいかと思います。

S3バケットにおけるリソースベースのポリシーは**バケットポリシー**と呼ばれ、以下のようなJSON形式で指定されます

```json:バケットポリシーの記載例（ユーザ1,2にバケット内全オブジェクトへの読取とリスト表示を許可）
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "SampleStatement",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::<アカウントID>:user/<ユーザ名1>",
          "arn:aws:iam::<アカウントID>:user/<ユーザ名2>"
        ]
      },
      "Action": [
        "s3:Get*",
        "s3:List*"
      ],
      "Resource": [
        "arn:aws:s3:::<バケット名>/*"
      ],
      "Condition": "*"
    }
  ]
}
```

それぞれのフィールドは以下の意味を持ちます

- Version → ポリシーの記述言語のバージョン（基本的には2012/10/17で固定）
- Statement → ポリシーの詳細を記述するフィールド

Statementフィールドは、更に以下の要素に分けられます。

- Sid → 複数Statementが存在する場合の識別子 (任意の名称を指定可能)
- Principal → ポリシーを適用するアクセス元 (ユーザ、ロール等のARNを指定 ([参考](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/s3-bucket-user-policy-specifying-principal-intro.html))、他AWSアカウントも指定可)
- Effect → アクセス権限の種類 (基本的には"Allow"(許可)か"Deny"(拒否)）
- Action → 許可または拒否するアクション (アスタリスク*は以下の全アクションが対象となる ([参考](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/API/API_Operations.html)))
- Resource → アクションの設定対象 (バケット名や内部のオブジェクト名を指定、ワイルドカードも使用可 ([参考](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/s3-arn-format.html)))
- Condition → ポリシー適用対象を絞るための追加条件 ([参考](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/amazon-s3-policy-keys.html))

なお、**バケットポリシーが設定されていない場合**は、**バケット所有者のAWSアカウントのみアクセスが許可**されている状態となっています。

### ・S3アクセスポイント
前述したアイデンティティ・リソースベースのポリシーは他のサービスにも存在しますが、S3アクセスポイントはS3独自の機能です。

S3アクセスポイントはバケットポリシーと同じく、アクセスされる側(**S3バケット**)**にアタッチするリソースベースのポリシー**ですが、バケットポリシーが1バケットに1つしかアタッチできないのに対し、**S3アクセスポイント**は1バケットに**複数アタッチできる**事が特徴です。
(他にもVPC内部のみにアクセス元を絞れる等の特徴があります)

これにより、**ユーザー毎にアクセス権限を変えたい場合**など、**バケットポリシーよりも更に詳細なアクセス制御を実施したい場合**に便利な機能となります。

アクセスポイントの文法は[バケットポリシー](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#バケットポリシー-リソースベースのポリシー)と基本的には同様のため、解説は割愛します。
具体的な使用法は以下の記事が分かりやすいです。

https://techblog.forgevision.com/entry/2019/12/14/222925

#### ※マルチリージョンアクセスポイント
通常のアクセスポイントはバケットごとに作成する必要がありますが、**複数のリージョンのバケット**を事前に登録し、**ユーザに最も近いバケットを自動選択**してくれる**マルチリージョンアクセスポイント**と呼ばれるサービスも存在します。

通常のアクセスポイントはアクセス制御による「**認可**」を実現しますが、マルチリージョンアクセスポイントは「**高速化**」や「**管理の簡略化**」も実現できる便利な機能です。

詳細は以下の記事が参考になります。

https://dev.classmethod.jp/articles/s3-multi-region-access-points/

なお、[公式ドキュメント](https://aws.amazon.com/jp/blogs/news/s3-multi-region-access-points-accelerate-performance-availability/)を見る限り、マルチリージョンアクセスへのアクセス許可は**マルチリージョンアクセスポイントポリシー**(マルチリージョンアクセスポイント作成後に編集可)と**構成するバケットのポリシー**(アイデンティティベースポリシー、バケットポリシーまたはアクセスポイント)**両方を設定する必要**があります。

<br>

## ACLによるアクセス制御
今まで紹介した3種類のポリシーは、いずれもIAMポリシーの文法に従ってJSONで記述されます。

一方で、**ACL**は上記ポリシーがS3に実装される以前から存在する、昔ながらのアクセス制御方法です。
ACLはXMLで記述される(ポリシーはJSON)等、ポリシーと多くの点で違いがあります。

### ポリシーとACLの違い
ポリシーとACLの違いを、以下の表に簡単にまとめました

|名称|記述形式|アクセス先の指定単位|アクセス元の認可単位|
|---|---|---|---|
|ポリシー|JSON|バケット単位|エンティティ(ユーザー、ロール)単位|
|ACL|XML|オブジェクト単位 (バケット単位も可能)|AWSアカウント単位([正規ユーザーID](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/finding-canonical-user-id.html))|

特筆すべき点として、ポリシーとACLで、アクセス元とアクセス先どちらが細かく権限指定できるかが逆転することが分かります。

- アクセス先はACL (オブジェクト単位)の方がポリシー (バケット単位)より細かく権限指定できる
- アクセス元はポリシー (エンティティ単位)の方がACL (AWSアカウント単位)より細かく権限指定できる

ただし、**ポリシーも**以下のようにプレフィックス指定による**フォルダごとのアクセス許可**を実現でき、実用上は指定単位の粗さで困る事はあまりないでしょう。

https://www.jpcyber.com/support/iam-s3-user-specific-folder

### ACLでのアクセス制御方法
アクセス元を以下の4種類に分類し、それぞれ「オブジェクトのリスト表示」「オブジェクトの書き込み」「バケットACLの読み取り」「バケットACLの読み取り」の権限を個別に設定します

- バケット所有者のAWSアカウント
- 全員 (AWS外からのアクセス=パブリックアクセス)
- Authenticated Usersグループ (バケット所有者以外のAWSアカウント)
- S3ログ配信グループ (後述の[S3サーバーログ](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#アクセスログの記録)配信に使用するアカウント、[参考](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/ServerLogs.html))

上記4種類以外にも、以下の「被付与者の追加」で個別のAWSアカウントの権限を設定する事ができます。

<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/1d6e430e-60c9-0b4c-e5a8-06b248f217a0.png">

詳細は以下の記事が参考になります

https://dev.classmethod.jp/articles/amazon-s3-acl-basics/

### ポリシーとACLどちらを使用するか
2022年現在、**ACLの使用は非推奨**で、基本的には**ポリシーを使用する事が推奨**されてされており、以下のようにバケット作成時に**デフォルトではACLが無効化**されています

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/ed572264-1684-9548-735a-29571a7fde97.png">

ACL無効化の背景については以下の記事が参考になります。

https://dev.classmethod.jp/articles/s3-bucket-owner-enforced/

<br>

## データの暗号化
S3バケット内に格納されたデータ(オブジェクト)を暗号化すると、更にセキュリティを高める事ができます。

**暗号化には以下の4種類の方法**があります
(どの方法も内部的にはHTTP/Sリクエストに暗号化用のヘッダーが付与されています)

|名称|暗号化を実施する場所|鍵の種類|アルゴリズム|概要|
|---|---|---|---|---|
|SSE-S3|サーバー側(AWS S3)|S3独自の鍵|AES-256|S3が管理する鍵によるS3側での暗号化|
|SSE-KMS|サーバー側(AWS S3)|KMS|AES-256|KMSで管理する鍵によるS3側での暗号化|
|SSE-C|サーバー側(AWS S3)|ユーザー独自の鍵|AES-256|ユーザー側が準備した鍵によるS3側での暗号化|
|クライアント側の暗号化|クライアント|ユーザー独自の鍵|AES, RSA等|S3にデータを送信する前にクライアント側でデータを暗号化|

それぞれ解説します。

### ・SSE-S3
**S3が管理する鍵**を使用し、サーバー側(S3)でデータを暗号化します。
デフォルトではこの方法が選択されています。

ユーザ側で鍵の管理等をあまり意識する必要がないので、**最も簡単にオブジェクトの暗号化を実現できる方法**と言えます

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingServerSideEncryption.html

オブジェクトごとに暗号化の有無を指定することも、バケット内を丸ごと暗号化する事もできます。
コンソールから暗号化を指定する方法は以下の記事が参考になります

https://dev.classmethod.jp/articles/lim-s3-sse-2021/

### ・SSE-KMS
**KMSの鍵**を使用し、サーバー側(S3)でデータを暗号化します。
[KMS](https://aws.amazon.com/jp/kms/)とは、AWSで暗号化鍵を一括管理する仕組みで、使用場所が分散して管理が煩雑になりがちな暗号化鍵を、CloudTrail等と併用してセキュアかつ効率的に管理する事ができます。

**暗号化鍵の管理をKMSに一元化したい場合**は、この方法を採用すると良いでしょう。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingKMSEncryption.html

オブジェクトごとに暗号化の有無を指定することも、バケット内を丸ごと暗号化する事もできます。
こちらも以下の記事が参考になります

https://dev.classmethod.jp/articles/lim-s3-sse-2021/

#### ※AWS管理キー (aws/s3)
SSE-KMSで使用できるキーとして、デフォルトのAWS管理キー (aws/s3)が準備されています。
このAWS管理キーを使用することでKMSキーのポリシー管理が不要となるため、**管理の手間を減らす**事ができます。

両者の違いは[こちら](https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-object-encryption-keys/)や[こちらの公式ドキュメント](https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/concepts.html#key-mgmt)が参考になりますが、**ユースケース**をざっくり分類すると以下のようになりそうです。

- 自アカウントのみからバケットにアクセスする場合 → AWS管理キーを使用
- 他アカウントからもバケットにアクセスする場合(クロスアカウント)、または詳細にアクセス制御したい場合 → 新たに鍵を作成 (カスタマーマネージドキー)

#### ※S3バケットキー
SSE-KMSを使用して暗号化を実行する場合、暗号化オブジェクトに対してリクエストが実行される度に、S3からKMSへのリクエストが発生し、Webアプリのような高頻度アクセスが必要な用途では[HTTPリクエストのコスト]()が多く発生してしまいます。

これを防ぐために、S3側にKMSのキーから生成された**S3バケットキー**を保持し、**KMSへのリクエストコストを削減**できる機能が準備されています。

コンソールから操作する場合は、[バケット作成時に「バケットキー」を「有効にする」をチェック](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/configuring-bucket-key.html)、または[バケット作成後にバケット設定から有効化](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/configuring-bucket-key.html)すれば、S3バケットキーを有効化する事ができます

### ・SSE-C
**ユーザーが準備した鍵**を使用し、サーバー側(S3)でデータを暗号化します。
コンソールからは

セキュリティポリシーや**自分で作成した暗号化キーを使用したい場合**は、この方法を採用すると良いでしょう。
また復号にもユーザ側の鍵が必要となるため、適切に使用すればセキュリティを強固にできますが、その分ユーザ側で鍵の管理を入念に実施する必要があります。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html

なお、この方法は**コンソールからは実行できず**、オブジェクトのアップロードにREST API、CLI、SDKのいずれかを使用する必要があります (以下でCLIでの実行例が紹介されています)

https://siguniang.wordpress.com/2014/06/14/s3-encryption-with-aws-cli/

また、SSE-Cではリクエストのヘッダーに鍵情報が埋め込まれるため、リクエスト自体が暗号化されていないと鍵の盗聴等のリスクがあり危険です。そのため**SSE-CはHTTPSの使用が必須**となっています。

### ・クライアント側の暗号化
今までの暗号化(サーバーサイド暗号化=SSE)は、S3にデータ(SSE-Cでは鍵も)を渡した後に**AWS側で暗号化を実施**していました。

一方で**クライアント側の暗号化**(CSE)では、**S3にデータを送信する前にクライアント側でデータを暗号化**します。

この方法はコンソール、REST API、CLIからは実行できず、**以下の言語のSDKからのみ実行できます**

- .NET (C#)
- Go
- Java
- PHP
- Ruby
- C++

詳細は以下の公式ドキュメントを参照ください。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingClientSideEncryption.html

また、上記方法ではS3専用のクライアント側暗号化SDKを使用していますが、**S3に限定されない暗号化ライブラリ**である**AWS Encryption SDK**による暗号化を実施することもできます(PythonやCLI等、**通常のクライアント側の暗号化では暗号化できない言語やプラットフォーム**でも実行できます)

https://docs.aws.amazon.com/ja_jp/encryption-sdk/latest/developer-guide/introduction.html

<br>

## ブロックパブリックアクセス
**パブリックアクセス**とは、**バケット名さえ知っていればインターネットから誰でもバケット内にアクセスできる**(読取、書込等)状態を指します。

外部に公開したいデータを格納する場合は便利な機能ですが、一般的には外部にデータを公開することは情報流出等のリスクを招くため、**パブリックアクセスはセキュリティ的に危険**な状態と言えます。

この**パブリックアクセスを強制的に防ぐ**機能が、**ブロックパブリックアクセス**です。

ブロックパブリックアクセスはバケットごと、またはアカウントごと([別記事で紹介]())に以下のような項目で設定できますが、この「パブリックアクセスを全てブロック」の**チェックを外した**だけで、**直ちにバケットが公開されるわけではありません**。

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/06428a62-4caa-e627-4e6a-1ee8f9533a1a.png">

この状態では以下のように「公開することができる」という含みのある表現がされており、実際には公開状態となっていません。

<img width=360 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/8d1a59f4-7159-5492-c58d-7aa3952320ce.png">

上記ブロックパブリックアクセスのチェックを外した上で、以下のような**外部からのアクセスを許可するバケットポリシー**(またはアクセスポイント、ACL)を付与して、初めてパブリックアクセスが可能となります。

```json:パブリックに読取可能となるバケットポリシーの例
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Statement1",
			"Principal": "*",
			"Effect": "Allow",
			"Action": [
                "s3:Get*",
                "s3:List*"
            ],
			"Resource": "arn:aws:s3:::<バケット名>/*"
		}
	]
}
```

上記のバケットポリシーをバケットに付与すると、以下のように正真正銘の公開状態となります

<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/2e80effc-923c-f360-1b20-e8f082cefdd0.png">

以上のように、パブリックアクセス許可は「**ブロックパブリックアクセス**」と「**ポリシーまたはACLによるアクセス制御**」による**ダブルチェック体制**である事を把握しておけば、設定ミス等を減らせるかと思います。
([アカウント全体でのブロックパブリックアクセス]()も含めてトリプルチェックともみなせる)

具体的な設定方法は以下の記事が参考になります。

https://zenn.dev/ymasutani/articles/019959e7c990b1

<br>

## 署名付きURL
**署名付きURL**とは、バケットへのアクセス権限を持たないユーザーに対して**オブジェクトへの一時的なアクセスを許可**するために発行するURLです。

バケット内のオブジェクトにHTTP/Sでアクセスするためには[「オブジェクトURL」(別記事で紹介)]()を使用しますが、この方法では永続的なアクセス権限を付与(あるいはパブリックアクセスを許可)する必要があり、セキュリティ的にはリスクがあります。

そこで**有効期限内のみアクセスを認める署名付きURL**を発行する事で、**セキュリティリスクを抑えつつ外部にオブジェクトを共有**する事ができます。

### ・署名付きURLとアクセス制御

**署名付きURL**によるオブジェクトへのアクセスは、**ブロックパブリックアクセス**が設定されていたり、**バケットポリシーでアクセスが明示的に許可されていなく**とも可能です。
ですので**期限を長く指定しすぎないように注意**してください(通常は数分オーダー)

### ・署名付きURLによるアクセス禁止
以下のようにバケットポリシーで明示的に署名付きURLのアクセスを禁止する事もできます

https://www.jpcyber.com/support/restrict-access-to-presigned-url

<br>

## CORS
CORS (Cross-Origin Resource Sharing)とは、ブラウザが**メインでやり取りする** (最初のHTMLを取得する)**サーバ以外のドメインからデータを取得**する事を指します (厳密にはドメインではなく「オリジン」です。[こちらの記事](https://qiita.com/att55/items/2154a8aad8bf1409db2b)が参考になります)

任意のサーバからデータを取得できるとセキュリティ上のリスク([CSRF](https://qiita.com/okamoai/items/044c03680766f0609d41)や[XSS](https://qiita.com/att55/items/2154a8aad8bf1409db2b#cors-%E3%81%AE%E5%BF%85%E8%A6%81%E6%80%A7))があるため、通常メインのサーバー以外のドメインからのデータ取得はブラウザで禁止されますが、S3のCORSでは**特定のドメインに限ってデータ取得を許可**する事ができます。

本機能が使われるケースとして一般的なのが、**JavaScript内でリクエスト(Ajax)を実行してHTMLやJSON等のリソースを取得**する場合で、Fetch APIやXHR等で指定したデータの取得元がメインのサーバーと異なるS3バケットの場合、CORSを指定する事でアクセスを有効化する必要があります。

メインのサーバー、データの取得元共にS3バケットを使用する場合での実装例を、以下でわかりやすく解説されています。

https://dev.classmethod.jp/articles/lim-s3-cors-2021/

なお、**CORS設定が必要**となるのは「**データ取得元のS3バケット**」(メインサーバー側ではない)である事にご注意ください。

<br>

## S3のアクセスアナライザー
[IAMのアクセスアナライザー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#access-analyzer)のS3版で、**外部からのアクセスが可能なセキュリティリスクの高いバケットを検知**する機能です。

具体的には

- インターネットから自由にアクセスできる(**パブリックアクセス**)バケット
- 他のAWSアカウントからアクセスできる (**クロスアカウントアクセス**)バケット

をそれぞれ検知します。
詳細は以下の公式ドキュメントを参照下さい

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/access-analyzer.html

具体的な使用例として、前述の[ブロックパブリックアクセス](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ブロックパブリックアクセス)が無効となったバケットの検知を以下の記事で紹介されています

https://dev.classmethod.jp/articles/stop-publishing-with-access-analyzer-for-s3/

<br>

## アクセスログの記録
セキュリティインシデントの監視や原因究明のためには、**ログにより証拠を残す**事が非常に有効です。
S3では、バケットへのアクセスログとして主に以下の2機能が提供されています。

|名称|ログを記録するサービス|ログの保存場所|
|---|---|---|
|S3サーバーログ|S3|S3内のバケット|
|CloudTrailによるログ記録|CloudTrail|S3内のバケット|

両者の差は以下の公式ドキュメントが詳しいですが、それぞれ記録できる情報が異なるため、用途に応じて使い分ける必要があります。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/monitoring-overview.html

具体的な使い分け方法は、以下の記事が詳しいです。ざっくり言うと以下のように使い分けられそうです

- S3サーバーログ → 情報量は比較的少ないが安価。日常使用ではこちらで十分
- CloudTrailによるログ記録 → 情報量が多いがやや高価。本番環境や監査向け

https://dev.classmethod.jp/articles/cloudtrail-s3-logs-vs-s3-server-access-logs/

なお、いずれのログも**ログの保存先バケットと監視先バケットは分ける必要**があります。
同一バケットに保存した場合、ログの保存がトリガーとなってさらにログが作成され、[コストが増えたり必要なログが埋もれてしまう](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/ServerLogs.html)恐れがあるからです。

### ※オブジェクトロック
**オブジェクトロック**とは、オブジェクトの**削除や上書きを一定期間または無制限に禁止**する機能です。

削除されては運用上まずいデータ(監査用のログ等)を保存する場合、このオブジェクトロックを指定し、**誤削除や不適切な削除を防ぐ**ことが望ましいです。

<br>
<br>

# バックアップとバージョン管理
[別記事で紹介したように]()、S3はマルチAZ構成による冗長化 (1ゾーンIAを除く)が行われており、デフォルトでも高い可用性、データ消失対策を実現できています。

よってS3はデータの**バックアップ用途**に使用される事が多いですが、**以下の機能を活用**することで、**バックアップとしての利便性向上**や**保管コストの削減**に繋げる事ができます。

|名称|概要|
|---|---|
|[**クロスリージョンレプリケーション**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#クロスリージョンレプリケーション-crr)|リージョンを跨ぐバケットのレプリケーションを実施|
|[**バケットのバージョニング**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#バケットのバージョニング)|バケット内のオブジェクトをバージョン管理する|
|[**ライフサイクルルール**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ライフサイクルルール)|時間経過に応じてオブジェクトクラスやバージョンを自動移行する|

## クロスリージョンレプリケーション (CRR)
**クロスリージョンレプリケーション**(CRR)とは、デフォルトのAZ間での冗長化に加え、**リージョンを跨ぐバケットのレプリケーション** (自動コピー)を設定することです。
災害等で特定のリージョンのデータが復旧不可能となったとしても、容易に復旧することが可能となります。

複数のAZが同時に使用不可となる事は滅多にありませんが、いざという時の**BCP**（事業継続計画）におけるデータの消失対策や、大規模障害発生時の可用性向上において有効な手法です。

クロスリージョンレプリケーションは、[バケットの設定画面]()の「レプリケーションルール」から設定可能です。
以下のように設定項目が多いので、それぞれ解説します

<img width=360 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/cef3e8f8-c05a-66bd-f93f-f006533a6831.png">

- **ステータス:** ルール作成直後からレプリケーションを有効化するかを選択します (後で有効化・無効化する事ができます)
- **優先順位:** 1つのバケットが複数のレプリケーションルールの送信先にされている場合、本ルールの優先順位を指定します (数字が)
- **ルールスコープを選択:** レプリケーションルールをバケット内全てのオブジェクトに適用するか、フィルタで一部オブジェクトに絞るかを選択します
- **プレフィックス:** 「ルールスコープを選択」でフィルタリングを選択した場合、プレフィックスで対象フォルダを絞れます
- **タグ:** 「ルールスコープを選択」でフィルタリングを選択した場合、タグにより対象オブジェクトを絞れます
- **送信先:** レプリケーション先のバケットを指定します。**ここで他リージョンのバケットを指定した場合、クロスリージョンレプリケーション**になります
- **IAMロール:** レプリケーションに必要なアクセス権限を持つIAMロールを指定します。「新しいロールを作成」を選択すると適したポリシーがアタッチされたロールが自動作成されます
- **暗号化:** [SSE-KMS](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#sse-kms)で暗号化されたオブジェクトもレプリケーションの対象とするかを選択します(なお、[SSE-S3](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#sse-s3)はデフォルトでレプリケーション対象、[SSE-C](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#sse-c)はレプリケーション対象外です)
- **送信先ストレージクラス:** レプリケーションされたオブジェクトが格納されるストレージクラスを選択します (デフォルトでは[S3 標準]())
- **追加のレプリケーションオプション:** 上記以外の追加オプションを指定します([参考](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/replication-additional-configs.html))。一部オプションは有料なのでご注意ください

なお、「送信先」に同リージョンのバケットを指定した場合、リージョンを跨がないレプリケーション(SRR)となり、BCP対策等の効果がなくなってしまいます。一方でログの集約や複数アカウント間オブジェクト連携が目的であればSRRが適している場合もあるので、以下を参考に用途に応じてリージョンを跨ぐか跨がないかを選択してください

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/replication.html

https://dev.classmethod.jp/articles/s3-same-region-replication/

## バケットのバージョニング
**バージョニング**とは、バケット内部にあるオブジェクトが変更された際に、**変更前のバージョンのオブジェクトが保持**される機能です。

下図のように以前のバージョン (「バージョンID」で管理)を閲覧・復元したり、変更されたオブジェクトを確認したりできるので、**データの誤削除対策や変更管理**等に有用です。
(Gitの変更管理と似ていますが、Gitは手動でコミットする必要があるのに対して、S3では**変更発生時に自動で変更前のバージョンが保持**されます)

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/a41d058d-61e6-baa8-60d1-79525001c8cf.png">

S3におけるバージョニングは**バケット単位**で設定されますが、コンソールから確認する際はオブジェクト単位で変更履歴を閲覧する事もできます。

バージョニングの具体的な動作は、後述する[ライフサイクルルール](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ライフサイクルルール)も含めて以下の記事が参考になります

https://dev.classmethod.jp/articles/3minutes-s3-versioning-lifecycle/

以前のバージョンの保持にも[料金]()が掛かるので、コストと利便性のバランスを見て、後述のライフサイクルルールを適切に設定すると良いでしょう。

### ・削除マーカー
オブジェクトが削除された場合は「削除マーカー」が残ります。この削除マーカーは**過去のバージョンを参照**することで**削除されたオブジェクトを復元**する事ができます。
一方で参照していた過去のバージョンを削除してしまうと、削除マーカー自身は[関連づけられたデータを持たない](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/DeleteMarker.html)ため、削除マーカーのみでは元のオブジェクトを復元できない事にご注意ください。

### ・MFA Delete
バージョニングを設定して**誤削除対策**をしていたとしても、バージョニング設定自体を間違えて変更してしまい、結果誤削除されてしまう事態も起こり得ます。

このような事態を防ぐための「2重のやらかし対策」として、**バージョニングの操作時**に**MFA** (多要素認証)を求める**MFA Delete**という機能が準備されています。

具体的には

- バケットのバージョニング状態の変更
- オブジェクトバージョンを完全に削除する (バージョンIDを指定する削除操作)

時にMFAが求められます。
詳細は以下の記事をご参照ください

https://dev.classmethod.jp/articles/s3-mfa-delete/

## ライフサイクルルール
**ライフサイクルルール**とは、**時間経過に応じたルールに基づくオブジェクトへの操作**が自動で実施される機能です。
「100日後にGlacierに移動し、200日後に現行バージョンが削除される」というようなルールが作れます。

ライフサイクルルールの指定単位は以下となります

- 基本的には**バケット単位**で設定するが、**プレフィックスを指定して一部のフォルダに適用を絞る**事もできる
- 時間経過判定の単位は「日」で、毎日世界標準時0時(日本時間午前9時)に更新される

ライフサイクルルールは**以下の用途**で使用されます。

1. ストレージクラスの自動移行
2. 過去のバージョンの削除
3. 現在のバージョンの失効
4. 削除マーカー・不完全なマルチパートアップロードの削除

それぞれ解説します

### 1.ストレージクラスの自動移行
[Intelligent-Tiering]()と似ていますが、**作成から一定期間経過したオブジェクトのストレージクラス**を**自動で変更**し、**ストレージコストを抑える**事ができます。

両者の違いは、以下となります

- **Intelligent-Tiering**：「**一定期間アクセスされなかった**オブジェクト」のストレージクラスを移行
- **ライフサイクルルール**：「**作成から一定日数が経過した**オブジェクト」のストレージクラスを移行

バージョニングに応じてルールを変えることもでき「最新バージョンのストレージクラスの移動」「非現行 (過去)バージョンのストレージクラス」に分けて設定する事ができます (後者の場合「現行でなくなってからの経過日数」に基づき移行されます)

なお、128kB以下のオブジェクトはS3 標準IA、S3 Intelligent-Tiering、S3 Glacier Instant Retrievalへの移行が実行されない事にご注意ください ([参考](https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-transition-general-considerations.html#lifecycle-general-considerations-transition-sc))

### 2. 過去のバージョンの削除
**現行バージョンでなくなってから一定期間経過した過去バージョンのオブジェクト**を、**自動的に完全に削除**します。

前述のように過去のバージョンにも[S3のコスト]()が発生するため、この設定で**定期的に削除**する事で、**コストが増大することを防ぐ**ことができます。
ただし、過去のバージョンが全て削除されてしまうと復元が不可能となってしまうため、[後述の3](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#3-現在のバージョンの失効)と組み合わせる際にはご注意ください。

### 3. 現在のバージョンの失効
**作成から一定期間経過したオブジェクト**を、**自動的に過去バージョンに移行**する事ができます。

移行後は現行のバージョンとして削除マーカーが残されます。
[前述の2](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#2-過去のバージョンの削除)と組み合わせると一定期間経過後にオブジェクトが復元不可能な状態まで削除されてしまうため、ご注意ください。

### 4. 削除マーカー・不完全なマルチパートアップロードの削除
こちらも以下の記事が参考になりますが、S3の運用を続けると「削除マーカー」や「[不完全なマルチパートアップロード](https://dev.classmethod.jp/articles/sugano-045-s3-lifecycle-policy/)」が大量に残り、コストやレスポンス速度に悪影響を与える事があります。これらを自動削除するのが本機能です。

https://dev.classmethod.jp/articles/3minutes-s3-versioning-lifecycle/

バケット内のゴミ掃除のような意味合いのある機能です。

# ベストプラクティスの実践
AWS公式では、以下の**S3のセキュリティベストプラクティス**と呼ばれるドキュメントが公開されています。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/security-best-practices.html

具体的には、**以下の項目に従うようS3の設定を見直す**事で、冒頭でも言及した**データの窃取や消失のリスクを最小限に抑える**事ができます。

**・セキュリティベストプラクティス一覧**

|ベストプラクティス推奨事項|関連機能|
|---|---|
|Amazon S3バケットに正しいポリシーが使用され、バケットが公開されていないことを確認する|[ポリシーによるアクセス制御](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ポリシーによるアクセス制御)<br>[ACL](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#aclによるアクセス制御)<br>[ブロックパブリックアクセス](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ブロックパブリックアクセス)<br>[S3のアクセスアナライザー](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#s3のアクセスアナライザー)|
|最小特権アクセスの実装|[ポリシーによるアクセス制御](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ポリシーによるアクセス制御)<br>[ACL](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#aclによるアクセス制御)|
|Amazon S3アクセスを必要とするアプリケーションとAWSのサービスにIAMロールを使用する|[アイデンティティベースのポリシー](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#アイデンティティベースのポリシー)|
|保管時のデータ暗号化の検討|[データの暗号化](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#データの暗号化)|
|送信時のデータの暗号化を強制する|[バケットポリシー](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#バケットポリシー-リソースベースのポリシー)|
|S3オブジェクトロックの検討|[オブジェクトロック](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#オブジェクトロック)|
|バージョニングの有効化|[バケットのバージョニング](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#バケットのバージョニング)<br>[AWS Config](https://aws.amazon.com/jp/config/)|
|Amazon S3クロスリージョンレプリケーションの検討|[クロスリージョンレプリケーション](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#クロスリージョンレプリケーション-crr)|
|Amazon S3アクセス用のVPCエンドポイントの検討|[VPCエンドポイント](https://qiita.com/c60evaporator/items/2f24d4796202e8b06a77#エンドポイント-vpcエンドポイント)|

※ 上記以外にも、[Amazon S3のモニタリングと監査のベストプラクティス](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/security-best-practices.html#security-best-practices-detect)という項目が紹介されていますが、どちらかというと監査向けの高度な内容となるため、本記事では割愛します。商用サービスや大規模組織での運用では、こちらもご参照ください。


各推奨事項を詳細に解説します。

## Amazon S3 バケットに正しいポリシーが使用され、バケットが公開されていないことを確認する
以下の機能を活用することで、意図しないバケットの外部への公開を防ぎます。

- [**S3に関連したポリシー**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ポリシーによるアクセス制御)の違いを把握し、設定時はワイルドカード(*)等の**広く権限を与える操作の取り扱いに注意**する
- [**ACL**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#aclによるアクセス制御)設定時は、**「バケット所有者」以外への権限付与時**は、取り扱いに**注意**する(できればACL自体を無効化する)
- [**ブロックパブリックアクセス**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ブロックパブリックアクセス)で、公開不要なバケットが誤って外部に公開される事を防ぐ
- [**S3のアクセスアナライザー**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#s3のアクセスアナライザー)で、外部に公開されたバケットを**定期的に確認**する

他にもListBuckets APIの活用等が紹介されていますが、上記以外はお金や手間が掛かる操作が多いため割愛します
(気になる方は[公式](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/security-best-practices.html)を参照ください)

## 最小特権アクセスの実装
[ポリシーによるアクセス制御](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ポリシーによるアクセス制御)、[ACL](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#aclによるアクセス制御)共に、**不必要に広い権限は付与せず、最小限の権限付与にとどめる**事が推奨されています。

例えば[バケットポリシー](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#バケットポリシー-リソースベースのポリシー)で外部AWSユーザーにアクセス権限を付与する際、ユーザを指定する`Principal`フィールドは、ワイルドカード(全てのAWSアカウント)よりも、アクセスが必要なユーザーのARN(特定のユーザーに絞る)を指定する事が推奨されます。

また、[前述のように](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#ポリシーとaclどちらを使用するか)ACLの設定自体が不要なケースも多いため、このような場合は**ACLを無効化**しましょう

## Amazon S3アクセスを必要とするアプリケーションとAWSのサービスにIAMロールを使用する
こちらはS3というよりIAMのベストプラクティスに近く、S3以外のサービスでも共通して意識すべき事項です。

**S3へのアクセス元がAWSサービス** (EC2やLambda等)のとき、[アイデンティティベースのポリシー](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#アイデンティティベースのポリシー)を付与する際には、[**アクセスキー**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アクセスキーによる認証)のような**長期認証情報ではなく**、[**IAMロール**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロール)のような**一時的な認証情報を付与することが推奨**されています

詳細は以下のIAMの記事を参照ください

https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロールを使用してアクセス許可を委任する

## 保管時のデータ暗号化の検討
前述の[**データの暗号化**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#データの暗号化)を利用してオブジェクトを暗号化する事で、データを盗み見られるリスクを減らす事ができます。

コンソールからの操作では暗号化による変化をあまり感じませんが、各種APIからの操作では暗号化有効時は鍵情報もリクエストに含める必要が生じるため、鍵情報を持たない攻撃者から盗み見られるリスクが軽減されます。

[前述のように](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#データの暗号化)暗号化はバケット側とオブジェクト側いずれからも設定する事ができますが、バケット側で設定してデフォルト暗号化を有効化 (アップロードされるファイルが自動で暗号化される)した方が、管理が楽なのでおすすめです。

## 送信時のデータの暗号化を強制する
ここでいう「暗号化」とは、バケット内の暗号化ではなく**送信時にHTTPSによる暗号化通信を強制する**事を指します。

以下の記事のように、バケットポリシーの"Condition"フィールド内"Bool"フィールドに`"aws:SecureTransport": "false"`を指定したDenyポリシーを作成する事で、**HTTPによる非暗号化通信を拒否**する事ができます。

https://dev.classmethod.jp/articles/s3-request-https-only/

HTTPSを強制したい場合は上記のようなバケットポリシーを作成しましょう
(上記の場合、Allowポリシーは"Statement"フィールドのリストに別途追加可能です。リスト指定が複雑になるのを避けるのであれば、[S3アクセスポイント](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#s3アクセスポイント)を使用しても良いでしょう)

## S3オブジェクトロックの検討
**削除されては運用上まずいデータ**(監査用のログ等)を保存する場合、前述の[**オブジェクトロック**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#オブジェクトロック)を指定し、**誤削除や不適切な削除を防ぐ**ことが望ましいです。

## バージョニングの有効化
前述の[**バケットのバージョニング**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#バケットのバージョニング)を使用することで変更発生時に変更前のオブジェクトを保持し、**データの意図しない変更やアプリケーション障害からの復旧を容易化**する事ができます。

また、[AWS Config](https://www.yume-tec.co.jp/column/series/aws%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%82%92%E6%8E%A1%E7%94%A8%E3%81%97%E3%81%9F%E3%81%84%E4%BA%BA%E4%BA%8B%E6%8B%85%E5%BD%93%E5%90%91%E3%81%91%E3%81%AEaws%E5%85%A5%E9%96%80/4621)という自動でAWSの設定を監視できるツールの[`s3-bucket-versioning-enabled`](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/s3-bucket-versioning-enabled.html)というルールを利用する事で、バージョニングの有効無効の確認を自動化する事ができるため、こちらの利用を検討する事も推奨されています (ただし有料かつお高めです)

## Amazon S3クロスリージョンレプリケーションの検討
前述の[**クロスリージョンレプリケーション(**](https://qiita.com/c60evaporator/items/ee7def3632eaf493409f#クロスリージョンレプリケーション-crr)を使用することでリージョンを跨ぐバケットのレプリケーション (自動コピー)を設定し、**災害等によるデータの消失を防ぐ**事ができます。

経営において**BCP** (事業継続計画)が重視されている現代においては、重要な情報を保管するバケットは基本的にこのクロスリージョンレプリケーションを適用した方が良いでしょう

## Amazon S3アクセス用のVPCエンドポイントの検討
こちらはS3というよりVPCの機能となりますが、**VPC内のAWSサービス** (EC2やFargate等)**からS3にアクセス**するとき、[**VPCエンドポイント**](https://qiita.com/c60evaporator/items/2f24d4796202e8b06a77#エンドポイント-vpcエンドポイント)経由でのアクセスが推奨されています。

これにより、インターネット経由のアクセスを遮断したり、バケットポリシーによりVPC内部にアクセス権限を絞る事で、**S3、VPC両者のセキュリティを向上**させる事ができます。

セキュリティ上のメリットに加え、[インターネットゲートウェイ](https://qiita.com/c60evaporator/items/2f24d4796202e8b06a77#インターネットゲートウェイとnatゲートウェイ)を経由しないためにコストも安くなりますが、2種類あるVPCエンドポイント (インターフェイスエンドポイント、ゲートウェイエンドポイント)のうち**ゲートウェイエンドポイント**は**アクセス料金が無料となるのでおすすめ**です。

VPCエンドポイントの**詳細は以下のVPCの記事を参照ください**

https://qiita.com/c60evaporator/items/2f24d4796202e8b06a77#エンドポイント-vpcエンドポイント