ちょっと前に既存の AWS CDK プロジェクトに cdk-nag を導入してみようという話があって,導入前に個人的な検証環境に cdk-nag を導入して試してみた❗️cdk-nag は cfn_nag にインスパイアされていると README に書かれていて,AWS CDK プロジェクトでベストプラクティスに近付くような改善箇所を検出できる.
Infrastructure as Code, 3rd Edition
最近読んだ「Infrastructure as Code, 3rd Edition」では Chapter.17 Infrastructure Code Testing Strategy の「Offline Static Code Analysis(オフライン静的コード解析)」で以下のように cfn_nag が紹介されていた💡
Terraform’s HCL and CloudFormation templates, such as TFLint, CloudFormation Linter, cfn_nag, and Trivy.
セットアップ
AWS CDK プロジェクトに cdk-nag を組み込むのは簡単で npm install
コマンドでセットアップして,エントリーポイントになる bin/xxx.ts
に Aspects を使って実装すれば OK👌
const app = new cdk.App() Aspects.of(app).add(new AwsSolutionsChecks({ verbose: true }))
ルールセット
現時点では以下の5種類のルールセットがある.詳しくはドキュメント RULES.md
にまとまっている❗️そして今回は1番基本的な AWS Solutions (AwsSolutionsChecks
) を試す.
- AWS Solutions (
AwsSolutionsChecks
) - HIPAA Security (
HIPAASecurityChecks
) - NIST 800-53 rev 4 (
NIST80053R4Checks
) - NIST 800-53 rev 5 (
NIST80053R5Checks
) - PCI DSS 3.2.1 (
PCIDSS321Checks
)
動作確認
cdk-nag は cdk synth
を実行するタイミングで呼び出される👌
$ npx cdk synth
個人的な検証環境で検出されたエラーの一部を紹介する❗️
🚨 AwsSolutions-S10
AwsSolutions-S10 では Amazon S3 バケットで HTTPS (TLS) 経由の暗号化された接続のみを許可していないと検出される.
AwsSolutions-S10: The S3 Bucket or bucket policy does not require requests to use SSL. You can use HTTPS (TLS) to help prevent potential attackers from eavesdropping on or manipulating network traffic using person-in-the-middle or similar attacks. You should allow only encrypted connections over HTTPS (TLS) using the aws:SecureTransport condition on Amazon S3 bucket policies.
今回は aws_s3 の enforceSSL: true
を追加した👌
const bucket = new aws_s3.Bucket(this, 'xxxxx', { bucketName: 'xxxxx', removalPolicy: RemovalPolicy.RETAIN_ON_UPDATE_OR_DELETE, enforceSSL: true, })
🚨 AwsSolutions-COG1
AwsSolutions-COG1 では Amazon Cognito でパスワードポリシーが要件を満たしていないと検出される.
AwsSolutions-COG1: The Cognito user pool does not have a password policy that minimally specify a password length of at least 8 characters, as well as requiring uppercase, numeric, and special characters. Strong password policies increase system security by encouraging users to create reliable and secure passwords.
今回は aws_cognito の passwordPolicy
を追加した👌
const userPool = new aws_cognito.UserPool(this, 'UserPool', { userPoolName: 'sandbox', passwordPolicy: { minLength: 8, requireLowercase: true, requireUppercase: true, requireDigits: true, requireSymbols: true } })
🚨 AwsSolutions-COG3
AwsSolutions-COG3 では Amazon Cognito で Advanced Security Mode が有効化されていないと検出される.
AwsSolutions-COG3: The Cognito user pool does not have AdvancedSecurityMode set to ENFORCED. Advanced security features enable the system to detect and act upon malicious sign-in attempts.
cdk-nag では不要なルールを抑制することもできる.今回は以下のように抑制した.
NagSuppressions.addResourceSuppressions(userPool, [ { id: 'AwsSolutions-COG3', reason: 'Cognito Advanced Security Mode is not necessary in my sandbox environment.' }, ])
🚨 AwsSolutions-S1
AwsSolutions-S1 では Amazon S3 バケットでアクセスログが有効化されていないと検出される.
AwsSolutions-S1: The S3 Bucket has server access logs disabled. The bucket should have server access logging enabled to provide detailed records for the requests that are made to the bucket.
同じく以下のように抑制した.
NagSuppressions.addResourceSuppressions(bucket, [ { id: 'AwsSolutions-S1', reason: 'S3 Bucket access logs is not necessary in my sandbox environment.' }, ])
🚨 AwsSolutions-VPC7
AwsSolutions-VPC7 では Amazon VPC で VPC Flow Logs が有効化されていないと検出される.
AwsSolutions-VPC7: The VPC does not have an associated Flow Log. VPC Flow Logs capture network flow information for a VPC, subnet, or network interface and stores it in Amazon CloudWatch Logs. Flow log data can help customers troubleshoot network issues; for example, to diagnose why specific traffic is not reaching an instance, which might be a result of overly restrictive security group rules.
個人的な検証環境では VPC Flow Logs は必要なく,同じく抑制した.
NagSuppressions.addResourceSuppressions(vpc, [ { id: 'AwsSolutions-VPC7', reason: 'VPC Flow Logs is not necessary in my sandbox environment.' }, ])
GitHub Actions で実行する
プルリクエストを出したときに GitHub Actions で cdk-nag を実行して,エラーがあったらワークフローを止めることもできる👌シンプルに GitHub Actions ワークフローを実装すると以下のようになる.
name: cdk-nag on: pull_request: branches: [main] jobs: cdk-nag: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 cache: npm - name: Install dependencies run: npm ci - name: cdk synth run: npx cdk synth