コンテンツにスキップ

CT.EC2.PV.8

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

コントロールの説明

VPC Block Public Access(VPC BPA)をアカウントレベルで強制し、IGW / Egress-only IGW 経由のインターネットアクセスをブロックする。

VPC BPA は、VPC / サブネットの IGW 経由のインターネットアクセスを一括でブロックするアカウントレベルの設定である。デフォルトでは無効(off)。

モードCLI の --internet-gateway-block-mode説明
無効(デフォルト)offVPC BPA 無効
インバウンドのみブロックblock-ingressインバウンドのインターネットトラフィックをブロック(NAT Gateway / Egress-only IGW 経由のアウトバウンドは許可)
双方向ブロックblock-bidirectionalIGW / Egress-only IGW 経由の全トラフィックをブロック

API レスポンスの InternetGatewayBlockMode フィールドが VPC BPA のモードを示す。

本コントロール(CT.EC2.PV.8)は Declarative Policy により、VPC BPA を block-bidirectional に強制し、除外(Exclusions)の作成も禁止する。

CT.EC2.PV.7(EBS Snapshot BPA)や CT.EC2.PV.11(Image BPA)と同じ Declarative Policy ベースのコントロールであり、以下の特性がある。

  • アカウントレベルの設定を直接強制する(SCP のように API コールをブロックするのではない)
  • 設定変更を試みると DeclarativePolicyViolation エラーになる
  • 無効化(デタッチ)すると元のアカウントレベル設定に復元される
VPC BPA はパブリック IP の付与や IGW 経由のインターネットアクセスが意図した設計である可能性もあり、実環境への投入時には影響評価が必要である。本コントロールは除外(Exclusions)も禁止するため、有効化すると全 VPC / サブネットのインターネットアクセスがブロックされる。

Security Hub CSPM との関係

VPC BPA に関連する Security Hub CSPM コントロール(HIGH):

コントロールタイトル
EC2.9EC2 インスタンスにパブリック IPv4 アドレスを持たせない
EC2.25EC2 起動テンプレートでパブリック IP を割り当てない
Autoscaling.5Auto Scaling 起動設定でパブリック IP を割り当てない
ECS.2ECS サービスにパブリック IP を自動割り当てしない
ECS.16ECS タスクセットにパブリック IP を自動割り当てしない
EMR.1EMR クラスタープライマリノードにパブリック IP を持たせない
RDS.46RDS DB インスタンスを IGW ルートがあるパブリックサブネットにデプロイしない
SageMaker.1SageMaker ノートブックインスタンスでダイレクトインターネットアクセスを無効にする

これらのコントロールは個別リソースの設定をチェックする。VPC BPA はネットワークレベルでインターネットアクセスをブロックするため、個別リソースの設定に関わらずパブリックアクセスを防止できるが、Security Hub の finding が変化するかは個別コントロールの検証で確認する。

検証環境

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

検証の流れ

    flowchart LR
    A[1. デフォルト状態の確認] --> B[2. VPC BPA 手動有効化]
    B --> C[3. 通信テスト<br>VPC BPA 有効/無効]
    C --> D[4. CT.EC2.PV.8 有効化]
    D --> E[5. 設定変更・除外<br>作成ブロック確認]
    D --> F[6. CloudTrail で確認]
    E & F --> G[7. CT.EC2.PV.8 無効化]
    G --> H[8. 復元確認]
    H --> I[9. クリーンアップ]
  

