コンテンツにスキップ
EBS スナップショット

EBS スナップショット

検証日: 2026-04-04 / リージョン: ap-northeast-1

概要

IAM Access Analyzer が EBS スナップショットの外部アクセスをどのように検出するかを検証する。

EBS スナップショットは modify-snapshot-attribute により外部アカウントへの共有やパブリック共有を設定できる。S3 の Block Public Access とは異なり、EBS の Block Public Access for Snapshots はデフォルトでは無効(unblocked)である(公式ドキュメント)。また、S3 の BPA がアカウントレベルとバケットレベルの 2 階層で設定できるのに対し、EBS の Block Public Access はアカウントレベルのみであり、スナップショット個別の設定はできない。--group-names all でパブリック共有を設定するとパブリックアクセスとして検出され、--user-ids で特定の外部アカウントを設定するとクロスアカウントアクセスとして検出される。

EBS スナップショットの外部アクセス制御レイヤー

レイヤーEBS スナップショットの状況
デフォルト保護Block Public Access for Snapshots(デフォルトでは無効)
予防(SCP)CT.EC2.PV.3(パブリック共有をブロック。クロスアカウント共有はブロックしない)
予防(Declarative)CT.EC2.PV.7(Block Public Access を強制。クロスアカウント共有はブロックしない)
Security Hub CSPMEC2.1(パブリック共有のチェック)
IAM Access Analyzerパブリック + クロスアカウントの到達可能性を分析
CT.EC2.PV.3(SCP)と CT.EC2.PV.7(Declarative)はどちらもパブリック共有のみをブロックし、特定アカウント ID へのクロスアカウント共有はブロックしない。本記事では CT.EC2.PV.3(SCP)との連動を検証する。CT.EC2.PV.7 の詳細は CT.EC2.PV.7 の検証記事 を参照。

結果

  • Block Public Access のデフォルト状態: EBS の Block Public Access for Snapshots はデフォルトでは無効(unblocked)。S3 の BPA(2023年4月以降デフォルト有効)とは異なる
  • パブリックアクセスの検出: modify-snapshot-attribute --group-names all でパブリック共有を設定すると、isPublic: true の finding が生成された。action は ec2:CopySnapshot, ec2:CreateVolume 等 7 つ
  • クロスアカウントアクセスの検出: --user-ids で組織外アカウントを設定すると、isPublic: false の finding が生成された。principal に組織外アカウント ID が特定された
  • 予防コントロール(CT.EC2.PV.3)との連動: CT.EC2.PV.3 は SCP 型であり、パブリック共有の設定操作(--group-names all)のみをブロックする。既存の共有には遡及せず、クロスアカウント共有(--user-ids)もブロックしない。resourceControlPolicyRestrictionNOT_APPLICABLE のまま変わらない
  • クリーンアップ: 共有を解除(modify-snapshot-attribute --operation-type remove)すると finding は RESOLVED になる

検証環境

検証環境の構成図

本記事のコマンドは、--profile 指定がない場合は Workload アカウントで実行する。IAM Access Analyzer の finding 確認は Audit アカウントで実行する。

検証の流れ

    flowchart LR
    A[1. 既存 finding の<br>確認] --> B[2. テスト用<br>スナップショット作成]
    B --> C[3. パブリックアクセス<br>検出の確認]
    C --> D[4. クロスアカウント<br>アクセス検出]
    D --> E[5. 予防コントロール<br>との連動]
    E --> F[6. クリーンアップ]
  

1. 既存 finding の確認

テスト用スナップショットを作成する前に、Block Public Access の状態と既存の EBS スナップショット finding を確認する。

Block Public Access の状態確認

aws ec2 get-snapshot-block-public-access-state
{
    "State": "unblocked",
    "ManagedBy": "account"
}

Block Public Access がデフォルトで無効(unblocked)であることを確認する。

既存 finding の確認

aws accessanalyzer list-findings-v2 \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
  --filter '{"status": {"eq": ["ACTIVE"]}, "resourceType": {"eq": ["AWS::EC2::Snapshot"]}}' \
  --query 'findings[].{id:id,resource:resource,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[]

2. テスト用スナップショットの作成

外部アカウントへの共有やパブリック共有を設定するスナップショットを作成する。検証目的のみで行い、ステップ 6 で削除する。

