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

RDS スナップショット

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

概要

IAM Access Analyzer が RDS スナップショットの外部アクセスをどのように検出するかを検証する。本記事では DB スナップショット(AWS::RDS::DBSnapshot)とクラスタースナップショット(AWS::RDS::DBClusterSnapshot)の両方を検証する。

RDS スナップショットは modify-db-snapshot-attribute(DB スナップショット)または modify-db-cluster-snapshot-attribute(クラスタースナップショット)により、restore 属性に all を指定するとパブリック共有、特定のアカウント ID を指定するとクロスアカウント共有となる。S3 や EBS のような Block Public Access の仕組みは存在しない。デフォルトでは共有設定がなく、明示的に設定しない限り外部アクセスは発生しない。

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

レイヤーRDS スナップショットの状況
デフォルト保護なし(Block Public Access なし)
予防(SCP / RCP)Control Tower 予防コントロールなし
Security Hub CSPMRDS.1(パブリック共有のチェック)
IAM Access Analyzerパブリック + クロスアカウントの到達可能性を分析

結果

  • パブリックアクセスの検出: DB スナップショット・クラスタースナップショットともに、restore 属性に all を設定すると isPublic: true の finding が生成された。組織外アカウントからの復元(restore-db-instance-from-db-snapshot / restore-db-cluster-from-snapshot)も成功した
  • クロスアカウントアクセスの検出: restore 属性に組織外アカウント ID を設定すると isPublic: false の finding が生成された。principal に組織外アカウント ID が特定された。組織外アカウントからの復元も成功した
  • DB スナップショットとクラスタースナップショットの違い: resourceTypeAWS::RDS::DBSnapshot / AWS::RDS::DBClusterSnapshot)と actionrds:RestoreDBInstanceFromDBSnapshot / rds:RestoreDBClusterFromSnapshot 等)が異なる。検出の仕組みは同一
  • resourceControlPolicyRestriction: RDS スナップショットに対応する RCP 型予防コントロールは存在しないため、すべて NOT_APPLICABLE
  • 共有解除による finding の解消: restore 属性から共有先を削除すると finding は RESOLVED になった

検証環境

検証環境の構成図

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

検証の流れ

    flowchart LR
    A[1. 既存 finding の<br>確認] --> B[2. テスト用<br>スナップショット作成]
    B --> C[3. DB スナップショット<br>の検出]
    C --> D[4. クラスター<br>スナップショットの検出]
    D --> E[5. クリーンアップ]
  

1. 既存 finding の確認

テスト用スナップショットを作成する前に、既存の RDS スナップショット 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::RDS::DBSnapshot"]}}' \
  --query 'findings[].{id:id,resource:resource,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[]
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::RDS::DBClusterSnapshot"]}}' \
  --query 'findings[].{id:id,resource:resource,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[]

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

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

DB インスタンスと DB スナップショット

テスト用 DB インスタンスを作成する。

aws rds create-db-instance \
  --db-instance-identifier iaa-rds-test \
  --db-instance-class db.t4g.micro \
  --engine mysql \
  --master-username admin \
  --master-user-password <パスワード> \
  --allocated-storage 20 \
  --no-multi-az \
  --no-publicly-accessible

DB インスタンスが available になったら、2 つの DB スナップショットを作成する。

aws rds create-db-snapshot \
  --db-instance-identifier iaa-rds-test \
  --db-snapshot-identifier iaa-rds-public-test \
  --query '{DBSnapshotIdentifier:DBSnapshot.DBSnapshotIdentifier,Status:DBSnapshot.Status}'
{
    "DBSnapshotIdentifier": "iaa-rds-public-test",
    "Status": "creating"
}
aws rds create-db-snapshot \
  --db-instance-identifier iaa-rds-test \
  --db-snapshot-identifier iaa-rds-crossaccount-test \
  --query '{DBSnapshotIdentifier:DBSnapshot.DBSnapshotIdentifier,Status:DBSnapshot.Status}'
{
    "DBSnapshotIdentifier": "iaa-rds-crossaccount-test",
    "Status": "creating"
}

スナップショットが available になったら、共有を設定する。

aws rds modify-db-snapshot-attribute \
  --db-snapshot-identifier iaa-rds-public-test \
  --attribute-name restore \
  --values-to-add all
(出力なし)
aws rds modify-db-snapshot-attribute \
  --db-snapshot-identifier iaa-rds-crossaccount-test \
  --attribute-name restore \
  --values-to-add <組織外アカウント ID>
