コンテンツにスキップ

RDS.1

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

概要

RDS.1 は RDS DB インスタンススナップショットがパブリック化されている場合に FAILED となる Security Hub CSPM コントロール。本記事では、Security Hub finding を EventBridge でフィルタし、SSM Automation の AWSSupport-ModifyRDSSnapshotPermission を起動してスナップショットを自動的にプライベートに戻す構成を検証する。

自動修復の構成

RDS スナップショットがパブリック化(modify-db-snapshot-attribute --values-to-add all)
  → Config ルール securityhub-rds-snapshots-public-prohibited-<サフィックス> が NON_COMPLIANT
  → Security Hub finding RDS.1 が FAILED
  → EventBridge ルールが finding をフィルタ(Input Transformer でスナップショット ID 抽出)
  → SSM Automation AWSSupport-ModifyRDSSnapshotPermission を起動(Private=Yes)
  → modify-db-snapshot-attribute --values-to-remove all 実行
  → スナップショットがプライベートに戻る
  → Config 再評価 → COMPLIANT
  → Security Hub finding → PASSED

使用するランブック

AWSSupport-ModifyRDSSnapshotPermission(AWS マネージド)を使用する。RDS DB インスタンススナップショットのみ対応で、クラスタースナップショット(DocumentDB / Neptune)には別途カスタムランブックが必要。

パラメータ役割
SnapshotIdentifiersStringList修復対象スナップショット ID(finding から抽出して渡す)
PrivateStringYes 固定
AutomationAssumeRoleARNSSM Automation が rds:ModifyDBSnapshotAttribute を呼ぶための IAM ロール

Security Hub finding 構造

Security Hub finding の Resources[0].Details.AwsRdsDbSnapshot.DbSnapshotIdentifier にスナップショット ID が ID 形式(ARN ではない)で含まれる。EventBridge Input Transformer で直接抽出可能。

{
  "Resources": [{
    "Type": "AwsRdsDbSnapshot",
    "Id": "arn:aws:rds:<リージョン>:<アカウント ID>:snapshot:<スナップショット ID>",
    "Details": {
      "AwsRdsDbSnapshot": {
        "DbSnapshotIdentifier": "<スナップショット ID>",
        ...
      }
    }
  }]
}

検証環境

検証環境の構成図

本記事のコマンドは、--profile 指定がない場合は Workload アカウントで実行する。事前に export AWS_PROFILE=Workload でデフォルトを設定しておくと便利。

検証の流れ

    flowchart LR
    A[1. 事前確認] --> B[2. 修復用 IAM ロール作成]
    B --> C[3. EventBridge ルール作成]
    C --> D[4. RDS インスタンス・<br>スナップショット作成]
    D --> E[5. パブリック化<br>FAILED 検知]
    E --> F[6. 自動修復実行確認]
    F --> G[7. PASSED 復帰確認]
    G --> H[8. クリーンアップ]
  

結果

検証項目結果
Security Hub finding(FAILED)から EventBridge へのトリガーTBD
Input Transformer でスナップショット ID 抽出TBD
SSM Automation 起動と修復実行TBD
スナップショットのパブリック共有解除TBD
Config / Security Hub PASSED 復帰TBD

1. 事前確認

Config ルールの存在確認

aws configservice describe-config-rules \
  --query "ConfigRules[?contains(ConfigRuleName, 'rds-snapshots-public-prohibited')].ConfigRuleName" \
  --output text \
  --region ap-northeast-1
securityhub-rds-snapshots-public-prohibited-<サフィックス>

既存の EventBridge ルール確認

aws events list-rules \
  --name-prefix "rds-1-auto-remediation" \
  --region ap-northeast-1 \
  --query 'Rules[].Name' \
  --output json
[]

2. 修復用 IAM ロール作成

SSM Automation が rds:ModifyDBSnapshotAttribute を呼ぶための IAM ロールと、EventBridge が SSM Automation を起動するための IAM ロールの 2 つを作成する。

2.1 SSM Automation 実行ロール

cat <<'EOF' > /tmp/ssm-automation-trust.json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Service": "ssm.amazonaws.com"},
    "Action": "sts:AssumeRole"
  }]
}
EOF

aws iam create-role \
  --role-name rds-1-automation-role \
  --assume-role-policy-document file:///tmp/ssm-automation-trust.json \
  --query 'Role.Arn' \
  --output text
arn:aws:iam::<アカウント ID>:role/rds-1-automation-role
cat <<'EOF' > /tmp/rds-snapshot-policy.json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "rds:DescribeDBSnapshots",
      "rds:DescribeDBSnapshotAttributes",
      "rds:ModifyDBSnapshotAttribute"
    ],
    "Resource": "*"
  }]
}
EOF

aws iam put-role-policy \
  --role-name rds-1-automation-role \
  --policy-name rds-snapshot-permission \
  --policy-document file:///tmp/rds-snapshot-policy.json

(出力なし)

2.2 EventBridge から SSM Automation 起動するロール

