🔎

cdk-nagに今更入門してみる

2024/05/07に公開

cdk-nag

cdkのコードに埋め込んでsynth時にルール準拠状況を確認してエラーを出してくれるやつ。
cdk-nagについては既に色々な記事が出てるのでそちらを見てください。

https://aws.amazon.com/jp/blogs/news/manage-application-security-and-compliance-with-the-aws-cloud-development-kit-and-cdk-nag/

インストール

'projen'を利用しているので、'.projenrc.ts'を以下のように追記して、'npx projen'

  deps: [
    // snip
    'cdk-nag',
  ],

導入時にエラーが出たので以下で対処した。
https://zenn.dev/gin_nazo/scraps/7a7c21e52eabad

CDKの修正

Aspectsから始まる行を追記する。
verbose: trueを入れると、該当の値なども出してくれる。

typescript
import { App, Aspects } from 'aws-cdk-lib';
import { AwsSolutionsChecks } from 'cdk-nag';
import { CloudTFdStack } from './lib/cloudtfd-stack';
import { awsConfig, globalConfig } from './lib/config/config';
import { GlobalStack } from './lib/global-stack';

const app = new App();
const ctfd = new CloudTFdStack(app, 'CloudTFdStack', {
  env: awsConfig,
  crossRegionReferences: true,
});

new GlobalStack(app, 'GlobalStack', {
  env: globalConfig,
  crossRegionReferences: true,
  contentsBucket: ctfd.contentsBucket,
  cloudfrontPublicKey: ctfd.cloudfrontPublicKey,
});

+ Aspects.of(app).add(new AwsSolutionsChecks({ verbose: true }));

app.synth();

cdk-nagの実行

npx cdk synthなどで実行する。
結果はcdk.out配下に保存される。

以下は自環境での実施なのでカウントとかは特に意味はない。参考までに。

指摘全文
# raiha @ raiha in ~/Documents/work/ExcessiveCloudTFd on git:main x [19:39:11] C:1
$ npx cdk synth
Bundling asset CloudTFdStack/ApplicationPatterns/CloudFrontKeyPair/CloudFrontKeyPairGenerator/Code/Stage...

  cdk.out/bundling-temp-6b95a4df4ae02107c7459da00ecfb6ebbbd00e149bd1f5e1645ed16072663480/index.js  3.1kb

⚡ Done in 9ms
[Error at /CloudTFdStack/Base/Vpc/Resource] 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.

[Warning at /CloudTFdStack/Base/SmtpSG/Resource] CdkNagValidationFailure: 'AwsSolutions-EC23' threw an error during validation. This is generally caused by a parameter referencing an intrinsic function. You can suppress the "CdkNagValidationFailure" to get rid of this error. For more details enable verbose logging.' The parameter resolved to to a non-primitive value "{"Fn::GetAtt":["BaseVpc4D0293C1","CidrBlock"]}", therefore the rule could not be validated.

[Warning at /CloudTFdStack/Base/EcrSG/Resource] CdkNagValidationFailure: 'AwsSolutions-EC23' threw an error during validation. This is generally caused by a parameter referencing an intrinsic function. You can suppress the "CdkNagValidationFailure" to get rid of this error. For more details enable verbose logging.' The parameter resolved to to a non-primitive value "{"Fn::GetAtt":["BaseVpc4D0293C1","CidrBlock"]}", therefore the rule could not be validated.

[Warning at /CloudTFdStack/Base/EcrDkrSG/Resource] CdkNagValidationFailure: 'AwsSolutions-EC23' threw an error during validation. This is generally caused by a parameter referencing an intrinsic function. You can suppress the "CdkNagValidationFailure" to get rid of this error. For more details enable verbose logging.' The parameter resolved to to a non-primitive value "{"Fn::GetAtt":["BaseVpc4D0293C1","CidrBlock"]}", therefore the rule could not be validated.

[Warning at /CloudTFdStack/Base/LogsSG/Resource] CdkNagValidationFailure: 'AwsSolutions-EC23' threw an error during validation. This is generally caused by a parameter referencing an intrinsic function. You can suppress the "CdkNagValidationFailure" to get rid of this error. For more details enable verbose logging.' The parameter resolved to to a non-primitive value "{"Fn::GetAtt":["BaseVpc4D0293C1","CidrBlock"]}", therefore the rule could not be validated.