テスト用ボリュームを作成し、2 つのスナップショットを取得する。

aws ec2 create-volume \
  --availability-zone ap-northeast-1a \
  --size 1 \
  --volume-type gp3 \
  --query '{VolumeId:VolumeId}'
{
    "VolumeId": "<テスト用ボリューム ID>"
}

パブリック共有用スナップショット

aws ec2 create-snapshot \
  --volume-id <テスト用ボリューム ID> \
  --description "iaa-ebs-public-test" \
  --query '{SnapshotId:SnapshotId,State:State}'
{
    "SnapshotId": "<パブリックスナップショット ID>",
    "State": "pending"
}

パブリック共有を設定する。

aws ec2 modify-snapshot-attribute \
  --snapshot-id <パブリックスナップショット ID> \
  --attribute createVolumePermission \
  --operation-type add \
  --group-names all
(出力なし)

クロスアカウント共有用スナップショット

aws ec2 create-snapshot \
  --volume-id <テスト用ボリューム ID> \
  --description "iaa-ebs-crossaccount-test" \
  --query '{SnapshotId:SnapshotId,State:State}'
{
    "SnapshotId": "<クロスアカウントスナップショット ID>",
    "State": "pending"
}

クロスアカウント共有を設定する。

aws ec2 modify-snapshot-attribute \
  --snapshot-id <クロスアカウントスナップショット ID> \
  --attribute createVolumePermission \
  --operation-type add \
  --user-ids <組織外アカウント ID>
(出力なし)

3. パブリックアクセスの検出

ポリシー変更後、IAM Access Analyzer が finding を生成・更新するまで最大 30 分かかる場合がある。

パブリック共有スナップショットの finding を確認する。

aws accessanalyzer list-findings-v2 \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
  --filter '{"status": {"eq": ["ACTIVE"]}, "resource": {"contains": ["<パブリックスナップショット ID>"]}}' \
  --query 'findings[].{id:id,resource:resource,resourceType:resourceType,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[
    {
        "id": "<パブリックスナップショット finding ID>",
        "resource": "arn:aws:ec2:ap-northeast-1::snapshot/<パブリックスナップショット ID>",
        "resourceType": "AWS::EC2::Snapshot",
        "status": "ACTIVE"
    }
]

finding の詳細を確認する。

aws accessanalyzer get-finding-v2 \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
  --id <パブリックスナップショット finding ID> \
  --region ap-northeast-1 \
  --profile Audit
{
    "findingDetails": [
        {
            "externalAccessDetails": {
                "action": [
                    "ec2:CopySnapshot",
                    "ec2:CreateVolume",
                    "ec2:DescribeFastSnapshotRestores",
                    "ec2:DescribeSnapshotAttribute",
                    "ec2:DescribeSnapshots",
                    "ec2:DisableFastSnapshotRestores",
                    "ec2:EnableFastSnapshotRestores"
                ],
                "condition": {},
                "isPublic": true,
                "principal": {"AWS": "*"},
                "resourceControlPolicyRestriction": "NOT_APPLICABLE"
            }
        }
    ],
    "resource": "arn:aws:ec2:ap-northeast-1::snapshot/<パブリックスナップショット ID>",
    "status": "ACTIVE",
    "resourceType": "AWS::EC2::Snapshot",
    "findingType": "ExternalAccess",
    "resourceOwnerAccount": "<Workload アカウント ID>",
    "id": "<パブリックスナップショット finding ID>"
}

以下を確認する。

  • isPublictrue
  • principal{"AWS": "*"}
  • actionec2:CreateVolume 等が含まれる
  • resourceControlPolicyRestrictionNOT_APPLICABLE

組織外アカウントからの実際のアクセス確認

組織外アカウントからパブリックスナップショットを使ってボリュームを作成できることを確認する。

aws ec2 create-volume \
  --availability-zone ap-northeast-1a \
  --snapshot-id <パブリックスナップショット ID> \
  --volume-type gp3 \
  --query '{VolumeId:VolumeId,State:State}' \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
{
    "VolumeId": "<組織外ボリューム ID>",
    "State": "creating"
}

確認後、組織外アカウントで作成したボリュームを削除する。

aws ec2 delete-volume \
  --volume-id <組織外ボリューム ID> \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