結果

  • デフォルトでは VPC BPA は無効(InternetGatewayBlockMode: off
  • 手動で VPC BPA を有効化(block-bidirectional)すると、IGW 経由のアウトバウンド通信がブロックされることを確認(SSM Run Command で curl が成功→VPC BPA 有効化後は結果が返らない)
  • VPC BPA が有効な状態では SSM エージェントの新規登録もできない
  • CT.EC2.PV.8 を有効化すると、VPC BPA が block-bidirectional に強制され、ManagedBy: declarative-policyExclusionsAllowed: not-allowed になる
  • CT.EC2.PV.8 有効時に VPC BPA の無効化を試みると DeclarativePolicyViolation でブロックされる
  • CT.EC2.PV.8 有効時にモード変更(block-ingress)を試みても同様にブロックされる
  • CT.EC2.PV.8 有効時に除外(Exclusion)の作成を試みても同様にブロックされる
  • 拒否イベントは CloudTrail に errorCode: Client.DeclarativePolicyViolation として記録される
  • CT.EC2.PV.8 を無効化すると、VPC BPA が元の状態(offManagedBy: account)に復元される

1. デフォルト状態の確認

VPC BPA の現在の状態を確認

aws ec2 describe-vpc-block-public-access-options \
  --region ap-northeast-1
{
    "VpcBlockPublicAccessOptions": {
        "AwsAccountId": "<アカウント ID>",
        "AwsRegion": "ap-northeast-1",
        "State": "default-state",
        "InternetGatewayBlockMode": "off",
        "Reason": "Default State",
        "ManagedBy": "account",
        "ExclusionsAllowed": "allowed"
    }
}

デフォルトでは VPC BPA は無効。InternetGatewayBlockMode が VPC BPA のモードを示し、off は無効を意味する。ManagedBy: account はアカウントレベルで管理されていることを示す。

2. VPC BPA 手動有効化

CT.EC2.PV.8 の有効化前に、手動で VPC BPA を有効化・無効化できることを確認する。

VPC BPA を bidirectional で有効化

aws ec2 modify-vpc-block-public-access-options \
  --internet-gateway-block-mode block-bidirectional \
  --region ap-northeast-1
{
    "VpcBlockPublicAccessOptions": {
        "State": "update-in-progress",
        "InternetGatewayBlockMode": "block-bidirectional",
        "Reason": "Customer Action",
        "ManagedBy": "account",
        "ExclusionsAllowed": "allowed"
    }
}

反映には約 2 分かかる。

有効化完了を確認

aws ec2 describe-vpc-block-public-access-options \
  --region ap-northeast-1
{
    "VpcBlockPublicAccessOptions": {
        "State": "update-complete",
        "InternetGatewayBlockMode": "block-bidirectional",
        "Reason": "Customer Action",
        "ManagedBy": "account",
        "ExclusionsAllowed": "allowed"
    }
}

VPC BPA を無効化して元に戻す

aws ec2 modify-vpc-block-public-access-options \
  --internet-gateway-block-mode off \
  --region ap-northeast-1
{
    "VpcBlockPublicAccessOptions": {
        "State": "update-in-progress",
        "InternetGatewayBlockMode": "off",
        "Reason": "Customer Action",
        "ManagedBy": "account",
        "ExclusionsAllowed": "allowed"
    }
}

反映完了まで待機し、State: update-complete を確認する。

aws ec2 describe-vpc-block-public-access-options \
  --region ap-northeast-1
{
    "VpcBlockPublicAccessOptions": {
        "State": "update-complete",
        "InternetGatewayBlockMode": "off",
        "Reason": "Customer Action",
        "ManagedBy": "account",
        "ExclusionsAllowed": "allowed"
    }
}

3. 通信テスト(VPC BPA 有効/無効)

VPC BPA の有効/無効でインターネットへのアウトバウンド通信がブロックされることを確認する。デフォルト VPC のパブリックサブネットに EC2 インスタンスを起動し、SSM Run Command で curl を実行する。

EC2 インスタンスの準備

SSM 用の IAM ロールとインスタンスプロファイルを作成し、EC2 インスタンスを起動する。

aws iam create-role \
  --role-name <SSM ロール名> \
  --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ec2.amazonaws.com"},"Action":"sts:AssumeRole"}]}'

(出力省略)

aws iam attach-role-policy \
  --role-name <SSM ロール名> \
  --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
(出力なし)
aws iam create-instance-profile \
  --instance-profile-name <インスタンスプロファイル名>

(出力省略)

aws iam add-role-to-instance-profile \
  --instance-profile-name <インスタンスプロファイル名> \
  --role-name <SSM ロール名>
(出力なし)
aws ec2 run-instances \
  --image-id <Amazon Linux 2023 AMI ID> \
  --instance-type t3.micro \
  --subnet-id <パブリックサブネット ID> \
  --associate-public-ip-address \
  --iam-instance-profile Name=<インスタンスプロファイル名> \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=vpc-bpa-test}]' \
  --query 'Instances[0].{InstanceId:InstanceId,State:State.Name}' \
  --region ap-northeast-1