(出力なし)

Aurora クラスターとクラスタースナップショット

テスト用 Aurora クラスターを作成する。

aws rds create-db-cluster \
  --db-cluster-identifier iaa-aurora-test \
  --engine aurora-mysql \
  --master-username admin \
  --master-user-password <パスワード>

クラスターが available になったら、2 つのクラスタースナップショットを作成する。

aws rds create-db-cluster-snapshot \
  --db-cluster-identifier iaa-aurora-test \
  --db-cluster-snapshot-identifier iaa-aurora-public-test \
  --query '{DBClusterSnapshotIdentifier:DBClusterSnapshot.DBClusterSnapshotIdentifier,Status:DBClusterSnapshot.Status}'
{
    "DBClusterSnapshotIdentifier": "iaa-aurora-public-test",
    "Status": "creating"
}
aws rds create-db-cluster-snapshot \
  --db-cluster-identifier iaa-aurora-test \
  --db-cluster-snapshot-identifier iaa-aurora-crossaccount-test \
  --query '{DBClusterSnapshotIdentifier:DBClusterSnapshot.DBClusterSnapshotIdentifier,Status:DBClusterSnapshot.Status}'
{
    "DBClusterSnapshotIdentifier": "iaa-aurora-crossaccount-test",
    "Status": "creating"
}

スナップショットが available になったら、共有を設定する。

aws rds modify-db-cluster-snapshot-attribute \
  --db-cluster-snapshot-identifier iaa-aurora-public-test \
  --attribute-name restore \
  --values-to-add all
(出力なし)
aws rds modify-db-cluster-snapshot-attribute \
  --db-cluster-snapshot-identifier iaa-aurora-crossaccount-test \
  --attribute-name restore \
  --values-to-add <組織外アカウント ID>
(出力なし)

3. DB スナップショットの検出

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

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

パブリック共有 DB スナップショットの 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": ["iaa-rds-public-test"]}}' \
  --query 'findings[].{id:id,resource:resource,resourceType:resourceType,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[
    {
        "id": "<DB パブリックスナップショット finding ID>",
        "resource": "arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:snapshot:iaa-rds-public-test",
        "resourceType": "AWS::RDS::DBSnapshot",
        "status": "ACTIVE"
    }
]

finding の詳細を確認する。

aws accessanalyzer get-finding-v2 \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
  --id <DB パブリックスナップショット finding ID> \
  --region ap-northeast-1 \
  --profile Audit
{
    "findingDetails": [
        {
            "externalAccessDetails": {
                "action": [
                    "rds:CopyDBSnapshot",
                    "rds:DescribeDBSnapshots",
                    "rds:RestoreDBInstanceFromDBSnapshot"
                ],
                "condition": {},
                "isPublic": true,
                "principal": {"AWS": "*"},
                "resourceControlPolicyRestriction": "NOT_APPLICABLE"
            }
        }
    ],
    "resource": "arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:snapshot:iaa-rds-public-test",
    "status": "ACTIVE",
    "resourceType": "AWS::RDS::DBSnapshot",
    "findingType": "ExternalAccess",
    "resourceOwnerAccount": "<Workload アカウント ID>",
    "id": "<DB パブリックスナップショット finding ID>"
}

以下を確認する。

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

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

組織外アカウントからパブリック DB スナップショットを使って DB インスタンスを復元できることを確認する。

aws rds restore-db-instance-from-db-snapshot \
  --db-instance-identifier iaa-rds-restore-public \
  --db-snapshot-identifier arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:snapshot:iaa-rds-public-test \
  --db-instance-class db.t4g.micro \
  --query '{DBInstanceIdentifier:DBInstance.DBInstanceIdentifier,DBInstanceStatus:DBInstance.DBInstanceStatus}' \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
{
    "DBInstanceIdentifier": "iaa-rds-restore-public",
    "DBInstanceStatus": "creating"
}

確認後、組織外アカウントで復元した DB インスタンスを削除する。

aws rds delete-db-instance \
  --db-instance-identifier iaa-rds-restore-public \
  --skip-final-snapshot \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
(出力なし)

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