(出力なし)

4. クロスアカウントアクセスの検出

クロスアカウント共有スナップショットの finding を確認する。

aws accessanalyzer list-findings-v2 \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
  --filter '{"status": {"eq": ["ACTIVE"]}, "resource": {"contains": ["<クロスアカウントスナップショット ID>"]}}' \
  --query 'findings[].{id:id,resource:resource,resourceType:resourceType,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[
    {
        "id": "<クロスアカウントスナップショット finding ID>",
        "resource": "arn:aws:ec2:ap-northeast-1::snapshot/<クロスアカウントスナップショット ID>",
        "resourceType": "AWS::EC2::Snapshot",
        "status": "ACTIVE"
    }
]

finding の詳細を確認する。

aws accessanalyzer get-finding-v2 \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
  --id <クロスアカウントスナップショット finding ID> \
  --region ap-northeast-1 \
  --profile Audit
{
    "findingDetails": [
        {
            "externalAccessDetails": {
                "action": [
                    "ec2:CopySnapshot",
                    "ec2:CreateVolume",
                    "ec2:DescribeFastSnapshotRestores",
                    "ec2:DescribeSnapshotAttribute",
                    "ec2:DescribeSnapshots",
                    "ec2:DisableFastSnapshotRestores",
                    "ec2:EnableFastSnapshotRestores"
                ],
                "condition": {},
                "isPublic": false,
                "principal": {"AWS": "<組織外アカウント ID>"},
                "resourceControlPolicyRestriction": "NOT_APPLICABLE"
            }
        }
    ],
    "resource": "arn:aws:ec2:ap-northeast-1::snapshot/<クロスアカウントスナップショット ID>",
    "status": "ACTIVE",
    "resourceType": "AWS::EC2::Snapshot",
    "findingType": "ExternalAccess",
    "resourceOwnerAccount": "<Workload アカウント ID>",
    "id": "<クロスアカウントスナップショット finding ID>"
}

以下を確認する。

  • isPublicfalse
  • principal に組織外アカウント ID が特定されている
  • actionec2:CreateVolume 等が含まれる
  • resourceControlPolicyRestrictionNOT_APPLICABLE

組織外アカウントからの実際のアクセス確認

組織外アカウントからクロスアカウントスナップショットを使ってボリュームを作成できることを確認する。

aws ec2 create-volume \
  --availability-zone ap-northeast-1a \
  --snapshot-id <クロスアカウントスナップショット ID> \
  --volume-type gp3 \
  --query '{VolumeId:VolumeId,State:State}' \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
{
    "VolumeId": "<組織外ボリューム ID>",
    "State": "creating"
}

確認後、組織外アカウントで作成したボリュームを削除する。

aws ec2 delete-volume \
  --volume-id <組織外ボリューム ID> \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
(出力なし)

5. 予防コントロール(CT.EC2.PV.3)との連動

本ステップは CT.EC2.PV.3(SCP: パブリック共有をブロック)が有効な環境で実施する。CT.EC2.PV.3 の詳細は CT.EC2.PV.3 の検証記事 を参照。
CT.EC2.PV.3 は SCP 型であり、パブリック共有(--group-names all)の新規設定のみをブロックする。既存のパブリック共有には遡及せず、クロスアカウント共有(--user-ids)もブロックしない。そのため、resourceControlPolicyRestrictionNOT_APPLICABLE のまま変わらない。

CT.EC2.PV.3 の有効化確認

CT.EC2.PV.3 が有効であることを確認する。

aws controltower list-enabled-controls \
  --target-identifier <対象 OU ARN> \
  --query "enabledControls[?controlIdentifier=='arn:aws:controlcatalog:::control/chlzfpsllhs3knp1ixr773wa6'].{controlIdentifier:controlIdentifier,statusSummary:statusSummary}" \
  --profile Master
[]

無効の場合は有効化する。

aws controltower enable-control \
  --control-identifier arn:aws:controlcatalog:::control/chlzfpsllhs3knp1ixr773wa6 \
  --target-identifier <対象 OU ARN> \
  --profile Master
{
    "operationIdentifier": "<オペレーション ID>"
}

既存のパブリック共有がブロックされないことの確認

CT.EC2.PV.3 が有効な状態でも、既存のパブリック共有スナップショットからのボリューム作成はブロックされないことを確認する。

