CT.EC2.PV.3
コントロールの説明
EBS スナップショットをパブリックに共有する操作を禁止(拒否)します。
ここでいう「パブリック共有」とは、スナップショット単位の createVolumePermission に Group: all を設定し、世界中の全 AWS アカウントがそのスナップショットからボリュームを作成できる状態にすることを指します。デフォルトでは CreateVolumePermissions は空(プライベート=自アカウントのみ)です。
Security Hub CSPM の [EC2.1] は「EBS スナップショットがパブリック共有されていないか」をチェック(検出)しますが、本コントロールを有効にすることで、そもそもパブリックへの属性変更操作自体を API レベルでブロックします。
なお、同じ目的のコントロールとして [CT.EC2.PV.7](Declarative Policy)があります。PV.7 はアカウントレベルで「Block Public Access for EBS Snapshots」を強制し、既にパブリック共有されていたスナップショットもプライベート扱いにします。PV.3(SCP)は API コールをブロックするだけで、有効化前にパブリック共有されていたスナップショットはそのまま維持されるため、PV.7 の方がより強力です。
検証の流れ
flowchart LR
A[1. 事前準備] --> B[2. パブリック共有<br>成功を確認]
B --> C[3. Security Hub EC2.1<br>で検出を確認]
C --> D[4. CT.EC2.PV.3<br>有効化]
D --> E[5. 既存パブリック共有<br>維持を確認]
D --> F[6. 新規パブリック共有<br>拒否を確認]
D --> G[7. パブリック共有の<br>解除は可能]
E & F & G --> H[8. CT.EC2.PV.3<br>無効化]
H --> I[9. パブリック共有<br>成功を確認]
結果
- コントロールの有効化前、EBS スナップショットをパブリック共有に設定でき、Security Hub [EC2.1] で「FAILED」として検出されることを確認できた。
- コントロールの有効化後、スナップショットの
createVolumePermissionにGroup: allを追加する操作が拒否されることを確認できた。 - 有効化前にパブリック共有されていたスナップショットについては、有効化後もパブリック設定が維持され、強制的なプライベート化は行われないことを確認できた。
- 有効化中でも、パブリック共有の解除(remove)は制限されないことを確認できた。SCP は
ec2:Add/group: allの条件でのみブロックするため、解除方向は許可される。 - 拒否時、「explicit deny in a service control policy」というメッセージが表示されるため、SCP による制御であることを確認できた。
- コントロールの無効化後、再びパブリック共有が可能になることを確認できた。
1. 事前準備
検証用の EBS ボリュームを作成し、スナップショットを取得する。
aws ec2 create-volume \
--availability-zone ap-northeast-1a \
--size 1 \
--volume-type gp3 \
--tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=ct-ec2-pv3-test}]' \
--query '{VolumeId:VolumeId,State:State}'{
"VolumeId": "vol-07f8f228d218d1412",
"State": "available"
}aws ec2 create-snapshot \
--volume-id <ボリューム ID> \
--description "ct-ec2-pv3-test" \
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=ct-ec2-pv3-test}]' \
--query '{SnapshotId:SnapshotId,State:State}'{
"SnapshotId": "snap-09a1a0c2f3564ec5b",
"State": "completed"
}スナップショットの共有設定がデフォルト(プライベート)であることを確認する。
aws ec2 describe-snapshot-attribute \
--snapshot-id <スナップショット ID> \
--attribute createVolumePermission{
"SnapshotId": "snap-09a1a0c2f3564ec5b",
"CreateVolumePermissions": []
}CreateVolumePermissions が空であれば、自アカウントのみがアクセス可能な状態(デフォルト)。
2. コントロール有効化前の確認
スナップショットをパブリック共有に設定する。
aws ec2 modify-snapshot-attribute \
--snapshot-id <スナップショット ID> \
--attribute createVolumePermission \
--operation-type add \
--group-names allパブリック共有されたことを確認する。
aws ec2 describe-snapshot-attribute \
--snapshot-id <スナップショット ID> \
--attribute createVolumePermission{
"SnapshotId": "snap-09a1a0c2f3564ec5b",
"CreateVolumePermissions": [
{
"Group": "all"
}
]
}Group: all が設定され、全 AWS アカウントからこのスナップショットを使ってボリュームを作成できる状態になった。
3. Security Hub CSPM での検出確認
Security Hub の [EC2.1](EBS snapshots should not be publicly restorable)でパブリック共有スナップショットが検出されることを確認する。
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Value": "EC2.1", "Comparison": "EQUALS"}],
"AwsAccountId": [{"Value": "<Workload のアカウント ID>", "Comparison": "EQUALS"}],
"ComplianceStatus": [{"Value": "FAILED", "Comparison": "EQUALS"}]
}' \
--query 'Findings[0].{Title:Title,ComplianceStatus:Compliance.Status,Severity:Severity.Label}'{
"Title": "EBS snapshots should not be publicly restorable",
"ComplianceStatus": "FAILED",
"Severity": "CRITICAL"
}4. 対象の予防コントロールを有効化(例外設定なし)
パブリック共有されたスナップショットが存在する状態のまま、コントロールを有効化する。
Control Tower の管理アカウントで、対象の OU にコントロールが有効になっていないことを確認する。
aws controltower list-enabled-controls \
--target-identifier <OU の ARN>{
"enabledControls": []
}コントロールを有効化する。
aws controltower enable-control \
--control-identifier arn:aws:controlcatalog:::control/chlzfpsllhs3knp1ixr773wa6 \
--target-identifier <OU の ARN>{
"arn": "arn:aws:controltower:ap-northeast-1:<管理アカウント ID>:enabledcontrol/<enabledcontrol ID>",
"operationIdentifier": "<オペレーション ID>"
}有効化が完了するまで待機する。
aws controltower get-control-operation \
--operation-identifier <オペレーション ID>{
"controlOperation": {
"operationType": "ENABLE_CONTROL",
"status": "SUCCEEDED",
"statusMessage": "Operation was successful."
}
}5. 有効化後の挙動確認(既存パブリック共有の維持)
有効化前にパブリック共有されていたスナップショットが、有効化後もパブリック設定のまま維持されていることを確認する。
aws ec2 describe-snapshot-attribute \
--snapshot-id <スナップショット ID> \
--attribute createVolumePermission{
"SnapshotId": "snap-09a1a0c2f3564ec5b",
"CreateVolumePermissions": [
{
"Group": "all"
}
]
}SCP は API コールをブロックするだけであり、有効化前に設定済みのパブリック共有は強制的にプライベート化されない。
6. 新規パブリック共有は制限(拒否)されることの確認
別のスナップショットを作成し、パブリック共有を試みる。
aws ec2 create-snapshot \
--volume-id <ボリューム ID> \
--description "ct-ec2-pv3-test-after" \
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=ct-ec2-pv3-test-after}]' \
--query '{SnapshotId:SnapshotId,State:State}'{
"SnapshotId": "snap-08447a38904ba0401",
"State": "completed"
}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:
You are not authorized to perform this operation.
User: arn:aws:sts::<Workload のアカウント ID>:assumed-role/<ロール名>/<ユーザー名>
is not authorized to perform: ec2:ModifySnapshotAttribute on resource:
arn:aws:ec2:ap-northeast-1::snapshot/<スナップショット ID>
with an explicit deny in a service control policy7. パブリック共有の解除は制限されないことの確認
SCP は ec2:Add/group が all の場合のみブロックするため、パブリック共有の解除(remove)は制限されない。ステップ 5 で確認したパブリック共有中のスナップショットで確認する。
aws ec2 modify-snapshot-attribute \
--snapshot-id <パブリック共有中のスナップショット ID> \
--attribute createVolumePermission \
--operation-type remove \
--group-names allaws ec2 describe-snapshot-attribute \
--snapshot-id <スナップショット ID> \
--attribute createVolumePermission{
"SnapshotId": "snap-09a1a0c2f3564ec5b",
"CreateVolumePermissions": []
}パブリック共有の解除は正常に実行できた。
8. 対象の予防コントロールを無効化
検証完了後、コントロールを無効化する。
aws controltower disable-control \
--control-identifier arn:aws:controlcatalog:::control/chlzfpsllhs3knp1ixr773wa6 \
--target-identifier <OU の ARN>{
"operationIdentifier": "<オペレーション ID>"
}aws controltower get-control-operation \
--operation-identifier <オペレーション ID>{
"controlOperation": {
"operationType": "DISABLE_CONTROL",
"status": "SUCCEEDED",
"statusMessage": "Operation was successful."
}
}9. 制限解除の確認
コントロール無効化後、再びパブリック共有が可能になることを確認する。
aws ec2 modify-snapshot-attribute \
--snapshot-id <スナップショット ID> \
--attribute createVolumePermission \
--operation-type add \
--group-names allaws ec2 describe-snapshot-attribute \
--snapshot-id <スナップショット ID> \
--attribute createVolumePermission{
"SnapshotId": "snap-09a1a0c2f3564ec5b",
"CreateVolumePermissions": [
{
"Group": "all"
}
]
}パブリック共有が再び可能になり、制限が解除されたことを確認できた。
10. クリーンアップ
検証で作成したリソースをすべて削除する。パブリック共有も解除しておく。
# パブリック共有を解除
aws ec2 modify-snapshot-attribute \
--snapshot-id <スナップショット ID> \
--attribute createVolumePermission \
--operation-type remove \
--group-names all
# スナップショットを削除
aws ec2 delete-snapshot --snapshot-id <スナップショット ID>
aws ec2 delete-snapshot --snapshot-id <スナップショット ID>
# EBS ボリュームを削除
aws ec2 delete-volume --volume-id <ボリューム ID>おまけ: Security Hub の検出を早める方法
Security Hub のコンプライアンスチェックはスケジュールベース(最大 12 時間間隔)で実行されるため、リソースの変更が即座に反映されない場合がある。検証時など、すぐに検出結果を確認したい場合は、対応する AWS Config ルールの評価を手動でトリガーできる。
Security Hub のコントロールは内部的に AWS Config ルールとして実装されている。EC2.1 に対応する Config ルールは SourceIdentifier が EBS_SNAPSHOT_PUBLIC_RESTORABLE_CHECK なので、これを条件にルール名を取得する。
aws configservice describe-config-rules \
--query 'ConfigRules[?Source.SourceIdentifier==`EBS_SNAPSHOT_PUBLIC_RESTORABLE_CHECK`].ConfigRuleName'出力例(末尾のハッシュ値は環境ごとに異なる):
[
"securityhub-ebs-snapshot-public-restorable-check-ab81288f"
]取得したルール名を指定して、評価を手動トリガーする。
aws configservice start-config-rules-evaluation \
--config-rule-names <上記で取得したルール名>数十秒〜1 分程度で評価が完了し、結果が Security Hub に反映される。