[Warning at /CloudTFdStack/Base/SsmSG/Resource] CdkNagValidationFailure: 'AwsSolutions-EC23' threw an error during validation. This is generally caused by a parameter referencing an intrinsic function. You can suppress the "CdkNagValidationFailure" to get rid of this error. For more details enable verbose logging.' The parameter resolved to to a non-primitive value "{"Fn::GetAtt":["BaseVpc4D0293C1","CidrBlock"]}", therefore the rule could not be validated.

[Warning at /CloudTFdStack/Base/SsmMessageSG/Resource] CdkNagValidationFailure: 'AwsSolutions-EC23' threw an error during validation. This is generally caused by a parameter referencing an intrinsic function. You can suppress the "CdkNagValidationFailure" to get rid of this error. For more details enable verbose logging.' The parameter resolved to to a non-primitive value "{"Fn::GetAtt":["BaseVpc4D0293C1","CidrBlock"]}", therefore the rule could not be validated.

[Warning at /CloudTFdStack/Base/SecretsManagerSG/Resource] CdkNagValidationFailure: 'AwsSolutions-EC23' threw an error during validation. This is generally caused by a parameter referencing an intrinsic function. You can suppress the "CdkNagValidationFailure" to get rid of this error. For more details enable verbose logging.' The parameter resolved to to a non-primitive value "{"Fn::GetAtt":["BaseVpc4D0293C1","CidrBlock"]}", therefore the rule could not be validated.

[Error at /CloudTFdStack/Database/Db/Secret/Resource] AwsSolutions-SMG4: The secret does not have automatic rotation scheduled. AWS Secrets Manager can be configured to automatically rotate the secret for a secured service or database.

[Error at /CloudTFdStack/Database/Db/Resource] AwsSolutions-RDS6: The RDS Aurora MySQL/PostgresSQL cluster does not have IAM Database Authentication enabled. With IAM Database Authentication enabled, the system doesn't have to use a password when connecting to the MySQL/PostgreSQL database instances, instead it uses an authentication token.

[Error at /CloudTFdStack/Database/Db/Resource] AwsSolutions-RDS10: The RDS instance or Aurora DB cluster does not have deletion protection enabled. Enabling Deletion Protection at the cluster level for Amazon Aurora databases or instance level for non Aurora instances helps protect from accidental deletion.

[Error at /CloudTFdStack/Database/Db/Resource] AwsSolutions-RDS11: The RDS instance or Aurora DB cluster uses the default endpoint port. Port obfuscation (using a non default endpoint port) adds an additional layer of defense against non-targeted attacks (i.e. MySQL/Aurora port 3306, SQL Server port 1433, PostgreSQL port 5432, etc).

[Error at /CloudTFdStack/Database/Db/Resource] AwsSolutions-RDS14: The RDS Aurora MySQL cluster does not have Backtrack enabled. Backtrack helps order to rewind cluster tables to a specific time, without using backups.

[Error at /CloudTFdStack/Redis/RedisSecret/Resource] AwsSolutions-SMG4: The secret does not have automatic rotation scheduled. AWS Secrets Manager can be configured to automatically rotate the secret for a secured service or database.

[Error at /CloudTFdStack/Redis/Redis] AwsSolutions-AEC5: The ElastiCache cluster uses the default endpoint port. Port obfuscation (using a non default endpoint port) adds an additional layer of defense against non-targeted attacks (i.e. Redis port 6379 and Memcached port 11211).

[Error at /CloudTFdStack/Mail/SMTP/SmtpSecretAccessKey/Resource] AwsSolutions-SMG4: The secret does not have automatic rotation scheduled. AWS Secrets Manager can be configured to automatically rotate the secret for a secured service or database.

[Error at /CloudTFdStack/Mail/SMTP/SmtpCredentialsGenerator/ServiceRole/Resource] AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]: The IAM user, role, or group uses AWS managed policies. An AWS managed policy is a standalone policy that is created and administered by AWS. Currently, many AWS managed policies do not restrict resource scope. Replace AWS managed policies with system specific (customer) managed policies.This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Policy::<policy>' for AWS managed policies. Example: appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/foo'].

[Error at /CloudTFdStack/Mail/SMTP/SmtpCredentialsGenerator/Resource] AwsSolutions-L1: The non-container Lambda function is not configured to use the latest runtime version. Use the latest available runtime for the targeted language to avoid technical debt. Runtimes specific to a language or framework version are deprecated when the version reaches end of life. This rule only applies to non-container Lambda functions.

