はじめに
本記事は以下の前回記事の続きです。
前回はAWS ConfigをCloudFormationで有効化する際のハマりポイントとして「サービスリンクロール」と「循環依存」の2点を解説しました。
本記事ではSecurity Hub CSPMを活用するうえでどのConfigリソースを有効化すべきかを、用途別に3パターンのCloudFormationテンプレートとして整理します。
Security Hub CSPMとAWS Configの関係
Security Hub CSPMの一部のコントロールは、AWS Configのリソース記録をもとに評価を行います。
そのため監視したいリソースタイプをAWS Configで記録していないと、Security Hubのコントロールが正しく評価されません。
どのリソースタイプが必要かは準拠する標準によって異なります。
3パターンの概要
| パターン | 用途 | 対応標準 | リソース数 |
|---|---|---|---|
| A | 検証・PoC用(前回記事と同じ構成) | 独自選定 | 19種類 |
| B | 最小構成(まずこれだけ有効化したい) | CIS AWS Foundations Benchmark v1.4.0 | 6種類 |
| C | 全標準対応(本番運用推奨) | 全標準 | AllSupported |
パターンA:検証用テンプレート
前回記事で作成した構成です。CloudFront → ALB → EC2 → S3/RDS という一般的なWebアプリ構成の検証を想定した19リソースを対象にしています。
AWSTemplateFormatVersion: "2010-09-09"
Description: >
AWS Config baseline for Security Hub CSPM (same region). Creates DeliveryChannel/Recorder,
uses existing AWSServiceRoleForConfig (does NOT create ServiceLinkedRole).
Parameters:
ConfigBucketName:
Type: String
Description: "Globally unique S3 bucket name for AWS Config delivery (3-63 chars, lowercase letters, numbers, hyphens, dots)."
MinLength: 3
MaxLength: 63
AllowedPattern: "^[a-z0-9][a-z0-9.-]*[a-z0-9]$"
ConstraintDescription: "3〜63文字。小文字英数字・ハイフン・ドットのみ使用可。先頭・末尾は英数字。"
ConfigBucketPrefix:
Type: String
Default: aws-config
Description: "Prefix for AWS Config objects in the bucket. Do NOT include leading/trailing '/'."
AllowedPattern: "^[A-Za-z0-9][A-Za-z0-9._-]*$"
ConstraintDescription: "Use only letters/numbers/._- and do not start with '/'. Do not include '/'."
Resources:
ConfigBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref ConfigBucketName
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
VersioningConfiguration:
Status: Enabled
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
ConfigBucketPolicy:
Type: AWS::S3::BucketPolicy
DependsOn: ConfigBucket
Properties:
Bucket: !Ref ConfigBucket
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: AWSConfigBucketPermissionsCheck
Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:GetBucketAcl
Resource: !GetAtt ConfigBucket.Arn
- Sid: AWSConfigBucketDelivery
Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:PutObject
Resource: !Sub "${ConfigBucket.Arn}/${ConfigBucketPrefix}/AWSLogs/${AWS::AccountId}/Config/*"
Condition:
StringEquals:
s3:x-amz-acl: bucket-owner-full-control
ConfigurationRecorder:
Type: AWS::Config::ConfigurationRecorder
DependsOn:
- ConfigBucketPolicy
Properties:
Name: default
RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
RecordingGroup:
AllSupported: false
IncludeGlobalResourceTypes: false
ResourceTypes:
- AWS::CloudFront::Distribution
- AWS::ElasticLoadBalancingV2::LoadBalancer
- AWS::ElasticLoadBalancingV2::Listener
- AWS::ElasticLoadBalancingV2::TargetGroup
- AWS::EC2::Instance
- AWS::EC2::SecurityGroup
- AWS::EC2::NetworkInterface
- AWS::EC2::VPC
- AWS::EC2::Subnet
- AWS::EC2::RouteTable
- AWS::EC2::NetworkAcl
- AWS::EC2::InternetGateway
- AWS::EC2::NatGateway
- AWS::EC2::EIP
- AWS::EC2::Volume
- AWS::EC2::FlowLog
- AWS::S3::Bucket
- AWS::RDS::DBInstance
- AWS::RDS::DBSubnetGroup
DeliveryChannel:
Type: AWS::Config::DeliveryChannel
DependsOn:
- ConfigBucketPolicy
Properties:
Name: default
S3BucketName: !Ref ConfigBucket
S3KeyPrefix: !Ref ConfigBucketPrefix
Outputs:
ConfigBucketOut:
Value: !Ref ConfigBucket
DeliveryChannelOut:
Value: default
RecorderOut:
Value: default
RoleArnUsed:
Value: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
パターンB:最小構成(CIS AWS Foundations Benchmark v1.4.0)
セキュリティ基準として広く採用されている CIS AWS Foundations Benchmark v1.4.0 に対応するための最小構成です。
「まずこれだけは有効化したい」という場合にご活用ください。
CIS v1.4.0 で必要なリソースタイプは以下の通りです。
| AWSサービス | リソースタイプ |
|---|---|
| Amazon EC2 |
AWS::EC2::NetworkAcl, AWS::EC2::SecurityGroup
|
| AWS IAM |
AWS::IAM::Policy, AWS::IAM::User
|
| Amazon RDS | AWS::RDS::DBInstance |
| Amazon S3 | AWS::S3::Bucket |
IAMはグローバルリソースのため IncludeGlobalResourceTypes: true を設定しています。
AWSTemplateFormatVersion: "2010-09-09"
Description: >
AWS Config minimum configuration for CIS AWS Foundations Benchmark v1.4.0.
Parameters:
ConfigBucketName:
Type: String
Description: "Globally unique S3 bucket name for AWS Config delivery (3-63 chars, lowercase letters, numbers, hyphens, dots)."
MinLength: 3
MaxLength: 63
AllowedPattern: "^[a-z0-9][a-z0-9.-]*[a-z0-9]$"
ConstraintDescription: "3〜63文字。小文字英数字・ハイフン・ドットのみ使用可。先頭・末尾は英数字。"
ConfigBucketPrefix:
Type: String
Default: aws-config
Description: "Prefix for AWS Config objects in the bucket. Do NOT include leading/trailing '/'."
AllowedPattern: "^[A-Za-z0-9][A-Za-z0-9._-]*$"
ConstraintDescription: "Use only letters/numbers/._- and do not start with '/'. Do not include '/'."
Resources:
ConfigBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref ConfigBucketName
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
VersioningConfiguration:
Status: Enabled
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
ConfigBucketPolicy:
Type: AWS::S3::BucketPolicy
DependsOn: ConfigBucket
Properties:
Bucket: !Ref ConfigBucket
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: AWSConfigBucketPermissionsCheck
Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:GetBucketAcl
Resource: !GetAtt ConfigBucket.Arn
- Sid: AWSConfigBucketDelivery
Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:PutObject
Resource: !Sub "${ConfigBucket.Arn}/${ConfigBucketPrefix}/AWSLogs/${AWS::AccountId}/Config/*"
Condition:
StringEquals:
s3:x-amz-acl: bucket-owner-full-control
ConfigurationRecorder:
Type: AWS::Config::ConfigurationRecorder
DependsOn:
- ConfigBucketPolicy
Properties:
Name: default
RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
RecordingGroup:
AllSupported: false
IncludeGlobalResourceTypes: true # IAM(グローバルリソース)を含むため true
ResourceTypes:
# CIS AWS Foundations Benchmark v1.4.0 対応リソース
- AWS::EC2::NetworkAcl
- AWS::EC2::SecurityGroup
- AWS::IAM::Policy
- AWS::IAM::User
- AWS::RDS::DBInstance
- AWS::S3::Bucket
DeliveryChannel:
Type: AWS::Config::DeliveryChannel
DependsOn:
- ConfigBucketPolicy
Properties:
Name: default
S3BucketName: !Ref ConfigBucket
S3KeyPrefix: !Ref ConfigBucketPrefix
Outputs:
ConfigBucketOut:
Value: !Ref ConfigBucket
DeliveryChannelOut:
Value: default
RecorderOut:
Value: default
RoleArnUsed:
Value: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
パターンC:全標準対応(AllSupported: true)
※AllSupported: true を推奨します
Security Hubの全標準(FSBP・CIS・NIST・PCI DSS等)に対応するためには150種類以上のリソースタイプの記録が必要です。
個別に列挙するよりも AllSupported: true を使用することを強く推奨します。
理由は以下の通りです。
| 理由 | 説明 |
|---|---|
| 管理コストが低い | AWSが新しいリソースタイプを追加しても自動で対応される |
| 設定ミスのリスクがない | 必要なリソースタイプの記録漏れが発生しない |
| Security Hubとの親和性が高い | 将来追加されるコントロールにも自動対応できる |
注意:
AllSupported: trueにすると記録対象リソースが増えるためAWS Configのコストが増加します。
コスト試算は AWS Config 料金ページ を参照してください。
AWSTemplateFormatVersion: "2010-09-09"
Description: >
AWS Config full configuration for all Security Hub CSPM standards.
Uses AllSupported: true to cover all resource types automatically.
Parameters:
ConfigBucketName:
Type: String
Description: "Globally unique S3 bucket name for AWS Config delivery (3-63 chars, lowercase letters, numbers, hyphens, dots)."
MinLength: 3
MaxLength: 63
AllowedPattern: "^[a-z0-9][a-z0-9.-]*[a-z0-9]$"
ConstraintDescription: "3〜63文字。小文字英数字・ハイフン・ドットのみ使用可。先頭・末尾は英数字。"
ConfigBucketPrefix:
Type: String
Default: aws-config
Description: "Prefix for AWS Config objects in the bucket. Do NOT include leading/trailing '/'."
AllowedPattern: "^[A-Za-z0-9][A-Za-z0-9._-]*$"
ConstraintDescription: "Use only letters/numbers/._- and do not start with '/'. Do not include '/'."
Resources:
ConfigBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref ConfigBucketName
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
VersioningConfiguration:
Status: Enabled
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
ConfigBucketPolicy:
Type: AWS::S3::BucketPolicy
DependsOn: ConfigBucket
Properties:
Bucket: !Ref ConfigBucket
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: AWSConfigBucketPermissionsCheck
Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:GetBucketAcl
Resource: !GetAtt ConfigBucket.Arn
- Sid: AWSConfigBucketDelivery
Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:PutObject
Resource: !Sub "${ConfigBucket.Arn}/${ConfigBucketPrefix}/AWSLogs/${AWS::AccountId}/Config/*"
Condition:
StringEquals:
s3:x-amz-acl: bucket-owner-full-control
ConfigurationRecorder:
Type: AWS::Config::ConfigurationRecorder
DependsOn:
- ConfigBucketPolicy
Properties:
Name: default
RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
RecordingGroup:
AllSupported: true # 全リソースタイプを自動で記録
IncludeGlobalResourceTypes: true # IAM等のグローバルリソースも含む
DeliveryChannel:
Type: AWS::Config::DeliveryChannel
DependsOn:
- ConfigBucketPolicy
Properties:
Name: default
S3BucketName: !Ref ConfigBucket
S3KeyPrefix: !Ref ConfigBucketPrefix
Outputs:
ConfigBucketOut:
Value: !Ref ConfigBucket
DeliveryChannelOut:
Value: default
RecorderOut:
Value: default
RoleArnUsed:
Value: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
まとめ
| パターン | AllSupported | リソース数 | 対応標準 | 推奨シーン |
|---|---|---|---|---|
| A(検証用) | false | 19種類 | 独自選定 | PoC・学習目的 |
| B(最小構成) | false | 6種類 | CIS v1.4.0 | まず始めたい場合 |
| C(全標準対応) | true | 全リソース | 全標準 | 本番運用(推奨) |
本番環境ではパターンCの AllSupported: true を採用し、コストと監視範囲のバランスを取ることを推奨します。
パターンBはコスト最小化が必要な場合や、特定の標準のみ対応すれば良い場合に有効です。