cat <<'EOF' > /tmp/eventbridge-trust.json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Service": "events.amazonaws.com"},
    "Action": "sts:AssumeRole"
  }]
}
EOF

aws iam create-role \
  --role-name rds-1-eventbridge-role \
  --assume-role-policy-document file:///tmp/eventbridge-trust.json \
  --query 'Role.Arn' \
  --output text
arn:aws:iam::<アカウント ID>:role/rds-1-eventbridge-role
cat <<'EOF' > /tmp/eventbridge-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ssm:StartAutomationExecution",
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::<アカウント ID>:role/rds-1-automation-role",
      "Condition": {
        "StringEquals": {
          "iam:PassedToService": "ssm.amazonaws.com"
        }
      }
    }
  ]
}
EOF

aws iam put-role-policy \
  --role-name rds-1-eventbridge-role \
  --policy-name eventbridge-ssm-automation \
  --policy-document file:///tmp/eventbridge-policy.json

(出力なし)

3. EventBridge ルール作成

3.1 ルール本体作成

Security Hub finding のうち、RDS.1 で FAILED のものをフィルタする。

cat <<'EOF' > /tmp/eventbridge-pattern.json
{
  "source": ["aws.securityhub"],
  "detail-type": ["Security Hub Findings - Imported"],
  "detail": {
    "findings": {
      "Compliance": {
        "SecurityControlId": ["RDS.1"],
        "Status": ["FAILED"]
      },
      "Resources": {
        "Type": ["AwsRdsDbSnapshot"]
      }
    }
  }
}
EOF

aws events put-rule \
  --name rds-1-auto-remediation \
  --event-pattern file:///tmp/eventbridge-pattern.json \
  --state ENABLED \
  --region ap-northeast-1 \
  --query 'RuleArn' \
  --output text
arn:aws:events:ap-northeast-1:<アカウント ID>:rule/rds-1-auto-remediation

3.2 ターゲット設定(Input Transformer 付き)

EVENTBRIDGE_ROLE_ARN=$(aws iam get-role \
  --role-name rds-1-eventbridge-role \
  --query 'Role.Arn' \
  --output text)

AUTOMATION_ROLE_ARN=$(aws iam get-role \
  --role-name rds-1-automation-role \
  --query 'Role.Arn' \
  --output text)

cat <<EOF > /tmp/eventbridge-target.json
[
  {
    "Id": "ssm-automation-target",
    "Arn": "arn:aws:ssm:ap-northeast-1::automation-definition/AWSSupport-ModifyRDSSnapshotPermission:\$DEFAULT",
    "RoleArn": "$EVENTBRIDGE_ROLE_ARN",
    "InputTransformer": {
      "InputPathsMap": {
        "snapshotId": "\$.detail.findings[0].Resources[0].Details.AwsRdsDbSnapshot.DbSnapshotIdentifier"
      },
      "InputTemplate": "{\"SnapshotIdentifiers\": [\"<snapshotId>\"], \"Private\": [\"Yes\"], \"AutomationAssumeRole\": [\"$AUTOMATION_ROLE_ARN\"]}"
    }
  }
]
EOF

aws events put-targets \
  --rule rds-1-auto-remediation \
  --targets file:///tmp/eventbridge-target.json \
  --region ap-northeast-1
{
    "FailedEntryCount": 0,
    "FailedEntries": []
}

4. RDS インスタンス・スナップショット作成

4.1 RDS インスタンス作成

aws rds create-db-instance \
  --db-instance-identifier rds1-remediation-test \
  --db-instance-class db.t3.micro \
  --engine mysql \
  --master-username admin \
  --master-user-password '<パスワード>' \
  --allocated-storage 20 \
  --no-publicly-accessible \
  --db-subnet-group-name default \
  --no-multi-az \
  --backup-retention-period 0 \
  --region ap-northeast-1 \
  --query 'DBInstance.{DBInstanceIdentifier:DBInstanceIdentifier,Status:DBInstanceStatus}' \
  --output json
{
    "DBInstanceIdentifier": "rds1-remediation-test",
    "Status": "creating"
}

available 待ち(約 5〜7 分)。

while true; do
  STATUS=$(aws rds describe-db-instances \
    --db-instance-identifier rds1-remediation-test \
    --query 'DBInstances[0].DBInstanceStatus' \
    --output text \
    --region ap-northeast-1)
  echo "$(date '+%H:%M:%S') status: $STATUS"
  case "$STATUS" in
    available) break ;;
    failed) echo "失敗"; break ;;
    *) sleep 60 ;;
  esac
done
HH:MM:SS status: creating
(数分間 creating を繰り返す)
HH:MM:SS status: available

4.2 スナップショット作成

aws rds create-db-snapshot \
  --db-instance-identifier rds1-remediation-test \
  --db-snapshot-identifier rds1-remediation-snapshot \
  --region ap-northeast-1 \
  --query 'DBSnapshot.{DBSnapshotIdentifier:DBSnapshotIdentifier,Status:Status}' \
  --output json

