S3 を安全に運用する ― Block Public Access・バケットポリシー・バージョニング・ライフサイクル・レプリケーション
S3 はシンプルですが、設定ミスによる情報漏洩が最も多いサービスでもあります。このハンズオンでは、S3 を安全かつ低コストに運用するための主要機能を実践します。パブリックアクセスのブロック、バケットポリシーによるアクセス制御、バージョニングによる誤削除対策、ライフサイクルによる自動階層化・削除、レプリケーションによる冗長化を体験します。
| 項目 | 内容 |
|---|---|
| 対象サービス | Amazon S3(Bucket Policy / BPA / Versioning / Lifecycle / Replication) |
| 主な学習内容 | 公開ブロック / ポリシー設計 / バージョン管理 / 階層化 / レプリケーション / ログ |
| 所要時間 | 60〜75 分 |
| 難易度 | ★★☆☆☆(初〜中級者向け) |
| 前提知識 | S3 の基本操作・JSON の読み書き |
| 費用目安 | ほぼ 0 USD(少量のオブジェクト + レプリケーションの転送のみ) |
handson-sec-src-xxxxhandson-sec-dst-xxxxap-northeast-1(東京)、レプリカ先は ap-northeast-3(大阪) または us-west-2 を使用aws s3 / s3api が使える環境(CloudShell 推奨)「S3」→「バケットを作成」 をクリックします。
「バケットを作成」をクリックします。
「アクセス許可」タブの 「パブリックアクセスをすべてブロック」 の 4 項目を確認します。これがオンの間は、たとえバケットポリシーで "Principal": "*" を許可しても公開されません(安全弁)。
| 設定 | 効果 |
|---|---|
| 新しい ACL をブロック | 新規の公開 ACL を拒否 |
| 任意の ACL をブロック | 既存の公開 ACL を無視 |
| 新しいバケットポリシーをブロック | 公開ポリシーの追加を拒否 |
| 任意のバケットポリシーをブロック | 公開ポリシー経由のアクセスを無視 |
「アクセス許可」→「バケットポリシー」→「編集」で以下を貼り付けます。HTTP(非暗号化)通信を拒否する典型的なポリシーです。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::handson-sec-src-xxxx",
"arn:aws:s3:::handson-sec-src-xxxx/*"
],
"Condition": {
"Bool": { "aws:SecureTransport": "false" }
}
}
]
}
HTTPS 経由の aws s3 cp は成功し、HTTP を強制した場合は AccessDenied になることを確認します。バケットの公開状態が「オブジェクトは公開されていません」と表示されていれば安全です。
「プロパティ」タブ →「バケットのバージョニング」→「編集」→ 「有効にする」 を選択して保存します。
「オブジェクト」一覧で「バージョンを表示」をオンにすると、v1 と v2 の 2 つのバージョンが見えます。
オブジェクトを削除すると 削除マーカー が付くだけで実体は残ります。削除マーカーを消すと元に戻ります。
# 削除(削除マーカーが付く) aws s3 rm s3://handson-sec-src-xxxx/sample.txt # 削除マーカーを消して復元(VersionId は list-object-versions で確認) aws s3api delete-object --bucket handson-sec-src-xxxx \ --key sample.txt --version-id <DeleteMarkerのVersionId>削除後も古いバージョンが残り、削除マーカーを除去するとオブジェクトが復活することを確認できれば、誤操作・ランサムウェア対策の基礎が身につきます。
アクセス頻度に応じてストレージクラスを自動で移行し、古いバージョンを自動削除します。
「管理」タブ →「ライフサイクルルール」→「ライフサイクルルールを作成」をクリックします。
| アクション | 対象 | 日数 |
|---|---|---|
| Standard-IA に移行 | 現行バージョン | 30 日後 |
| Glacier Instant Retrieval に移行 | 現行バージョン | 90 日後 |
| 以前のバージョンを完全削除 | 非現行バージョン | 30 日後 |
| 不完全なマルチパートアップロードを削除 | ― | 7 日後 |
「ルールを作成」をクリックします。
| クラス | 用途 | 相対コスト |
|---|---|---|
| Standard | 高頻度アクセス | 高 |
| Standard-IA | 低頻度(取り出し料あり) | 中 |
| Glacier Instant | アーカイブ(即時取り出し) | 低 |
| Glacier Deep Archive | 長期保管(数時間で取り出し) | 最安 |
ライフサイクルルール一覧に handson-tiering が「有効」で表示されれば成功です(実際の移行は設定日数の経過後にバックグラウンドで自動実行されます)。
別リージョン(例: 大阪 ap-northeast-3)に handson-sec-dst-xxxx を作成します。バージョニングを有効化しておきます(レプリケーションの必須条件)。
ソースバケット handson-sec-src-xxxx →「管理」→「レプリケーションルール」→「レプリケーションルールを作成」をクリックします。
「保存」をクリックします。「既存オブジェクトのレプリケート」を問われたら、今回は新規オブジェクトのみで OK です。
ソースにアップしたオブジェクトが別リージョンのバケットに自動コピーされ、オブジェクト詳細の「レプリケーションステータス」が COMPLETED になれば成功です。
ログ保存用バケット handson-sec-log-xxxx を作成し、ソースバケットの「プロパティ」→「サーバーアクセスのログ記録」→「編集」で有効化、ログ先に作成したバケットを指定します。
オブジェクトレベルの API(GetObject / PutObject)を確実に記録したい場合は CloudTrail の データイベント を有効にします。「誰が・いつ・どの IP から」アクセスしたかを追跡できます。
ポータルの「S3 + Athena + Firehose」ハンズオンと連携し、アクセスログを Athena でクエリすると、アクセス元 IP やリクエスト数を集計できます。
しばらく操作した後、ログバケットにアクセスログファイルが出力されていれば成功です(出力まで数時間かかる場合があります)。
バージョニング有効バケットは、すべてのバージョンと削除マーカーを消さないと削除できません。下記手順で確実に削除してください。
s3crr_role_... を削除| 習得したスキル | 実践内容 |
|---|---|
| 公開ブロック | Block Public Access の 4 項目と安全弁の理解 |
| バケットポリシー | HTTPS 強制(aws:SecureTransport)など Deny ポリシー |
| バージョニング | 上書き・削除マーカー・誤削除からの復元 |
| ライフサイクル | 階層化(IA / Glacier)・旧バージョンの自動失効 |
| レプリケーション | クロスリージョンの自動コピーで冗長化 |