S3 セキュリティ・ライフサイクル ハンズオン

S3 を安全に運用する ― Block Public Access・バケットポリシー・バージョニング・ライフサイクル・レプリケーション

Amazon S3 Bucket Policy Block Public Access Versioning Lifecycle Replication マネコン操作 所要時間 60〜75 分 v1.0

📋 概要

S3 はシンプルですが、設定ミスによる情報漏洩が最も多いサービスでもあります。このハンズオンでは、S3 を安全かつ低コストに運用するための主要機能を実践します。パブリックアクセスのブロック、バケットポリシーによるアクセス制御、バージョニングによる誤削除対策、ライフサイクルによる自動階層化・削除、レプリケーションによる冗長化を体験します。

項目内容
対象サービスAmazon S3(Bucket Policy / BPA / Versioning / Lifecycle / Replication)
主な学習内容公開ブロック / ポリシー設計 / バージョン管理 / 階層化 / レプリケーション / ログ
所要時間60〜75 分
難易度★★☆☆☆(初〜中級者向け)
前提知識S3 の基本操作・JSON の読み書き
費用目安ほぼ 0 USD(少量のオブジェクト + レプリケーションの転送のみ)
ℹ️ S3 の防御は多層
  • Block Public Access:アカウント / バケット単位の安全弁(最優先で評価)
  • バケットポリシー:リソースベースのアクセス制御
  • IAM ポリシー:ユーザー / ロール側の制御
  • 暗号化:保存データ(SSE)と通信(HTTPS)の保護

🏗️ 全体像

🪣 ソースバケット handson-sec-src-xxxx
BPA 有効 / ポリシーで HTTPS 強制 / バージョニング ON
↓ ライフサイクル(自動階層化・失効)
🧊 Standard → Standard-IA → Glacier → 削除
アクセス頻度に応じてコスト最適化
↓ レプリケーション(CRR)
🪣 レプリカバケット handson-sec-dst-xxxx
別リージョンへ自動コピー(DR / 冗長化)
↓ アクセスログ
📋 ログバケット → Athena で分析
誰がいつ何にアクセスしたか

✅ 前提条件

🛡️ ステップ 1 ― Block Public Access とバケットポリシー

1-1. バケットを作成

「S3」→「バケットを作成」 をクリックします。

バケット名handson-sec-src-xxxx
リージョンap-northeast-1(東京)
パブリックアクセスをすべてブロックオン(デフォルト維持)
デフォルト暗号化SSE-S3(有効)

「バケットを作成」をクリックします。

1-2. Block Public Access の意味を理解する

「アクセス許可」タブの 「パブリックアクセスをすべてブロック」 の 4 項目を確認します。これがオンの間は、たとえバケットポリシーで "Principal": "*" を許可しても公開されません(安全弁)。

設定効果
新しい ACL をブロック新規の公開 ACL を拒否
任意の ACL をブロック既存の公開 ACL を無視
新しいバケットポリシーをブロック公開ポリシーの追加を拒否
任意のバケットポリシーをブロック公開ポリシー経由のアクセスを無視
1-3. HTTPS を強制するバケットポリシー

「アクセス許可」→「バケットポリシー」→「編集」で以下を貼り付けます。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" }
      }
    }
  ]
}
1-4. テストファイルをアップロード
echo "secret data v1" > sample.txt aws s3 cp sample.txt s3://handson-sec-src-xxxx/sample.txt
✅ 確認ポイント

HTTPS 経由の aws s3 cp は成功し、HTTP を強制した場合は AccessDenied になることを確認します。バケットの公開状態が「オブジェクトは公開されていません」と表示されていれば安全です。

🔁 ステップ 2 ― バージョニングで誤削除に備える

2-1. バージョニングを有効化

「プロパティ」タブ →「バケットのバージョニング」→「編集」→ 「有効にする」 を選択して保存します。

2-2. 上書きと削除を検証
# 同じキーに上書き(v2 になる) echo "secret data v2" > sample.txt aws s3 cp sample.txt s3://handson-sec-src-xxxx/sample.txt # バージョン一覧を確認 aws s3api list-object-versions --bucket handson-sec-src-xxxx --prefix sample.txt

「オブジェクト」一覧で「バージョンを表示」をオンにすると、v1 と v2 の 2 つのバージョンが見えます。

2-3. 誤削除からの復元

オブジェクトを削除すると 削除マーカー が付くだけで実体は残ります。削除マーカーを消すと元に戻ります。

# 削除(削除マーカーが付く) 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>
✅ 確認ポイント

削除後も古いバージョンが残り、削除マーカーを除去するとオブジェクトが復活することを確認できれば、誤操作・ランサムウェア対策の基礎が身につきます。

🧊 ステップ 3 ― ライフサイクルでコスト最適化

