アカウントレベルの S3 パブリックアクセスブロックを AWS CDK で設定したみた

アカウントレベルの S3 パブリックアクセスブロックを AWS CDK で設定したみた

Clock Icon2025.02.03

こんにちは、製造ビジネステクノロジー部の若槻です。

Amazon S3 のパブリックアクセスブロックは、アカウントレベルで設定することができます。アカウントレベルで設定することで、アカウント内の全ての S3 バケットに対してパブリックアクセスブロックを有効化することができます。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/configuring-block-public-access-account.html

今回は、アカウントレベルの S3 パブリックアクセスブロックを AWS CDK で設定したみました。

やってみた

設定前

上記のパブリックブロックアクセス設定のうちいずれかが無効になっている場合は、Security Hub で以下のコントロールが検出されます。

[S3.1] 2.1.5.1 S3 Block Public Access setting should be enabled

https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/s3-controls.html#s3-1

設定の有効化

アカウントレベルの S3 パブリックアクセスブロックは CloudFormation に対応していません。そこで次のように S3Control の API を利用してカスタムリソースを作成します。

lib/constructs/s3-account-public-access-block/index.ts
import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as cr from 'aws-cdk-lib/custom-resources';
import { Construct } from 'constructs';

export class S3AccountPublicAccessBlockConstruct extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const accountId = cdk.Stack.of(this).account;

    // アカウントレベルでの S3 パブリックアクセスブロックを有効化
    new cr.AwsCustomResource(this, 'S3AccountPublicAccessBlock', {
      onCreate: {
        service: 'S3Control',
        action: 'putPublicAccessBlock',
        parameters: {
          AccountId: accountId,
          PublicAccessBlockConfiguration: {
            BlockPublicAcls: true,
            BlockPublicPolicy: true,
            IgnorePublicAcls: true,
            RestrictPublicBuckets: true,
          },
        },
        physicalResourceId: cr.PhysicalResourceId.of(
          'S3AccountPublicAccessBlock'
        ),
      },
      onDelete: {
        service: 'S3Control',
        action: 'deletePublicAccessBlock',
        parameters: {
          AccountId: accountId,
        },
      },
      policy: cr.AwsCustomResourcePolicy.fromStatements([
        new iam.PolicyStatement({
          effect: iam.Effect.ALLOW,
          actions: [
            's3:PutAccountPublicAccessBlock',
            's3:DeleteAccountPublicAccessBlock',
          ],
          resources: ['*'],
        }),
      ]),
    });
  }
}

上記のカスタムリソースをデプロイして onCreate を実行しパブリックアクセスブロックを有効化します。

マネジメントコンソールから S3 のアカウント設定にアクセスすると、パブリックアクセスブロックが有効になっていることが確認できました。

設定の無効化

下記のようにカスタムリソースを削除して再度デプロイを行います。

diff --git a/lib/security-stack.ts b/lib/security-stack.ts
index a7bddea..6a1835a 100644
--- a/lib/security-stack.ts
+++ b/lib/security-stack.ts
@@ -91,9 +91,6 @@ export class SecurityStack extends cdk.Stack {

-    // S3 アカウントパブリックアクセスブロックを有効化
-    new S3AccountPublicAccessBlockConstruct(this, "S3AccountPublicAccessBlock");
-

パブリックアクセスブロックを無効化することができました。

備考

AccountId の指定は必須

スタックの env プロパティで AWS アカウント ID を指定している場合でも、putPublicAccessBlock および putPublicAccessBlock アクションでは AccountId パラメーターの指定が必須となります。未指定の場合はデプロイ時に次のようなエラーとなるので注意しましょう。

Security |   1 | 8:51:59 PM | CREATE_FAILED        | Custom::AWS                 | S3AccountPublicAccessBlock/S3AccountPublicAccessBlock/Resource/Default (S3AccountPublicAccessBlock3EE41F53) Received response status [FAILED] from custom resource. Message returned: AccountId is required but not set (RequestId: 59a80166-f3c5-47c1-a22e-9c7ade01853f)

パブリックアクセスブロックが既に有効の場合でも、有効化操作は成功する

一部のセキュリティ系の機能ではすでに設定が有効化されている状態で有効化操作を行った場合にエラーになるものがあります。

パブリックアクセスブロックに関しては既に有効化されている場合でも、有効化操作は成功するので留意しましょう。

おわりに

アカウントレベルの S3 パブリックアクセスブロックを AWS CDK で設定したみました。

Security Hub 対応の一環で設定を行うことは多いと思うので、参考にしていただければ幸いです。

以上

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.