SSM エージェントの登録を待ち、PingStatus: Online を確認する。

aws ssm describe-instance-information \
  --filters "Key=InstanceIds,Values=<インスタンス ID>" \
  --query 'InstanceInformationList[0].{InstanceId:InstanceId,PingStatus:PingStatus}' \
  --region ap-northeast-1
{
    "InstanceId": "<インスタンス ID>",
    "PingStatus": "Online"
}

VPC BPA 無効状態での通信テスト

aws ssm send-command \
  --instance-ids <インスタンス ID> \
  --document-name "AWS-RunShellScript" \
  --parameters 'commands=["curl -s -o /dev/null -w \"%{http_code}\" --connect-timeout 10 https://www.google.co.jp"]' \
  --query 'Command.{CommandId:CommandId}' \
  --region ap-northeast-1
aws ssm get-command-invocation \
  --command-id <コマンド ID> \
  --instance-id <インスタンス ID> \
  --query '{Status:Status,StandardOutputContent:StandardOutputContent}' \
  --region ap-northeast-1
{
    "Status": "Success",
    "StandardOutputContent": "301"
}

HTTP 301(リダイレクト)= HTTP ステータスコードが返ること自体が IGW 経由の通信が成功している証拠。

VPC BPA 有効化

aws ec2 modify-vpc-block-public-access-options \
  --internet-gateway-block-mode block-bidirectional \
  --region ap-northeast-1

反映完了(約 2 分)まで待機する。

VPC BPA 有効状態での通信テスト

aws ssm send-command \
  --instance-ids <インスタンス ID> \
  --document-name "AWS-RunShellScript" \
  --parameters 'commands=["curl -s -o /dev/null -w \"%{http_code}\" --connect-timeout 10 https://www.google.co.jp 2>&1 || echo TIMEOUT"]' \
  --query 'Command.{CommandId:CommandId}' \
  --region ap-northeast-1

SSM Run Command の結果が返らない(Status: Pending → 最終的に DeliveryTimedOut)。VPC BPA により IGW 経由の通信がブロックされ、SSM エージェントがコマンドを受信できないため。

VPC BPA が有効な状態では、SSM エージェントの新規登録もできない(IGW 経由の通信がブロックされるため)。VPC BPA 有効化前に SSM エージェントが登録済みであっても、Run Command の結果は返らない。ただし、これは SSM の通信が IGW 経由の場合に限る。SSM 用の VPC エンドポイント(com.amazonaws.<リージョン>.ssmssmmessagesec2messages)が設定されている環境では、通信は IGW を経由しないため VPC BPA の影響を受けない。

VPC BPA を無効化して元に戻す

aws ec2 modify-vpc-block-public-access-options \
  --internet-gateway-block-mode off \
  --region ap-northeast-1

反映完了まで待機する。

4. CT.EC2.PV.8 有効化

コントロールが未有効化であることを確認

aws controltower list-enabled-controls \
  --target-identifier <対象 OU ARN> \
  --query 'enabledControls[?contains(controlIdentifier, `acfp8qjz7eggnursu5pfw7q2w`)]' \
  --profile Master \
  --region ap-northeast-1
[]

コントロールを有効化

aws controltower enable-control \
  --control-identifier arn:aws:controlcatalog:::control/acfp8qjz7eggnursu5pfw7q2w \
  --target-identifier <対象 OU ARN> \
  --profile Master \
  --region ap-northeast-1
{
    "arn": "<有効化 ARN>",
    "operationIdentifier": "<オペレーション ID>"
}

有効化の完了を確認