アクセス頻度に応じてストレージクラスを自動で移行し、古いバージョンを自動削除します。

3-1. ライフサイクルルールを作成

「管理」タブ →「ライフサイクルルール」→「ライフサイクルルールを作成」をクリックします。

ルール名handson-tiering
適用範囲バケット内のすべてのオブジェクト
3-2. 移行・失効ルールを設定
アクション対象日数
Standard-IA に移行現行バージョン30 日後
Glacier Instant Retrieval に移行現行バージョン90 日後
以前のバージョンを完全削除非現行バージョン30 日後
不完全なマルチパートアップロードを削除7 日後

「ルールを作成」をクリックします。

ℹ️ ストレージクラスとコスト
クラス用途相対コスト
Standard高頻度アクセス
Standard-IA低頻度(取り出し料あり)
Glacier Instantアーカイブ(即時取り出し)
Glacier Deep Archive長期保管(数時間で取り出し)最安
✅ 確認ポイント

ライフサイクルルール一覧に handson-tiering が「有効」で表示されれば成功です(実際の移行は設定日数の経過後にバックグラウンドで自動実行されます)。

🌏 ステップ 4 ― クロスリージョンレプリケーション(CRR)

4-1. レプリカ先バケットを作成

別リージョン(例: 大阪 ap-northeast-3)に handson-sec-dst-xxxx を作成します。バージョニングを有効化しておきます(レプリケーションの必須条件)。

4-2. レプリケーションルールを作成

ソースバケット handson-sec-src-xxxx →「管理」→「レプリケーションルール」→「レプリケーションルールを作成」をクリックします。

ルール名handson-crr
送信元バケット内のすべてのオブジェクト
送信先handson-sec-dst-xxxx(別リージョン)
IAM ロール新しいロールを作成

「保存」をクリックします。「既存オブジェクトのレプリケート」を問われたら、今回は新規オブジェクトのみで OK です。

4-3. レプリケーションを検証
# ソースに新規アップロード echo "replicate me" > repl.txt aws s3 cp repl.txt s3://handson-sec-src-xxxx/repl.txt # 数十秒後、レプリカ先を確認 aws s3 ls s3://handson-sec-dst-xxxx/ --region ap-northeast-3
✅ 確認ポイント

ソースにアップしたオブジェクトが別リージョンのバケットに自動コピーされ、オブジェクト詳細の「レプリケーションステータス」が COMPLETED になれば成功です。

📋 ステップ 5 ― アクセスログと分析(発展)

5-1. サーバーアクセスログを有効化

ログ保存用バケット handson-sec-log-xxxx を作成し、ソースバケットの「プロパティ」→「サーバーアクセスのログ記録」→「編集」で有効化、ログ先に作成したバケットを指定します。

5-2. CloudTrail データイベント(より詳細)

オブジェクトレベルの API(GetObject / PutObject)を確実に記録したい場合は CloudTrail の データイベント を有効にします。「誰が・いつ・どの IP から」アクセスしたかを追跡できます。

5-3. Athena で分析(任意)

ポータルの「S3 + Athena + Firehose」ハンズオンと連携し、アクセスログを Athena でクエリすると、アクセス元 IP やリクエスト数を集計できます。

✅ 確認ポイント

しばらく操作した後、ログバケットにアクセスログファイルが出力されていれば成功です(出力まで数時間かかる場合があります)。

🧹 クリーンアップ

⚠️ バージョニング有効バケットの削除は要注意

バージョニング有効バケットは、すべてのバージョンと削除マーカーを消さないと削除できません。下記手順で確実に削除してください。

削除手順

  1. レプリケーションルールを削除(ソースバケットの管理タブ)
  2. 全バケットのオブジェクト(全バージョン)を削除
    # バージョン込みで空にする(各バケットで実行) aws s3 rm s3://handson-sec-src-xxxx --recursive aws s3api delete-objects --bucket handson-sec-src-xxxx \ --delete "$(aws s3api list-object-versions --bucket handson-sec-src-xxxx \ --query '{Objects: Versions[].{Key:Key,VersionId:VersionId}}' --output json)" マネコンの「空にする」ボタンでも全バージョン削除できます。
  3. 3 つのバケットを削除
    src / dst / log バケットをそれぞれ削除
  4. レプリケーション用 IAM ロールを削除
    IAM → ロール → 自動作成された s3crr_role_... を削除

学習のまとめ

習得したスキル実践内容
公開ブロックBlock Public Access の 4 項目と安全弁の理解
バケットポリシーHTTPS 強制(aws:SecureTransport)など Deny ポリシー
バージョニング上書き・削除マーカー・誤削除からの復元
ライフサイクル階層化(IA / Glacier)・旧バージョンの自動失効
レプリケーションクロスリージョンの自動コピーで冗長化