[Error at /CloudTFdStack/Mail/SMTP/SmtpSecretProvider/framework-onEvent/ServiceRole/Resource] AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]: The IAM user, role, or group uses AWS managed policies. An AWS managed policy is a standalone policy that is created and administered by AWS. Currently, many AWS managed policies do not restrict resource scope. Replace AWS managed policies with system specific (customer) managed policies.This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Policy::<policy>' for AWS managed policies. Example: appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/foo'].

[Error at /CloudTFdStack/Mail/SMTP/SmtpSecretProvider/framework-onEvent/ServiceRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::<MailSMTPSmtpCredentialsGenerator1DBB414C.Arn>:*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/Mail/SMTP/SmtpSecretProvider/framework-onEvent/Resource] AwsSolutions-L1: The non-container Lambda function is not configured to use the latest runtime version. Use the latest available runtime for the targeted language to avoid technical debt. Runtimes specific to a language or framework version are deprecated when the version reaches end of life. This rule only applies to non-container Lambda functions.

[Error at /CloudTFdStack/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/Resource] AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]: The IAM user, role, or group uses AWS managed policies. An AWS managed policy is a standalone policy that is created and administered by AWS. Currently, many AWS managed policies do not restrict resource scope. Replace AWS managed policies with system specific (customer) managed policies.This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Policy::<policy>' for AWS managed policies. Example: appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/foo'].

[Error at /CloudTFdStack/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/CTFdBucket/Resource] 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.

[Error at /CloudTFdStack/ApplicationPatterns/CtfdSecretKey/Resource] AwsSolutions-SMG4: The secret does not have automatic rotation scheduled. AWS Secrets Manager can be configured to automatically rotate the secret for a secured service or database.

[Error at /CloudTFdStack/ApplicationPatterns/CloudFrontKeyPair/CloudFrontKeyPairGenerator/ServiceRole/Resource] AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]: The IAM user, role, or group uses AWS managed policies. An AWS managed policy is a standalone policy that is created and administered by AWS. Currently, many AWS managed policies do not restrict resource scope. Replace AWS managed policies with system specific (customer) managed policies.This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Policy::<policy>' for AWS managed policies. Example: appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/foo'].

[Error at /CloudTFdStack/ApplicationPatterns/CloudFrontKeyPair/CloudFrontKeyPairGenerator/Resource] AwsSolutions-L1: The non-container Lambda function is not configured to use the latest runtime version. Use the latest available runtime for the targeted language to avoid technical debt. Runtimes specific to a language or framework version are deprecated when the version reaches end of life. This rule only applies to non-container Lambda functions.

[Error at /CloudTFdStack/ApplicationPatterns/CloudFrontKeyPair/CloudFrontKeyPairProvider/framework-onEvent/ServiceRole/Resource] AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]: The IAM user, role, or group uses AWS managed policies. An AWS managed policy is a standalone policy that is created and administered by AWS. Currently, many AWS managed policies do not restrict resource scope. Replace AWS managed policies with system specific (customer) managed policies.This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Policy::<policy>' for AWS managed policies. Example: appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/foo'].

[Error at /CloudTFdStack/ApplicationPatterns/CloudFrontKeyPair/CloudFrontKeyPairProvider/framework-onEvent/ServiceRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::<ApplicationPatternsCloudFrontKeyPairCloudFrontKeyPairGenerator8CA226A5.Arn>:*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/CloudFrontKeyPair/CloudFrontKeyPairProvider/framework-onEvent/Resource] AwsSolutions-L1: The non-container Lambda function is not configured to use the latest runtime version. Use the latest available runtime for the targeted language to avoid technical debt. Runtimes specific to a language or framework version are deprecated when the version reaches end of life. This rule only applies to non-container Lambda functions.

[Error at /CloudTFdStack/ApplicationPatterns/Cluster/Resource] AwsSolutions-ECS4: The ECS Cluster has CloudWatch Container Insights disabled. CloudWatch Container Insights allow operators to gain a better perspective on how the cluster’s applications and microservices are performing.

[Error at /CloudTFdStack/ApplicationPatterns/Service/LB/Resource] AwsSolutions-ELB2: The ELB does not have access logs enabled. Access logs allow operators to to analyze traffic patterns and identify and troubleshoot security issues.