aws controltower get-control-operation \
  --operation-identifier <オペレーション ID> \
  --query 'controlOperation.{operationType:operationType,status:status}' \
  --profile Master \
  --region ap-northeast-1
{
    "operationType": "ENABLE_CONTROL",
    "status": "SUCCEEDED"
}

VPC BPA が Declarative Policy により強制されていることを確認

aws ec2 describe-vpc-block-public-access-options \
  --region ap-northeast-1
{
    "VpcBlockPublicAccessOptions": {
        "State": "update-complete",
        "InternetGatewayBlockMode": "block-bidirectional",
        "Reason": "Organization Change",
        "ManagedBy": "declarative-policy",
        "ExclusionsAllowed": "not-allowed"
    }
}

手動有効化時との違い:

  • ManagedBy: accountdeclarative-policy
  • ExclusionsAllowed: allowednot-allowed(除外の作成が禁止。Master 側からも除外は作成できない。公式ドキュメント: “you cannot exclude VPCs or subnets from the effects of this control”)
  • Reason: Customer ActionOrganization Change

5. 設定変更・除外作成ブロック確認

VPC BPA の無効化を試みる → DeclarativePolicyViolation

aws ec2 modify-vpc-block-public-access-options \
  --internet-gateway-block-mode off \
  --region ap-northeast-1
An error occurred (DeclarativePolicyViolation) when calling the ModifyVpcBlockPublicAccessOptions operation: This functionality has been disabled by a Declarative Policy. Custom Message: This action is blocked by a declarative policy that is managed by AWS Control Tower. For details, contact the administrator for your organization.

Declarative Policy により設定変更がブロックされる。SCP の AccessDenied とは異なり、DeclarativePolicyViolation エラーが返される。

VPC BPA が変更されていないことを確認

aws ec2 describe-vpc-block-public-access-options \
  --region ap-northeast-1
{
    "VpcBlockPublicAccessOptions": {
        "State": "update-complete",
        "InternetGatewayBlockMode": "block-bidirectional",
        "Reason": "Organization Change",
        "ManagedBy": "declarative-policy",
        "ExclusionsAllowed": "not-allowed"
    }
}

モード変更(block-ingress)を試みる → DeclarativePolicyViolation

aws ec2 modify-vpc-block-public-access-options \
  --internet-gateway-block-mode block-ingress \
  --region ap-northeast-1
An error occurred (DeclarativePolicyViolation) when calling the ModifyVpcBlockPublicAccessOptions operation: ...

block-bidirectional から block-ingress への変更もブロックされる。

除外(Exclusion)の作成を試みる → DeclarativePolicyViolation

CT.EC2.PV.8 は ExclusionsAllowed: not-allowed を設定するため、除外の作成もブロックされる。

aws ec2 create-vpc-block-public-access-exclusion \
  --subnet-id <パブリックサブネット ID> \
  --internet-gateway-exclusion-mode allow-bidirectional \
  --region ap-northeast-1
An error occurred (DeclarativePolicyViolation) when calling the CreateVpcBlockPublicAccessExclusion operation: This functionality has been disabled by a Declarative Policy. Custom Message: This action is blocked by a declarative policy that is managed by AWS Control Tower. For details, contact the administrator for your organization.

6. CloudTrail で確認

CloudTrail で拒否イベントを確認

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=ModifyVpcBlockPublicAccessOptions \
  --start-time <検索開始時刻> \
  --end-time <検索終了時刻> \
  --region ap-northeast-1 \
  --query 'Events[].CloudTrailEvent' \
  --output text | jq 'select(.errorCode != null) | {eventName, errorCode, errorMessage}'
{
  "eventName": "ModifyVpcBlockPublicAccessOptions",
  "errorCode": "Client.DeclarativePolicyViolation",
  "errorMessage": "This functionality has been disabled by a Declarative Policy. Custom Message: This action is blocked by a declarative policy that is managed by AWS Control Tower. For details, contact the administrator for your organization."
}

