はじめに
AWS内にデータを保管する際、多くのケースでS3が第一の選択肢となるかと思います。
一方で、データ保管にはセキュリティやバックアップの設定が不可欠であり、適切に設定しないとデータの窃取・消失リスクが増大してしまいます。
本記事では、上記リスクを下げるために役立つS3のセキュリティとバックアップ機能をまとめた上で、公式ベストプラクティスの実践方法を整理しました!
「S3を何となく使っているけど、適切に設定できているか不安」という方に、ぜひご一読頂ければと思います。
概要
本記事は、以下の3節から構成されます
順を追って解説します
S3のセキュリティ機能
S3は大容量データを保管するという性質上、当然機密情報が含まれるケースを想定しなければなりません。
例えば、2021年に巷を騒がせた免許証流出事件も、(S3かは不明ですが)クラウドストレージで保管されていた機密情報への不正アクセスに起因しており、より厳しいセキュリティ対策が必要であることが記事中でも結論づけられています。
このような機密情報を守るためにS3は以下のセキュリティ機能を持ち、適切な活用によりセキュリティ強度を高める事ができます。
名称 | 概要 |
---|---|
ポリシーによるアクセス制御 | バケットにアクセスできるユーザーやアプリケーションを制限する |
ACLによるアクセス制御 | バケットやオブジェクトにアクセスできるAWSアカウントを制限する |
データの暗号化 | バケットに格納されたオブジェクトを暗号化する |
ブロックパブリックアクセス | インターネットからのアクセスを禁止する |
署名付きURL | 時間制限付きで外部にオブジェクトを公開するURLを発行 |
CORS | オリジン以外のドメインからのデータ取得を許可する |
S3のアクセスアナライザー | 外部からのアクセスが可能なセキュリティリスクの高いバケットを検知 |
アクセスログの記録 | アクセスログをS3サーバーログやCloudTrailで記録 |
それぞれ詳細を解説します
ポリシーによるアクセス制御
ポリシー(IAMポリシー)とは、AWS上の各サービスに対するアクセス条件を設定するための仕組みです。
詳細は以下のIAMの記事を参照頂きたいですが、S3で使用されるポリシーは下記3種類に大別されます
名称 | 概要 | S3での主な用途 |
---|---|---|
アイデンティティベースのポリシー | アクセスする側(ユーザー、ロール)にアタッチするポリシー | S3全体に対するアクセス権限を付与したい場合 |
バケットポリシー (リソースベースのポリシー) | アクセスされる側(S3バケット)にアタッチするポリシー(1個のみアタッチ可) | バケットごとに細かくアクセス制御を実施したい場合 |
S3アクセスポイント | アクセスされる側(S3バケット)にアタッチするポリシー(複数アタッチ可) | ユーザーごとに各バケットへのアクセス制御を変える等、バケットポリシーより更に詳細にアクセス制御を実施したい場合 |
なお、公式ドキュメントによるとアイデンティティベースとリソースベース(バケットポリシー, S3アクセスポイント)両方のポリシーが設定された場合、両方のポリシーで許可されている主体のみがアクセスを許可されます。
また、後述のようにバケットポリシー非設定時はバケット所有者のAWSアカウントのみアクセスが許可されるので、バケットへのアクセスには以下のポリシー設定が必要となります
- バケット所有者のAWSアカウントからバケットにアクセスする場合: アイデンティティベースのポリシーの設定が必要
- 上記以外からバケットにアクセスする場合: アイデンティティベースとリソースベース両方のポリシーの設定が必要
それぞれ解説します
・アイデンティティベースのポリシー
アクセスする側(ユーザー、ロール)にアタッチするポリシーであり、一般的にS3全体(全てのバケット)に対するアクセス権限を付与したい場合に使用される事が多いです。
(アクセスできるバケットを制限する事もできますが、管理が大変となるためこの用途ではリソースベースのポリシーを使用した方が無難です)
アイデンティティベースのポリシーは、設定が簡単なAWS管理ポリシー(S3ではAmazonS3FullAccess
(フルアクセス)やAmazonS3ReadOnlyAccess
(読取専用)がよく使用されます)と、自由度の高いカスタマー管理ポリシーに分けられますが、詳細は以下の記事をご参照ください
・バケットポリシー (リソースベースのポリシー)
アクセスされる側(S3バケット)にアタッチするポリシーであり、一般的にバケットごとに細かくアクセス制御を実施したい場合に使用される事が多いです。
例え話とはなりますが、「Windowsのフォルダへのアクセス権を与える際に、フォルダを右クリックしてアクセスできるユーザを指定」や「Linuxでフォルダへのアクセス権限をchmodコマンドで変更」する場合に近いと解釈すれば、イメージしやすいかと思います。
S3バケットにおけるリソースベースのポリシーはバケットポリシーと呼ばれ、以下のようなJSON形式で指定されます
{
"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を指定 (参考)、他AWSアカウントも指定可)
- Effect → アクセス権限の種類 (基本的には"Allow"(許可)か"Deny"(拒否))
- Action → 許可または拒否するアクション (アスタリスク*は以下の全アクションが対象となる (参考))
- Resource → アクションの設定対象 (バケット名や内部のオブジェクト名を指定、ワイルドカードも使用可 (参考))
- Condition → ポリシー適用対象を絞るための追加条件 (参考)
なお、バケットポリシーが設定されていない場合は、バケット所有者のAWSアカウントのみアクセスが許可されている状態となっています。
・S3アクセスポイント
前述したアイデンティティ・リソースベースのポリシーは他のサービスにも存在しますが、S3アクセスポイントはS3独自の機能です。
S3アクセスポイントはバケットポリシーと同じく、アクセスされる側(S3バケット)にアタッチするリソースベースのポリシーですが、バケットポリシーが1バケットに1つしかアタッチできないのに対し、S3アクセスポイントは1バケットに複数アタッチできる事が特徴です。
(他にもVPC内部のみにアクセス元を絞れる等の特徴があります)
これにより、ユーザー毎にアクセス権限を変えたい場合など、バケットポリシーよりも更に詳細なアクセス制御を実施したい場合に便利な機能となります。
アクセスポイントの文法はバケットポリシーと基本的には同様のため、解説は割愛します。
具体的な使用法は以下の記事が分かりやすいです。
※マルチリージョンアクセスポイント
通常のアクセスポイントはバケットごとに作成する必要がありますが、複数のリージョンのバケットを事前に登録し、ユーザに最も近いバケットを自動選択してくれるマルチリージョンアクセスポイントと呼ばれるサービスも存在します。
通常のアクセスポイントはアクセス制御による「認可」を実現しますが、マルチリージョンアクセスポイントは「高速化」や「管理の簡略化」も実現できる便利な機能です。
詳細は以下の記事が参考になります。
なお、公式ドキュメントを見る限り、マルチリージョンアクセスへのアクセス許可はマルチリージョンアクセスポイントポリシー(マルチリージョンアクセスポイント作成後に編集可)と構成するバケットのポリシー(アイデンティティベースポリシー、バケットポリシーまたはアクセスポイント)両方を設定する必要があります。
ACLによるアクセス制御
今まで紹介した3種類のポリシーは、いずれもIAMポリシーの文法に従ってJSONで記述されます。
一方で、ACLは上記ポリシーがS3に実装される以前から存在する、昔ながらのアクセス制御方法です。
ACLはXMLで記述される(ポリシーはJSON)等、ポリシーと多くの点で違いがあります。
ポリシーとACLの違い
ポリシーとACLの違いを、以下の表に簡単にまとめました
名称 | 記述形式 | アクセス先の指定単位 | アクセス元の認可単位 |
---|---|---|---|
ポリシー | JSON | バケット単位 | エンティティ(ユーザー、ロール)単位 |
ACL | XML | オブジェクト単位 (バケット単位も可能) | AWSアカウント単位(正規ユーザーID) |
特筆すべき点として、ポリシーとACLで、アクセス元とアクセス先どちらが細かく権限指定できるかが逆転することが分かります。
- アクセス先はACL (オブジェクト単位)の方がポリシー (バケット単位)より細かく権限指定できる
- アクセス元はポリシー (エンティティ単位)の方がACL (AWSアカウント単位)より細かく権限指定できる
ただし、ポリシーも以下のようにプレフィックス指定によるフォルダごとのアクセス許可を実現でき、実用上は指定単位の粗さで困る事はあまりないでしょう。
ACLでのアクセス制御方法
アクセス元を以下の4種類に分類し、それぞれ「オブジェクトのリスト表示」「オブジェクトの書き込み」「バケットACLの読み取り」「バケットACLの読み取り」の権限を個別に設定します
- バケット所有者のAWSアカウント
- 全員 (AWS外からのアクセス=パブリックアクセス)
- Authenticated Usersグループ (バケット所有者以外のAWSアカウント)
- S3ログ配信グループ (後述のS3サーバーログ配信に使用するアカウント、参考)
上記4種類以外にも、以下の「被付与者の追加」で個別のAWSアカウントの権限を設定する事ができます。
詳細は以下の記事が参考になります
ポリシーとACLどちらを使用するか
2022年現在、ACLの使用は非推奨で、基本的にはポリシーを使用する事が推奨されてされており、以下のようにバケット作成時にデフォルトではACLが無効化されています
ACL無効化の背景については以下の記事が参考になります。
データの暗号化
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)でデータを暗号化します。
デフォルトではこの方法が選択されています。
ユーザ側で鍵の管理等をあまり意識する必要がないので、最も簡単にオブジェクトの暗号化を実現できる方法と言えます
オブジェクトごとに暗号化の有無を指定することも、バケット内を丸ごと暗号化する事もできます。
コンソールから暗号化を指定する方法は以下の記事が参考になります
・SSE-KMS
KMSの鍵を使用し、サーバー側(S3)でデータを暗号化します。
KMSとは、AWSで暗号化鍵を一括管理する仕組みで、使用場所が分散して管理が煩雑になりがちな暗号化鍵を、CloudTrail等と併用してセキュアかつ効率的に管理する事ができます。
暗号化鍵の管理をKMSに一元化したい場合は、この方法を採用すると良いでしょう。
オブジェクトごとに暗号化の有無を指定することも、バケット内を丸ごと暗号化する事もできます。
こちらも以下の記事が参考になります
※AWS管理キー (aws/s3)
SSE-KMSで使用できるキーとして、デフォルトのAWS管理キー (aws/s3)が準備されています。
このAWS管理キーを使用することでKMSキーのポリシー管理が不要となるため、管理の手間を減らす事ができます。
両者の違いはこちらやこちらの公式ドキュメントが参考になりますが、ユースケースをざっくり分類すると以下のようになりそうです。
- 自アカウントのみからバケットにアクセスする場合 → AWS管理キーを使用
- 他アカウントからもバケットにアクセスする場合(クロスアカウント)、または詳細にアクセス制御したい場合 → 新たに鍵を作成 (カスタマーマネージドキー)
※S3バケットキー
SSE-KMSを使用して暗号化を実行する場合、暗号化オブジェクトに対してリクエストが実行される度に、S3からKMSへのリクエストが発生し、Webアプリのような高頻度アクセスが必要な用途ではHTTPリクエストのコストが多く発生してしまいます。
これを防ぐために、S3側にKMSのキーから生成されたS3バケットキーを保持し、KMSへのリクエストコストを削減できる機能が準備されています。
コンソールから操作する場合は、バケット作成時に「バケットキー」を「有効にする」をチェック、またはバケット作成後にバケット設定から有効化すれば、S3バケットキーを有効化する事ができます
・SSE-C
ユーザーが準備した鍵を使用し、サーバー側(S3)でデータを暗号化します。
コンソールからは
セキュリティポリシーや自分で作成した暗号化キーを使用したい場合は、この方法を採用すると良いでしょう。
また復号にもユーザ側の鍵が必要となるため、適切に使用すればセキュリティを強固にできますが、その分ユーザ側で鍵の管理を入念に実施する必要があります。
なお、この方法はコンソールからは実行できず、オブジェクトのアップロードにREST API、CLI、SDKのいずれかを使用する必要があります (以下でCLIでの実行例が紹介されています)
また、SSE-Cではリクエストのヘッダーに鍵情報が埋め込まれるため、リクエスト自体が暗号化されていないと鍵の盗聴等のリスクがあり危険です。そのためSSE-CはHTTPSの使用が必須となっています。
・クライアント側の暗号化
今までの暗号化(サーバーサイド暗号化=SSE)は、S3にデータ(SSE-Cでは鍵も)を渡した後にAWS側で暗号化を実施していました。
一方でクライアント側の暗号化(CSE)では、S3にデータを送信する前にクライアント側でデータを暗号化します。
この方法はコンソール、REST API、CLIからは実行できず、以下の言語のSDKからのみ実行できます
- .NET (C#)
- Go
- Java
- PHP
- Ruby
- C++
詳細は以下の公式ドキュメントを参照ください。
また、上記方法ではS3専用のクライアント側暗号化SDKを使用していますが、S3に限定されない暗号化ライブラリであるAWS Encryption SDKによる暗号化を実施することもできます(PythonやCLI等、通常のクライアント側の暗号化では暗号化できない言語やプラットフォームでも実行できます)
ブロックパブリックアクセス
パブリックアクセスとは、バケット名さえ知っていればインターネットから誰でもバケット内にアクセスできる(読取、書込等)状態を指します。
外部に公開したいデータを格納する場合は便利な機能ですが、一般的には外部にデータを公開することは情報流出等のリスクを招くため、パブリックアクセスはセキュリティ的に危険な状態と言えます。
このパブリックアクセスを強制的に防ぐ機能が、ブロックパブリックアクセスです。
ブロックパブリックアクセスはバケットごと、またはアカウントごと(別記事で紹介)に以下のような項目で設定できますが、この「パブリックアクセスを全てブロック」のチェックを外しただけで、直ちにバケットが公開されるわけではありません。
この状態では以下のように「公開することができる」という含みのある表現がされており、実際には公開状態となっていません。
上記ブロックパブリックアクセスのチェックを外した上で、以下のような外部からのアクセスを許可するバケットポリシー(またはアクセスポイント、ACL)を付与して、初めてパブリックアクセスが可能となります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Principal": "*",
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": "arn:aws:s3:::<バケット名>/*"
}
]
}
上記のバケットポリシーをバケットに付与すると、以下のように正真正銘の公開状態となります
以上のように、パブリックアクセス許可は「ブロックパブリックアクセス」と「ポリシーまたはACLによるアクセス制御」によるダブルチェック体制である事を把握しておけば、設定ミス等を減らせるかと思います。
(アカウント全体でのブロックパブリックアクセスも含めてトリプルチェックともみなせる)
具体的な設定方法は以下の記事が参考になります。
署名付きURL
署名付きURLとは、バケットへのアクセス権限を持たないユーザーに対してオブジェクトへの一時的なアクセスを許可するために発行するURLです。
バケット内のオブジェクトにHTTP/Sでアクセスするためには「オブジェクトURL」(別記事で紹介)を使用しますが、この方法では永続的なアクセス権限を付与(あるいはパブリックアクセスを許可)する必要があり、セキュリティ的にはリスクがあります。
そこで有効期限内のみアクセスを認める署名付きURLを発行する事で、セキュリティリスクを抑えつつ外部にオブジェクトを共有する事ができます。
・署名付きURLとアクセス制御
署名付きURLによるオブジェクトへのアクセスは、ブロックパブリックアクセスが設定されていたり、バケットポリシーでアクセスが明示的に許可されていなくとも可能です。
ですので期限を長く指定しすぎないように注意してください(通常は数分オーダー)
・署名付きURLによるアクセス禁止
以下のようにバケットポリシーで明示的に署名付きURLのアクセスを禁止する事もできます
CORS
CORS (Cross-Origin Resource Sharing)とは、ブラウザがメインでやり取りする (最初のHTMLを取得する)サーバ以外のドメインからデータを取得する事を指します (厳密にはドメインではなく「オリジン」です。こちらの記事が参考になります)
任意のサーバからデータを取得できるとセキュリティ上のリスク(CSRFやXSS)があるため、通常メインのサーバー以外のドメインからのデータ取得はブラウザで禁止されますが、S3のCORSでは特定のドメインに限ってデータ取得を許可する事ができます。
本機能が使われるケースとして一般的なのが、JavaScript内でリクエスト(Ajax)を実行してHTMLやJSON等のリソースを取得する場合で、Fetch APIやXHR等で指定したデータの取得元がメインのサーバーと異なるS3バケットの場合、CORSを指定する事でアクセスを有効化する必要があります。
メインのサーバー、データの取得元共にS3バケットを使用する場合での実装例を、以下でわかりやすく解説されています。
なお、CORS設定が必要となるのは「データ取得元のS3バケット」(メインサーバー側ではない)である事にご注意ください。
S3のアクセスアナライザー
IAMのアクセスアナライザーのS3版で、外部からのアクセスが可能なセキュリティリスクの高いバケットを検知する機能です。
具体的には
- インターネットから自由にアクセスできる(パブリックアクセス)バケット
- 他のAWSアカウントからアクセスできる (クロスアカウントアクセス)バケット
をそれぞれ検知します。
詳細は以下の公式ドキュメントを参照下さい
具体的な使用例として、前述のブロックパブリックアクセスが無効となったバケットの検知を以下の記事で紹介されています
アクセスログの記録
セキュリティインシデントの監視や原因究明のためには、ログにより証拠を残す事が非常に有効です。
S3では、バケットへのアクセスログとして主に以下の2機能が提供されています。
名称 | ログを記録するサービス | ログの保存場所 |
---|---|---|
S3サーバーログ | S3 | S3内のバケット |
CloudTrailによるログ記録 | CloudTrail | S3内のバケット |
両者の差は以下の公式ドキュメントが詳しいですが、それぞれ記録できる情報が異なるため、用途に応じて使い分ける必要があります。
具体的な使い分け方法は、以下の記事が詳しいです。ざっくり言うと以下のように使い分けられそうです
- S3サーバーログ → 情報量は比較的少ないが安価。日常使用ではこちらで十分
- CloudTrailによるログ記録 → 情報量が多いがやや高価。本番環境や監査向け
なお、いずれのログもログの保存先バケットと監視先バケットは分ける必要があります。
同一バケットに保存した場合、ログの保存がトリガーとなってさらにログが作成され、コストが増えたり必要なログが埋もれてしまう恐れがあるからです。
※オブジェクトロック
オブジェクトロックとは、オブジェクトの削除や上書きを一定期間または無制限に禁止する機能です。
削除されては運用上まずいデータ(監査用のログ等)を保存する場合、このオブジェクトロックを指定し、誤削除や不適切な削除を防ぐことが望ましいです。
バックアップとバージョン管理
別記事で紹介したように、S3はマルチAZ構成による冗長化 (1ゾーンIAを除く)が行われており、デフォルトでも高い可用性、データ消失対策を実現できています。
よってS3はデータのバックアップ用途に使用される事が多いですが、以下の機能を活用することで、バックアップとしての利便性向上や保管コストの削減に繋げる事ができます。
名称 | 概要 |
---|---|
クロスリージョンレプリケーション | リージョンを跨ぐバケットのレプリケーションを実施 |
バケットのバージョニング | バケット内のオブジェクトをバージョン管理する |
ライフサイクルルール | 時間経過に応じてオブジェクトクラスやバージョンを自動移行する |
クロスリージョンレプリケーション (CRR)
クロスリージョンレプリケーション(CRR)とは、デフォルトのAZ間での冗長化に加え、リージョンを跨ぐバケットのレプリケーション (自動コピー)を設定することです。
災害等で特定のリージョンのデータが復旧不可能となったとしても、容易に復旧することが可能となります。
複数のAZが同時に使用不可となる事は滅多にありませんが、いざという時のBCP(事業継続計画)におけるデータの消失対策や、大規模障害発生時の可用性向上において有効な手法です。
クロスリージョンレプリケーションは、バケットの設定画面の「レプリケーションルール」から設定可能です。
以下のように設定項目が多いので、それぞれ解説します
- ステータス: ルール作成直後からレプリケーションを有効化するかを選択します (後で有効化・無効化する事ができます)
- 優先順位: 1つのバケットが複数のレプリケーションルールの送信先にされている場合、本ルールの優先順位を指定します (数字が)
- ルールスコープを選択: レプリケーションルールをバケット内全てのオブジェクトに適用するか、フィルタで一部オブジェクトに絞るかを選択します
- プレフィックス: 「ルールスコープを選択」でフィルタリングを選択した場合、プレフィックスで対象フォルダを絞れます
- タグ: 「ルールスコープを選択」でフィルタリングを選択した場合、タグにより対象オブジェクトを絞れます
- 送信先: レプリケーション先のバケットを指定します。ここで他リージョンのバケットを指定した場合、クロスリージョンレプリケーションになります
- IAMロール: レプリケーションに必要なアクセス権限を持つIAMロールを指定します。「新しいロールを作成」を選択すると適したポリシーがアタッチされたロールが自動作成されます
- 暗号化: SSE-KMSで暗号化されたオブジェクトもレプリケーションの対象とするかを選択します(なお、SSE-S3はデフォルトでレプリケーション対象、SSE-Cはレプリケーション対象外です)
- 送信先ストレージクラス: レプリケーションされたオブジェクトが格納されるストレージクラスを選択します (デフォルトではS3 標準)
- 追加のレプリケーションオプション: 上記以外の追加オプションを指定します(参考)。一部オプションは有料なのでご注意ください
なお、「送信先」に同リージョンのバケットを指定した場合、リージョンを跨がないレプリケーション(SRR)となり、BCP対策等の効果がなくなってしまいます。一方でログの集約や複数アカウント間オブジェクト連携が目的であればSRRが適している場合もあるので、以下を参考に用途に応じてリージョンを跨ぐか跨がないかを選択してください
バケットのバージョニング
バージョニングとは、バケット内部にあるオブジェクトが変更された際に、変更前のバージョンのオブジェクトが保持される機能です。
下図のように以前のバージョン (「バージョンID」で管理)を閲覧・復元したり、変更されたオブジェクトを確認したりできるので、データの誤削除対策や変更管理等に有用です。
(Gitの変更管理と似ていますが、Gitは手動でコミットする必要があるのに対して、S3では変更発生時に自動で変更前のバージョンが保持されます)
S3におけるバージョニングはバケット単位で設定されますが、コンソールから確認する際はオブジェクト単位で変更履歴を閲覧する事もできます。
バージョニングの具体的な動作は、後述するライフサイクルルールも含めて以下の記事が参考になります
以前のバージョンの保持にも料金が掛かるので、コストと利便性のバランスを見て、後述のライフサイクルルールを適切に設定すると良いでしょう。
・削除マーカー
オブジェクトが削除された場合は「削除マーカー」が残ります。この削除マーカーは過去のバージョンを参照することで削除されたオブジェクトを復元する事ができます。
一方で参照していた過去のバージョンを削除してしまうと、削除マーカー自身は関連づけられたデータを持たないため、削除マーカーのみでは元のオブジェクトを復元できない事にご注意ください。
・MFA Delete
バージョニングを設定して誤削除対策をしていたとしても、バージョニング設定自体を間違えて変更してしまい、結果誤削除されてしまう事態も起こり得ます。
このような事態を防ぐための「2重のやらかし対策」として、バージョニングの操作時にMFA (多要素認証)を求めるMFA Deleteという機能が準備されています。
具体的には
- バケットのバージョニング状態の変更
- オブジェクトバージョンを完全に削除する (バージョンIDを指定する削除操作)
時にMFAが求められます。
詳細は以下の記事をご参照ください
ライフサイクルルール
ライフサイクルルールとは、時間経過に応じたルールに基づくオブジェクトへの操作が自動で実施される機能です。
「100日後にGlacierに移動し、200日後に現行バージョンが削除される」というようなルールが作れます。
ライフサイクルルールの指定単位は以下となります
- 基本的にはバケット単位で設定するが、プレフィックスを指定して一部のフォルダに適用を絞る事もできる
- 時間経過判定の単位は「日」で、毎日世界標準時0時(日本時間午前9時)に更新される
ライフサイクルルールは以下の用途で使用されます。
- ストレージクラスの自動移行
- 過去のバージョンの削除
- 現在のバージョンの失効
- 削除マーカー・不完全なマルチパートアップロードの削除
それぞれ解説します
1.ストレージクラスの自動移行
Intelligent-Tieringと似ていますが、作成から一定期間経過したオブジェクトのストレージクラスを自動で変更し、ストレージコストを抑える事ができます。
両者の違いは、以下となります
- Intelligent-Tiering:「一定期間アクセスされなかったオブジェクト」のストレージクラスを移行
- ライフサイクルルール:「作成から一定日数が経過したオブジェクト」のストレージクラスを移行
バージョニングに応じてルールを変えることもでき「最新バージョンのストレージクラスの移動」「非現行 (過去)バージョンのストレージクラス」に分けて設定する事ができます (後者の場合「現行でなくなってからの経過日数」に基づき移行されます)
なお、128kB以下のオブジェクトはS3 標準IA、S3 Intelligent-Tiering、S3 Glacier Instant Retrievalへの移行が実行されない事にご注意ください (参考)
2. 過去のバージョンの削除
現行バージョンでなくなってから一定期間経過した過去バージョンのオブジェクトを、自動的に完全に削除します。
前述のように過去のバージョンにもS3のコストが発生するため、この設定で定期的に削除する事で、コストが増大することを防ぐことができます。
ただし、過去のバージョンが全て削除されてしまうと復元が不可能となってしまうため、後述の3と組み合わせる際にはご注意ください。
3. 現在のバージョンの失効
作成から一定期間経過したオブジェクトを、自動的に過去バージョンに移行する事ができます。
移行後は現行のバージョンとして削除マーカーが残されます。
前述の2と組み合わせると一定期間経過後にオブジェクトが復元不可能な状態まで削除されてしまうため、ご注意ください。
4. 削除マーカー・不完全なマルチパートアップロードの削除
こちらも以下の記事が参考になりますが、S3の運用を続けると「削除マーカー」や「不完全なマルチパートアップロード」が大量に残り、コストやレスポンス速度に悪影響を与える事があります。これらを自動削除するのが本機能です。
バケット内のゴミ掃除のような意味合いのある機能です。
ベストプラクティスの実践
AWS公式では、以下のS3のセキュリティベストプラクティスと呼ばれるドキュメントが公開されています。
具体的には、以下の項目に従うようS3の設定を見直す事で、冒頭でも言及したデータの窃取や消失のリスクを最小限に抑える事ができます。
・セキュリティベストプラクティス一覧
ベストプラクティス推奨事項 | 関連機能 |
---|---|
Amazon S3バケットに正しいポリシーが使用され、バケットが公開されていないことを確認する |
ポリシーによるアクセス制御 ACL ブロックパブリックアクセス S3のアクセスアナライザー |
最小特権アクセスの実装 |
ポリシーによるアクセス制御 ACL |
Amazon S3アクセスを必要とするアプリケーションとAWSのサービスにIAMロールを使用する | アイデンティティベースのポリシー |
保管時のデータ暗号化の検討 | データの暗号化 |
送信時のデータの暗号化を強制する | バケットポリシー |
S3オブジェクトロックの検討 | オブジェクトロック |
バージョニングの有効化 |
バケットのバージョニング AWS Config |
Amazon S3クロスリージョンレプリケーションの検討 | クロスリージョンレプリケーション |
Amazon S3アクセス用のVPCエンドポイントの検討 | VPCエンドポイント |
※ 上記以外にも、Amazon S3のモニタリングと監査のベストプラクティスという項目が紹介されていますが、どちらかというと監査向けの高度な内容となるため、本記事では割愛します。商用サービスや大規模組織での運用では、こちらもご参照ください。
各推奨事項を詳細に解説します。
Amazon S3 バケットに正しいポリシーが使用され、バケットが公開されていないことを確認する
以下の機能を活用することで、意図しないバケットの外部への公開を防ぎます。
- S3に関連したポリシーの違いを把握し、設定時はワイルドカード(*)等の広く権限を与える操作の取り扱いに注意する
- ACL設定時は、「バケット所有者」以外への権限付与時は、取り扱いに注意する(できればACL自体を無効化する)
- ブロックパブリックアクセスで、公開不要なバケットが誤って外部に公開される事を防ぐ
- S3のアクセスアナライザーで、外部に公開されたバケットを定期的に確認する
他にもListBuckets APIの活用等が紹介されていますが、上記以外はお金や手間が掛かる操作が多いため割愛します
(気になる方は公式を参照ください)
最小特権アクセスの実装
ポリシーによるアクセス制御、ACL共に、不必要に広い権限は付与せず、最小限の権限付与にとどめる事が推奨されています。
例えばバケットポリシーで外部AWSユーザーにアクセス権限を付与する際、ユーザを指定するPrincipal
フィールドは、ワイルドカード(全てのAWSアカウント)よりも、アクセスが必要なユーザーのARN(特定のユーザーに絞る)を指定する事が推奨されます。
また、前述のようにACLの設定自体が不要なケースも多いため、このような場合はACLを無効化しましょう
Amazon S3アクセスを必要とするアプリケーションとAWSのサービスにIAMロールを使用する
こちらはS3というよりIAMのベストプラクティスに近く、S3以外のサービスでも共通して意識すべき事項です。
S3へのアクセス元がAWSサービス (EC2やLambda等)のとき、アイデンティティベースのポリシーを付与する際には、アクセスキーのような長期認証情報ではなく、IAMロールのような一時的な認証情報を付与することが推奨されています
詳細は以下のIAMの記事を参照ください
保管時のデータ暗号化の検討
前述のデータの暗号化を利用してオブジェクトを暗号化する事で、データを盗み見られるリスクを減らす事ができます。
コンソールからの操作では暗号化による変化をあまり感じませんが、各種APIからの操作では暗号化有効時は鍵情報もリクエストに含める必要が生じるため、鍵情報を持たない攻撃者から盗み見られるリスクが軽減されます。
前述のように暗号化はバケット側とオブジェクト側いずれからも設定する事ができますが、バケット側で設定してデフォルト暗号化を有効化 (アップロードされるファイルが自動で暗号化される)した方が、管理が楽なのでおすすめです。
送信時のデータの暗号化を強制する
ここでいう「暗号化」とは、バケット内の暗号化ではなく送信時にHTTPSによる暗号化通信を強制する事を指します。
以下の記事のように、バケットポリシーの"Condition"フィールド内"Bool"フィールドに"aws:SecureTransport": "false"
を指定したDenyポリシーを作成する事で、HTTPによる非暗号化通信を拒否する事ができます。
HTTPSを強制したい場合は上記のようなバケットポリシーを作成しましょう
(上記の場合、Allowポリシーは"Statement"フィールドのリストに別途追加可能です。リスト指定が複雑になるのを避けるのであれば、S3アクセスポイントを使用しても良いでしょう)
S3オブジェクトロックの検討
削除されては運用上まずいデータ(監査用のログ等)を保存する場合、前述のオブジェクトロックを指定し、誤削除や不適切な削除を防ぐことが望ましいです。
バージョニングの有効化
前述のバケットのバージョニングを使用することで変更発生時に変更前のオブジェクトを保持し、データの意図しない変更やアプリケーション障害からの復旧を容易化する事ができます。
また、AWS Configという自動でAWSの設定を監視できるツールのs3-bucket-versioning-enabled
というルールを利用する事で、バージョニングの有効無効の確認を自動化する事ができるため、こちらの利用を検討する事も推奨されています (ただし有料かつお高めです)
Amazon S3クロスリージョンレプリケーションの検討
前述のクロスリージョンレプリケーション(を使用することでリージョンを跨ぐバケットのレプリケーション (自動コピー)を設定し、災害等によるデータの消失を防ぐ事ができます。
経営においてBCP (事業継続計画)が重視されている現代においては、重要な情報を保管するバケットは基本的にこのクロスリージョンレプリケーションを適用した方が良いでしょう
Amazon S3アクセス用のVPCエンドポイントの検討
こちらはS3というよりVPCの機能となりますが、VPC内のAWSサービス (EC2やFargate等)からS3にアクセスするとき、VPCエンドポイント経由でのアクセスが推奨されています。
これにより、インターネット経由のアクセスを遮断したり、バケットポリシーによりVPC内部にアクセス権限を絞る事で、S3、VPC両者のセキュリティを向上させる事ができます。
セキュリティ上のメリットに加え、インターネットゲートウェイを経由しないためにコストも安くなりますが、2種類あるVPCエンドポイント (インターフェイスエンドポイント、ゲートウェイエンドポイント)のうちゲートウェイエンドポイントはアクセス料金が無料となるのでおすすめです。
VPCエンドポイントの詳細は以下のVPCの記事を参照ください