while true; do
  STATUS=$(aws rds describe-db-snapshots \
    --db-snapshot-identifier rds1-remediation-snapshot \
    --query 'DBSnapshots[0].Status' \
    --output text \
    --region ap-northeast-1)
  echo "$(date '+%H:%M:%S') snapshot: $STATUS"
  case "$STATUS" in
    available) break ;;
    failed) echo "失敗"; break ;;
    *) sleep 30 ;;
  esac
done

5. パブリック化して FAILED を確認

5.1 スナップショットをパブリック化

aws rds modify-db-snapshot-attribute \
  --db-snapshot-identifier rds1-remediation-snapshot \
  --attribute-name restore \
  --values-to-add all \
  --region ap-northeast-1 \
  --query 'DBSnapshotAttributesResult.DBSnapshotAttributes' \
  --output json
[
    {
        "AttributeName": "restore",
        "AttributeValues": [
            "all"
        ]
    }
]

5.2 Security Hub finding が FAILED になることを確認

Security Hub への反映には数分かかる。

sleep 300

aws securityhub get-findings \
  --filters '{"ComplianceSecurityControlId":[{"Comparison":"EQUALS","Value":"RDS.1"}],"ComplianceStatus":[{"Comparison":"EQUALS","Value":"FAILED"}],"ResourceId":[{"Comparison":"PREFIX","Value":"arn:aws:rds:ap-northeast-1:<アカウント ID>:snapshot:rds1-remediation-snapshot"}]}' \
  --region ap-northeast-1 \
  --query 'Findings[0].{Status:Compliance.Status,SnapshotId:Resources[0].Details.AwsRdsDbSnapshot.DbSnapshotIdentifier}' \
  --output json
{
    "Status": "FAILED",
    "SnapshotId": "rds1-remediation-snapshot"
}

6. 自動修復の実行確認

EventBridge が finding を捕捉して SSM Automation を起動するはず。SSM Automation の実行履歴を確認する。

sleep 60

aws ssm describe-automation-executions \
  --filters Key=DocumentNamePrefix,Values=AWSSupport-ModifyRDSSnapshotPermission \
  --max-results 5 \
  --region ap-northeast-1 \
  --query 'AutomationExecutionMetadataList[].{Status:AutomationExecutionStatus,ExecutionStartTime:ExecutionStartTime,ExecutionId:AutomationExecutionId}' \
  --output json
[
    {
        "Status": "Success",
        "ExecutionStartTime": "<開始時刻>",
        "ExecutionId": "<実行 ID>"
    }
]

7. PASSED 復帰確認

7.1 スナップショットがプライベートに戻ったことを確認

aws rds describe-db-snapshot-attributes \
  --db-snapshot-identifier rds1-remediation-snapshot \
  --region ap-northeast-1 \
  --query 'DBSnapshotAttributesResult.DBSnapshotAttributes' \
  --output json
[
    {
        "AttributeName": "restore",
        "AttributeValues": []
    }
]

restore 属性が空になっていれば、自動修復によりプライベートに戻った状態。

7.2 Config / Security Hub finding 確認

RULE_NAME=$(aws configservice describe-config-rules \
  --query "ConfigRules[?contains(ConfigRuleName, 'rds-snapshots-public-prohibited')].ConfigRuleName" \
  --output text \
  --region ap-northeast-1)

aws configservice start-config-rules-evaluation \
  --config-rule-names $RULE_NAME \
  --region ap-northeast-1

sleep 60

aws securityhub get-findings \
  --filters '{"ComplianceSecurityControlId":[{"Comparison":"EQUALS","Value":"RDS.1"}],"ResourceId":[{"Comparison":"PREFIX","Value":"arn:aws:rds:ap-northeast-1:<アカウント ID>:snapshot:rds1-remediation-snapshot"}]}' \
  --region ap-northeast-1 \
  --query 'Findings[0].{Status:Compliance.Status,UpdatedAt:UpdatedAt}' \
  --output json
{
    "Status": "PASSED",
    "UpdatedAt": "<更新時刻>"
}

8. クリーンアップ

# RDS スナップショット削除
aws rds delete-db-snapshot \
  --db-snapshot-identifier rds1-remediation-snapshot \
  --region ap-northeast-1

# RDS インスタンス削除
aws rds delete-db-instance \
  --db-instance-identifier rds1-remediation-test \
  --skip-final-snapshot \
  --delete-automated-backups \
  --region ap-northeast-1

# EventBridge ルール削除(ターゲットも削除)
aws events remove-targets \
  --rule rds-1-auto-remediation \
  --ids ssm-automation-target \
  --region ap-northeast-1

aws events delete-rule \
  --name rds-1-auto-remediation \
  --region ap-northeast-1

# IAM ロール削除
aws iam delete-role-policy \
  --role-name rds-1-automation-role \
  --policy-name rds-snapshot-permission

aws iam delete-role \
  --role-name rds-1-automation-role

aws iam delete-role-policy \
  --role-name rds-1-eventbridge-role \
  --policy-name eventbridge-ssm-automation

aws iam delete-role \
  --role-name rds-1-eventbridge-role

参考

Amazonアソシエイトリンク