SCP の AccessDenied とは異なり、Declarative Policy の拒否は Client.DeclarativePolicyViolation として記録される。errorMessage にも Declarative Policy による拒否であることが明記されている。

除外作成の拒否イベントも同様に記録される。

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=CreateVpcBlockPublicAccessExclusion \
  --start-time <検索開始時刻> \
  --end-time <検索終了時刻> \
  --region ap-northeast-1 \
  --query 'Events[].CloudTrailEvent' \
  --output text | jq 'select(.errorCode != null) | {eventName, errorCode, errorMessage}'
{
  "eventName": "CreateVpcBlockPublicAccessExclusion",
  "errorCode": "Client.DeclarativePolicyViolation",
  "errorMessage": "This functionality has been disabled by a Declarative Policy. Custom Message: This action is blocked by a declarative policy that is managed by AWS Control Tower. For details, contact the administrator for your organization."
}

CloudWatch Logs(Organization Trail)で確認

aws logs start-query \
  --log-group-name <Organization Trail ログループ名> \
  --start-time <検索開始時刻(UNIX)> \
  --end-time <検索終了時刻(UNIX)> \
  --query-string 'fields @timestamp, eventName, errorCode, errorMessage | filter eventName = "ModifyVpcBlockPublicAccessOptions" and errorCode != ""' \
  --profile Master \
  --region ap-northeast-1
{
    "queryId": "<クエリ ID>"
}
aws logs get-query-results \
  --query-id <クエリ ID> \
  --profile Master \
  --region ap-northeast-1
{
    "results": [
        [
            {"field": "@timestamp", "value": "<タイムスタンプ>"},
            {"field": "eventName", "value": "ModifyVpcBlockPublicAccessOptions"},
            {"field": "errorCode", "value": "Client.DeclarativePolicyViolation"},
            {"field": "errorMessage", "value": "This functionality has been disabled by a Declarative Policy. Custom Message: This action is blocked by a declarative policy that is managed by AWS Control Tower. For details, contact the administrator for your organization."}
        ]
    ],
    "status": "Complete"
}

7. CT.EC2.PV.8 無効化

aws controltower disable-control \
  --control-identifier arn:aws:controlcatalog:::control/acfp8qjz7eggnursu5pfw7q2w \
  --target-identifier <対象 OU ARN> \
  --profile Master \
  --region ap-northeast-1
{
    "operationIdentifier": "<オペレーション ID>"
}
aws controltower get-control-operation \
  --operation-identifier <オペレーション ID> \
  --query 'controlOperation.{operationType:operationType,status:status}' \
  --profile Master \
  --region ap-northeast-1
{
    "operationType": "DISABLE_CONTROL",
    "status": "SUCCEEDED"
}

8. 復元確認

VPC BPA が元の状態(off)に復元されていることを確認

aws ec2 describe-vpc-block-public-access-options \
  --region ap-northeast-1
{
    "VpcBlockPublicAccessOptions": {
        "State": "update-complete",
        "InternetGatewayBlockMode": "off",
        "Reason": "Organization Change",
        "ManagedBy": "account",
        "ExclusionsAllowed": "allowed"
    }
}

ManagedByaccount に戻り、InternetGatewayBlockModeoff に復元されている。CT.EC2.PV.7(EBS Snapshot BPA)と同様に、Declarative Policy のデタッチ時は元のアカウントレベル設定に復元される。

9. クリーンアップ

ステップ 3 で作成した EC2 インスタンスと IAM リソースを削除する。

aws ec2 terminate-instances \
  --instance-ids <インスタンス ID> \
  --region ap-northeast-1
aws iam remove-role-from-instance-profile \
  --instance-profile-name <インスタンスプロファイル名> \
  --role-name <SSM ロール名>
(出力なし)
aws iam delete-instance-profile \
  --instance-profile-name <インスタンスプロファイル名>
(出力なし)
aws iam detach-role-policy \
  --role-name <SSM ロール名> \
  --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
(出力なし)
aws iam delete-role \
  --role-name <SSM ロール名>
(出力なし)

Amazonアソシエイトリンク