[Error at /CloudTFdStack/ApplicationPatterns/Service/TaskDef/TaskRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Action::s3:GetObject*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/Service/TaskDef/TaskRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Action::s3:GetBucket*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/Service/TaskDef/TaskRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Action::s3:List*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/Service/TaskDef/TaskRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Action::s3:DeleteObject*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/Service/TaskDef/TaskRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Action::s3:Abort*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/Service/TaskDef/TaskRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::<ApplicationPatternsCTFdBucket6E193294.Arn>/*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/Service/TaskDef/Resource] AwsSolutions-ECS2: The ECS Task Definition includes a container definition that directly specifies environment variables. Use secrets to inject environment variables during container startup from AWS Systems Manager Parameter Store or Secrets Manager instead of directly specifying plaintext environment variables. Updates to direct environment variables require operators to change task definitions and perform new deployments.

[Error at /CloudTFdStack/ApplicationPatterns/Service/TaskDef/ExecutionRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/S3PrefixList/GetPrefixListId/CustomResourcePolicy/Resource] AwsSolutions-IAM5[Resource::*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/CloudfrontOriginPrefixList/GetPrefixListId/CustomResourcePolicy/Resource] AwsSolutions-IAM5[Resource::*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource] AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]: The IAM user, role, or group uses AWS managed policies. An AWS managed policy is a standalone policy that is created and administered by AWS. Currently, many AWS managed policies do not restrict resource scope. Replace AWS managed policies with system specific (customer) managed policies.This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Policy::<policy>' for AWS managed policies. Example: appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/foo'].

[Error at /CloudTFdStack/AWS679f53fac002430cb0da5b7982bd2287/Resource] AwsSolutions-L1: The non-container Lambda function is not configured to use the latest runtime version. Use the latest available runtime for the targeted language to avoid technical debt. Runtimes specific to a language or framework version are deprecated when the version reaches end of life. This rule only applies to non-container Lambda functions.

[Error at /CloudTFdStack/Monitor/Notice/Resource] AwsSolutions-SNS2: The SNS Topic does not have server-side encryption enabled. Server side encryption adds additional protection of sensitive data delivered as messages to subscribers.

[Error at /CloudTFdStack/Monitor/Notice/Resource] AwsSolutions-SNS3: The SNS Topic does not require publishers to use SSL. Without HTTPS (TLS), a network-based attacker can eavesdrop on network traffic or manipulate it, using an attack such as man-in-the-middle. Allow only encrypted connections over HTTPS (TLS) using the aws:SecureTransport condition and the 'sns: Publish' action in the topic policy to force publishers to use SSL. If SSE is already enabled then this control is auto enforced.

[Error at /CloudTFdStack/Monitor/Warn/Resource] AwsSolutions-SNS2: The SNS Topic does not have server-side encryption enabled. Server side encryption adds additional protection of sensitive data delivered as messages to subscribers.

[Error at /CloudTFdStack/Monitor/Warn/Resource] AwsSolutions-SNS3: The SNS Topic does not require publishers to use SSL. Without HTTPS (TLS), a network-based attacker can eavesdrop on network traffic or manipulate it, using an attack such as man-in-the-middle. Allow only encrypted connections over HTTPS (TLS) using the aws:SecureTransport condition and the 'sns: Publish' action in the topic policy to force publishers to use SSL. If SSE is already enabled then this control is auto enforced.

[Error at /CloudTFdStack/Monitor/Critical/Resource] AwsSolutions-SNS2: The SNS Topic does not have server-side encryption enabled. Server side encryption adds additional protection of sensitive data delivered as messages to subscribers.

[Error at /CloudTFdStack/Monitor/Critical/Resource] AwsSolutions-SNS3: The SNS Topic does not require publishers to use SSL. Without HTTPS (TLS), a network-based attacker can eavesdrop on network traffic or manipulate it, using an attack such as man-in-the-middle. Allow only encrypted connections over HTTPS (TLS) using the aws:SecureTransport condition and the 'sns: Publish' action in the topic policy to force publishers to use SSL. If SSE is already enabled then this control is auto enforced.

[Error at /GlobalStack/Cdn/LogBucket/Resource] 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.

[Warning at /GlobalStack/Cdn/CloudFront/Resource] AwsSolutions-CFR1: The CloudFront distribution may require Geo restrictions. Geo restriction may need to be enabled for the distribution in order to allow or deny a country in order to allow or restrict users in specific locations from accessing content.


Found errors
Rule ID カウント 意味
AwsSolutions-VPC7 VPCフローログの取得されていない
AwsSolutions-SMG4 4 シークレットのローテーションがスケジュールされていない
AwsSolutions-RDS6 1 RDSでIAM認証が有効ではない
AwsSolutions-RDS10 1 RDSの削除保護が有効ではない
AwsSolutions-RDS11 1 RDSがデフォルトポートを利用している
AwsSolutions-RDS14 1 RDS Auroraでバックトラックが有効ではない
AwsSolutions-AEC5 1 ElastiCacheがデフォルトポートを利用している
AwsSolutions-IAM4 7 IAMでAWSマネージドルールグループを利用している
AwsSolutions-IAM5 8 IAMエンティティにワイルドカードを利用している
AwsSolutions-L1 5 (コンテナでない)Lambdaが最新のランタイムでない
AwsSolutions-S1 2 S3のサーバアクセスログが有効ではない
AwsSolutions-ECS2 1 タスク定義の環境変数に直接に値が指定されている
AwsSolutions-ECS4 1 ECSのContainer Insightsが有効ではない
AwsSolutions-ELB2 1 ELBのアクセスログが有効ではない
AwsSolutions-SNS2 3 server-side encryptionが有効ではない
AwsSolutions-SNS3 3 SSLを無効ではない(TLSのみが有効にする)

対応

ここも自環境での話なので参考までに。

部分的な対応も含めて指摘に従う

Rule ID カウント 意味
AwsSolutions-RDS11 1 RDSがデフォルトポートを利用している
AwsSolutions-SMG4 4 シークレットのローテーションがスケジュールされていない
AwsSolutions-RDS14 1 RDS Auroraでバックトラックが有効ではない
AwsSolutions-AEC5 1 ElastiCacheがデフォルトポートを利用している
AwsSolutions-L1 5 (コンテナでない)Lambdaが最新のランタイムでない
AwsSolutions-SNS3 3 SSLを無効ではない(TLSのみが有効にする)
AwsSolutions-ECS4 1 ECSのContainer Insightsが有効ではない
  • デフォルトポートから変えるのは個人的にはSGとかでちゃんと守れてればいらないと思うけども、一回やっとけばいいのであれば対応しておくぐらいの気持ち。
  • RDSだけローテーションさせたけど、SecretはElastiCachedとかでも使ってて、そっちは無視した。
  • Auroraのバックトラックは指摘されて初めて機能を知ったのでよかった。
  • Lambdaが最新でないのは指摘としてどうなんだ?とは思うけど、利用できる最新のにあげた(この指摘はマイナーバージョンではなくメジャーバージョンを上げろと言っている気がする)
  • SNSはTLSじゃなかったら弾くようにenforeceSSLを入れた
  • Container Insightsは有効にした、rdsはServerlessがInsights未対応なため指摘されてない

指摘に対応しない

Rule ID カウント 意味
AwsSolutions-VPC7 VPCフローログの取得されていない
AwsSolutions-RDS10 1 RDSの削除保護が有効ではない
AwsSolutions-RDS6 1 RDSでIAM認証が有効ではない
AwsSolutions-IAM4 7 IAMでAWSマネージドルールグループを利用している
AwsSolutions-IAM5 8 IAMエンティティにワイルドカードを利用している
AwsSolutions-S1 2 S3のサーバアクセスログが有効ではない
AwsSolutions-ECS2 1 タスク定義の環境変数に直接に値が指定されている
AwsSolutions-ELB2 1 ELBのアクセスログが有効ではない
AwsSolutions-SNS2 3 server-side encryptionが有効ではない
  • VPCフローログは不要と判断
  • 削除保護入れるとCFnから消すのがめんどくさくなるので許容
  • IAM認証が使えるかどうかはWebサーバ次第で、今回はできない
  • 全部AWSLambdaBasicExecutionRoleだったので許容。この指摘はめっちゃいいと思う。
  • ワイルドカードの指摘は、正確には特定リソースのみに限っていて認識しているものなので許容(s3:Get*とかそういうやつ)
  • S3のアクセスログは不要と判断
  • タスク定義は必要なものはSecrets Managerを併用しているため問題なし
  • ELBのアクセスログは不要と判断
  • SNSのサーバサイド暗号化はAWSサービス間連携がめんどくなくので不要と判断

指摘をSuppressionする

以下2つを見比べながらやると理解が進む
https://github.com/cdklabs/cdk-nag
https://tech.dentsusoken.com/entry/introducing_cdk_nag

Stack全体で特定ポリシーに対する指摘をSuppression

AWSLambdaBasicExecutionRoleに対する指摘だったので、このポリシーでのAwsSolutions-IAM4をStack全体でSuppressionしたい場合

指摘は以下

[Error at /CloudTFdStack/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource] AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]: The IAM user, role, or group uses AWS managed policies. An AWS managed policy is a standalone policy that is created and administered by AWS. Currently, many AWS managed policies do not restrict resource scope. Replace AWS managed policies with system specific (customer) managed policies.This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Policy::<policy>' for AWS managed policies. Example: appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/foo'].

<AWS::Partition>を自分のAWSアカウントIDに書き換えたくなるけど、そのままappliesToに書けば良い
Stack全体なのでaddStackSuppressionsを使う

NagSuppressions.addStackSuppressions(
  this,
  [
    {
      id: 'AwsSolutions-IAM4',
      reason: 'AWSLambdaBasicExecutionRole is allowd',
      appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'],
    },
  ],
);

CDKが自動的に作成するリソースに対するSuppression

Error at以下に続くリソース名の複雑さから分かるように、CDKが作成しているリソースがある。この場合、CDKのコード上ではインスタンス化してないので、addResourceSuppressionsでは対応できない。(指摘そのものが不要ならaddStackSuppressionsでも良い)

指摘は以下

[Error at /CloudTFdStack/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

addResourceSuppressionsByPathを使うことでリソースのパス名で指定することができる。
できるのだが、このランダムになりそうな文字列をコードに入れることにすごい抵抗があるのでもっといい方法はないのだろうか?参考

NagSuppressions.addResourceSuppressionsByPath(
  this,
'/CloudTFdStack/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/DefaultPolicy/Resource',
  [{ id: 'AwsSolutions-IAM5', reason: 'Uncontrollable due to CDK-generated custom resource.' }],
);

ワイルドカードを使っているポリシーに対するSuppression

cdk-nagではポリシーに*が入っていれば'AwsSolutions-IAM5'で指摘されるようで、S3にgrantReadWrite()なんかを実施するとGet*List*などの個数分だけ指摘が入る。
そこで特定のワイルドカードを持つActionに対して、AwsSolutions-IAM5をSuppresionする。

指摘は以下(これが複数ある)

[Error at /CloudTFdStack/ApplicationPatterns/Service/TaskDef/TaskRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Action::s3:List*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

[Error at /CloudTFdStack/ApplicationPatterns/Service/TaskDef/TaskRole/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::<ApplicationPatternsCTFdBucket6E193294.Arn>/*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission. Metadata explaining the evidence (e.g. via supporting links) for wildcard permissions allows for transparency to operators. This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'Action::<action>' for policy actions and 'Resource::<resource>' for resources. Example: appliesTo: ['Action::s3:*'].

appliesToに複数Actionを設定することで、条件を絞ったSuppressionを作れる。
addResourceSuppressionsの第三引数(applyToChildren)をtrueにすることで、コンストラクタ配下も含めてSuprressionをかけることができる。L2コンストラクタならまぁいいけどもL3とかでやるとあらぬところにSuppressionかかりそうなので、生成されるものに自信がある時に使うといいと思う。
'Action::s3:*'とかでSuppressionできるのかと思ったけどできなかった。(正規表現を使えるので、できるのかもしれない)

NagSuppressions.addResourceSuppressions(
  this.loadBalancedFargateService.service.taskDefinition,
  [
    {
      id: 'AwsSolutions-IAM5',
      reason: 'Allow ReadWrite for a specific bucket.',
      appliesTo: [
        'Action::s3:Abort*',
        'Action::s3:DeleteObject*',
        'Action::s3:List*',
        'Action::s3:GetObject*',
        'Action::s3:GetBucket*',
        'Resource::<ApplicationPatternsCTFdBucket6E193294.Arn>/*',
      ],
    },
    { id: 'AwsSolutions-ECS2', reason: 'Not needed for this project.' },
  ],
  true,
);

終わりに

言うまでもなく後から対応すると大変なので、できるだけ早めに有効にしておいた方が良い

Discussion