クロスアカウント共有 DB スナップショットの 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": ["iaa-rds-crossaccount-test"]}}' \
  --query 'findings[].{id:id,resource:resource,resourceType:resourceType,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[
    {
        "id": "<DB クロスアカウントスナップショット finding ID>",
        "resource": "arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:snapshot:iaa-rds-crossaccount-test",
        "resourceType": "AWS::RDS::DBSnapshot",
        "status": "ACTIVE"
    }
]

finding の詳細を確認する。

aws accessanalyzer get-finding-v2 \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
  --id <DB クロスアカウントスナップショット finding ID> \
  --region ap-northeast-1 \
  --profile Audit
{
    "findingDetails": [
        {
            "externalAccessDetails": {
                "action": [
                    "rds:CopyDBSnapshot",
                    "rds:DescribeDBSnapshots",
                    "rds:RestoreDBInstanceFromDBSnapshot"
                ],
                "condition": {},
                "isPublic": false,
                "principal": {"AWS": "<組織外アカウント ID>"},
                "resourceControlPolicyRestriction": "NOT_APPLICABLE"
            }
        }
    ],
    "resource": "arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:snapshot:iaa-rds-crossaccount-test",
    "status": "ACTIVE",
    "resourceType": "AWS::RDS::DBSnapshot",
    "findingType": "ExternalAccess",
    "resourceOwnerAccount": "<Workload アカウント ID>",
    "id": "<DB クロスアカウントスナップショット finding ID>"
}

以下を確認する。

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

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

組織外アカウントからクロスアカウント DB スナップショットを使って DB インスタンスを復元できることを確認する。

aws rds restore-db-instance-from-db-snapshot \
  --db-instance-identifier iaa-rds-restore-crossaccount \
  --db-snapshot-identifier arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:snapshot:iaa-rds-crossaccount-test \
  --db-instance-class db.t4g.micro \
  --query '{DBInstanceIdentifier:DBInstance.DBInstanceIdentifier,DBInstanceStatus:DBInstance.DBInstanceStatus}' \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
{
    "DBInstanceIdentifier": "iaa-rds-restore-crossaccount",
    "DBInstanceStatus": "creating"
}

確認後、組織外アカウントで復元した DB インスタンスを削除する。

aws rds delete-db-instance \
  --db-instance-identifier iaa-rds-restore-crossaccount \
  --skip-final-snapshot \
  --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": ["iaa-aurora-public-test"]}}' \
  --query 'findings[].{id:id,resource:resource,resourceType:resourceType,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[
    {
        "id": "<クラスターパブリックスナップショット finding ID>",
        "resource": "arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:cluster-snapshot:iaa-aurora-public-test",
        "resourceType": "AWS::RDS::DBClusterSnapshot",
        "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": [
                    "rds:CopyDBClusterSnapshot",
                    "rds:DescribeDBClusterSnapshots",
                    "rds:RestoreDBClusterFromSnapshot"
                ],
                "condition": {},
                "isPublic": true,
                "principal": {"AWS": "*"},
                "resourceControlPolicyRestriction": "NOT_APPLICABLE"
            }
        }
    ],
    "resource": "arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:cluster-snapshot:iaa-aurora-public-test",
    "status": "ACTIVE",
    "resourceType": "AWS::RDS::DBClusterSnapshot",
    "findingType": "ExternalAccess",
    "resourceOwnerAccount": "<Workload アカウント ID>",
    "id": "<クラスターパブリックスナップショット finding ID>"
}

DB スナップショットとの違い:

  • resourceTypeAWS::RDS::DBClusterSnapshot
  • actionrds:CopyDBClusterSnapshot, rds:DescribeDBClusterSnapshots, rds:RestoreDBClusterFromSnapshot(DB スナップショットとは異なるアクション名)

以下を確認する。

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

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

組織外アカウントからパブリッククラスタースナップショットを使ってクラスターを復元できることを確認する。

aws rds restore-db-cluster-from-snapshot \
  --db-cluster-identifier iaa-aurora-restore-public \
  --snapshot-identifier arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:cluster-snapshot:iaa-aurora-public-test \
  --engine aurora-mysql \
  --query '{DBClusterIdentifier:DBCluster.DBClusterIdentifier,Status:DBCluster.Status}' \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
{
    "DBClusterIdentifier": "iaa-aurora-restore-public",
    "Status": "creating"
}

確認後、組織外アカウントで復元したクラスターを削除する。

aws rds delete-db-cluster \
  --db-cluster-identifier iaa-aurora-restore-public \
  --skip-final-snapshot \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
(出力なし)

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