aws ec2 create-volume \
  --availability-zone ap-northeast-1a \
  --snapshot-id <パブリックスナップショット ID> \
  --volume-type gp3 \
  --query '{VolumeId:VolumeId,State:State}' \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
{
    "VolumeId": "<組織外ボリューム ID>",
    "State": "creating"
}

SCP は modify-snapshot-attribute API をブロックするだけで、既存の共有設定によるアクセスには遡及しない。確認後、ボリュームを削除する。

aws ec2 delete-volume \
  --volume-id <組織外ボリューム ID> \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
(出力なし)

既存のクロスアカウント共有スナップショットからのボリューム作成も同様にブロックされないことを確認する。

aws ec2 create-volume \
  --availability-zone ap-northeast-1a \
  --snapshot-id <クロスアカウントスナップショット ID> \
  --volume-type gp3 \
  --query '{VolumeId:VolumeId,State:State}' \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
{
    "VolumeId": "<組織外ボリューム ID>",
    "State": "creating"
}

確認後、ボリュームを削除する。

aws ec2 delete-volume \
  --volume-id <組織外ボリューム ID> \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
(出力なし)

パブリック共有の設定がブロックされることの確認

CT.EC2.PV.3 が有効な状態で、クロスアカウント用スナップショットへのパブリック共有の設定がブロックされることを確認する。

aws ec2 modify-snapshot-attribute \
  --snapshot-id <クロスアカウントスナップショット ID> \
  --attribute createVolumePermission \
  --operation-type add \
  --group-names all
An error occurred (UnauthorizedOperation) when calling the ModifySnapshotAttribute operation: ...
with an explicit deny in a service control policy: ...

resourceControlPolicyRestriction の確認

再スキャンを実行し、SCP 型では resourceControlPolicyRestriction が変わらないことを確認する。

aws accessanalyzer start-resource-scan \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
  --resource-arn arn:aws:ec2:ap-northeast-1::snapshot/<パブリックスナップショット ID> \
  --resource-owner-account <Workload アカウント ID> \
  --region ap-northeast-1 \
  --profile Audit
(出力なし)
aws accessanalyzer get-finding-v2 \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
  --id <パブリックスナップショット finding ID> \
  --region ap-northeast-1 \
  --profile Audit

resourceControlPolicyRestrictionNOT_APPLICABLE のまま変わらないことを確認する。SCP 型のコントロールは IAM Access Analyzer の resourceControlPolicyRestriction には反映されない。また、RCP 型では再スキャンにより旧 finding が RESOLVED になり新しい finding ID で再生成されたが、SCP 型では finding ID も変わらない。

6. クリーンアップ

CT.EC2.PV.3 の無効化

ステップ 5 で CT.EC2.PV.3 を有効化した場合のみ無効化する。元々有効な環境ではそのまま有効にしておくこと。
aws controltower disable-control \
  --control-identifier arn:aws:controlcatalog:::control/chlzfpsllhs3knp1ixr773wa6 \
  --target-identifier <対象 OU ARN> \
  --profile Master
{
    "operationIdentifier": "<オペレーション ID>"
}

共有の解除

aws ec2 modify-snapshot-attribute \
  --snapshot-id <パブリックスナップショット ID> \
  --attribute createVolumePermission \
  --operation-type remove \
  --group-names all
(出力なし)
aws ec2 modify-snapshot-attribute \
  --snapshot-id <クロスアカウントスナップショット ID> \
  --attribute createVolumePermission \
  --operation-type remove \
  --user-ids <組織外アカウント ID>
(出力なし)

finding の確認

共有解除後、finding が RESOLVED になることを確認する。

aws accessanalyzer list-findings-v2 \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
  --filter '{"resourceType": {"eq": ["AWS::EC2::Snapshot"]}}' \
  --query 'findings[].{id:id,resource:resource,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[]

テスト用リソースの削除

aws ec2 delete-snapshot \
  --snapshot-id <パブリックスナップショット ID>
(出力なし)
aws ec2 delete-snapshot \
  --snapshot-id <クロスアカウントスナップショット ID>
(出力なし)
aws ec2 delete-volume \
  --volume-id <テスト用ボリューム ID>
(出力なし)

Amazonアソシエイトリンク