クロスアカウント共有クラスタースナップショットの 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": ["iaa-aurora-crossaccount-test"]}}' \
  --query 'findings[].{id:id,resource:resource,resourceType:resourceType,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[
    {
        "id": "<クラスタークロスアカウントスナップショット finding ID>",
        "resource": "arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:cluster-snapshot:iaa-aurora-crossaccount-test",
        "resourceType": "AWS::RDS::DBClusterSnapshot",
        "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": [
                    "rds:CopyDBClusterSnapshot",
                    "rds:DescribeDBClusterSnapshots",
                    "rds:RestoreDBClusterFromSnapshot"
                ],
                "condition": {},
                "isPublic": false,
                "principal": {"AWS": "<組織外アカウント ID>"},
                "resourceControlPolicyRestriction": "NOT_APPLICABLE"
            }
        }
    ],
    "resource": "arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:cluster-snapshot:iaa-aurora-crossaccount-test",
    "status": "ACTIVE",
    "resourceType": "AWS::RDS::DBClusterSnapshot",
    "findingType": "ExternalAccess",
    "resourceOwnerAccount": "<Workload アカウント ID>",
    "id": "<クラスタークロスアカウントスナップショット finding ID>"
}

以下を確認する。

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

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

組織外アカウントからクロスアカウントクラスタースナップショットを使ってクラスターを復元できることを確認する。

aws rds restore-db-cluster-from-snapshot \
  --db-cluster-identifier iaa-aurora-restore-crossaccount \
  --snapshot-identifier arn:aws:rds:ap-northeast-1:<Workload アカウント ID>:cluster-snapshot:iaa-aurora-crossaccount-test \
  --engine aurora-mysql \
  --query '{DBClusterIdentifier:DBCluster.DBClusterIdentifier,Status:DBCluster.Status}' \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
{
    "DBClusterIdentifier": "iaa-aurora-restore-crossaccount",
    "Status": "creating"
}

確認後、組織外アカウントで復元したクラスターを削除する。

aws rds delete-db-cluster \
  --db-cluster-identifier iaa-aurora-restore-crossaccount \
  --skip-final-snapshot \
  --profile <組織外プロファイル> \
  --region ap-northeast-1
(出力なし)

5. クリーンアップ

共有の解除

DB スナップショットの共有を解除する。

aws rds modify-db-snapshot-attribute \
  --db-snapshot-identifier iaa-rds-public-test \
  --attribute-name restore \
  --values-to-remove all
(出力なし)
aws rds modify-db-snapshot-attribute \
  --db-snapshot-identifier iaa-rds-crossaccount-test \
  --attribute-name restore \
  --values-to-remove <組織外アカウント ID>
(出力なし)

クラスタースナップショットの共有を解除する。

aws rds modify-db-cluster-snapshot-attribute \
  --db-cluster-snapshot-identifier iaa-aurora-public-test \
  --attribute-name restore \
  --values-to-remove all
(出力なし)
aws rds modify-db-cluster-snapshot-attribute \
  --db-cluster-snapshot-identifier iaa-aurora-crossaccount-test \
  --attribute-name restore \
  --values-to-remove <組織外アカウント 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 '{"status": {"eq": ["ACTIVE"]}, "resourceType": {"eq": ["AWS::RDS::DBSnapshot"]}}' \
  --query 'findings[].{id:id,resource:resource,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[]
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::RDS::DBClusterSnapshot"]}}' \
  --query 'findings[].{id:id,resource:resource,status:status}' \
  --region ap-northeast-1 \
  --profile Audit
[]

テスト用リソースの削除

aws rds delete-db-snapshot \
  --db-snapshot-identifier iaa-rds-public-test
(出力なし)
aws rds delete-db-snapshot \
  --db-snapshot-identifier iaa-rds-crossaccount-test
(出力なし)
aws rds delete-db-cluster-snapshot \
  --db-cluster-snapshot-identifier iaa-aurora-public-test
(出力なし)
aws rds delete-db-cluster-snapshot \
  --db-cluster-snapshot-identifier iaa-aurora-crossaccount-test
(出力なし)
aws rds delete-db-instance \
  --db-instance-identifier iaa-rds-test \
  --skip-final-snapshot
(出力なし)
aws rds delete-db-cluster \
  --db-cluster-identifier iaa-aurora-test \
  --skip-final-snapshot
(出力なし)

Amazonアソシエイトリンク