$30 off During Our Annual Pro Sale. View Details »

セキュリティスキャンツール cdk-nag を使ってみた

Kinyo
September 08, 2022

セキュリティスキャンツール cdk-nag を使ってみた

AWSインフラをCDKでIaC化したらcdk-nagでセキュリティスキャンしたくない?(特にサプレスの方法)
https://tech.isid.co.jp/entry/introducing_cdk_nag

cdk-nagのAWS公式ブログ
https://aws.amazon.com/jp/blogs/news/manage-application-security-and-compliance-with-the-aws-cloud-development-kit-and-cdk-nag/

cdk-nag
https://github.com/cdklabs/cdk-nag

JAWS-UG CDK支部 #3
https://jawsug-cdk.connpass.com/event/256768/

Kinyo

September 08, 2022
Tweet

Other Decks in Programming

Transcript

  1. ηΩϡϦςΟεΩϟϯπʔϧ cdk-nagΛ࢖ͬͯΈͨ 2022/9/7 JAWS-UG CDKࢧ෦ #3

  2. Kinyo
 
 
 גࣜձࣾి௨ࠃࡍ৘ใαʔϏεʢISIDʣ
 ηΩϡϦςΟΤϯδχΞ
 ։ൃ΋গ͠
 
 CDKྺ ൒೥ʢv2͔Βʣ
 CloudFormationະܦݧ


    
 ຊ೔ͷLT಺༰͸ϒϩάʹ΋ॻ͍ͯ͋Γ·͢👉
 ʮAWSΠϯϑϥΛCDKͰIaCԽͨ͠Βcdk-nagͰηΩϡϦςΟεΩϟϯͨ͠ ͘ͳ͍ʁʢಛʹαϓϨεͷํ๏ʣʯ
 https://tech.isid.co.jp/entry/introducing_cdk_nag ࣗݾ঺հ
  3. IaCΛ࢝ΊΔલ ίʔυʹΠϯϑϥͷ؅ཧΛ೚ͤͯେৎ෉ʁ 😟

  4. CDKΛ࢖͍࢝Ίͨޙ IaC࠷ߴ & CDK࠷ߴʂ खͰϦιʔεΛ৮ΔͳΜͯා͗͢Δʂ 😌

  5. ୹͍هड़ͰϦιʔεΛ࡞ΕΔɻૉ੖Β͍͠ɻ new s3.Bucket(this, "MyGrapefruitBucket"); ͔͜͠͠ͷίʔυͰσϓϩΠ͞ΕΔS3όέοτ͸ɾɾɾ

  6. ϒϩοΫύϒϦοΫΞΫηε͕Φϑʂ σϑΥϧτͷ҉߸Խ͕ແޮʂ TLS௨৴ʹ੍ݶ͞Ε͍ͯͳ͍ʂ

  7. new s3.Bucket(this, "MyGrapefruitBucket", { blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, encryption: s3.BucketEncryption.S3_MANAGED, enforceSSL: true,

    }); CDKͳΒɺରԠ͸؆୯ ͔͠͠ɺ͍ͣΕ΋ΦϓγϣφϧͳϓϩύςΟ 👉 ઃఆͷଘࡏʹؾ෇͔ͣʹσϓϩΠͯ͠͠·͏͔΋
  8. ؆୯ʹॻ͚ΔΏ͑ʹ ҆શͳઃఆʹͳ͍ͬͯͳ͍͔΋ɾɾɾ ࠶ͼෆ҆ʹɾɾɾ 😟

  9. cdk-nag https://docs.aws.amazon.com/cdk/v2/guide/apps.html#lifecycle ͜͜ͰίϯετϥΫτΛνΣοΫ 👉 ϧʔϧͷҧ൓͕͋ΔͱσϓϩΠͰ͖ͳ͍ ʹCI/CDʹ૊ΈࠐΈ΍͍͢ʂ CDKίʔυ͕ϕετϓϥΫςΟεʹԊ͍ͬͯΔ͔νΣοΫ

  10. ಋೖํ๏ import * as cdk from "aws-cdk-lib"; import { AwsSolutionsChecks

    } from "cdk-nag"; import { CdkBranchStack } from “../lib/cdk-branch-stack"; const app = new cdk.App(); new CdkBranchStack(app, "CdkBranchStack", {}); cdk.Aspects.of(app).add(new AwsSolutionsChecks({ verbose: true })); ࢖͍͍ͨϧʔϧύοΫΛΠϯϙʔτʢσϑΥϧτͰ5ͭ༻ҙ͞Ε͍ͯΔʣ npm install cdk-nag εςοϓ1 εςοϓ2 ΞϓϦέʔγϣϯʹద༻
  11. ࢖͍ํ % cdk synth [Error at /CdkBranchStack/MyGrapefruitBucket/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 /CdkBranchStack/MyGrapefruitBucket/Resource] AwsSolutions-S2: The S3 Bucket does not have public access restricted and blocked. The bucket should have public access restricted and blocked to prevent unauthorized access. [Error at /CdkBranchStack/MyGrapefruitBucket/Resource] AwsSolutions-S3: The S3 Bucket does not default encryption enabled. The bucket should minimally have SSE enabled to help protect data-at-rest. [Error at /CdkBranchStack/MyGrapefruitBucket/Resource] 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. Found errors ελοΫ໊ ϦιʔεID ϧʔϧID cdk synth ͓Αͼ cdk deploy ͰεΩϟϯ͕૸Δ
  12. αϓϨε ݕग़͞Εͨ໰୊ʹରͯ͠ɺ ʮ͜Ε͸େৎ෉ͩΑʯͱڭ͑ͯ͋͛Δ͜ͱ ηΩϡϦςΟεΩϟϯͰආ͚ͯ͸௨Εͳ͍΋ͷ

  13. ʮաෆ଍ͷͳ͍αϓϨεʯ͕େ੾ αϓϨε͕ෆ଍͍ͯ͠Δͱɾɾɾ
 ରԠ༧ఆͷͳ͍Ξϥʔτ͕͍ͭ·Ͱ΋࢒Δ
 ͦͷ͏ͪΞϥʔτΛݟͳ͘ͳΔ
 → ✅ cdk-nagͰ͸Ξϥʔτ͕࢒͍ͬͯΔͱσϓϩΠͰ͖ͳ͍ͷͰɺ
 ໰୊ʹ͸ͳΒͳ͍ αϓϨε͕ա৒ͩͱɾɾɾ
 কདྷతʹ࡞ΔϦιʔεͰɺग़ͯ΄͍͠Ξϥʔτ͕ग़ͳ͘ͳΔ


    જࡏతͳ໰୊ʹؾ෇͔ͣʹσϓϩΠͯ͠͠·͏
 → ⚠ cdk-nagͰ͸ϦιʔεΛࢦఆͯ͠αϓϨε͢ΔͷͰى͜Γʹ͍͕͘ɺ
 ؾΛ෇͚ΔϙΠϯτ΋͋Δ
  14. جຊతͳαϓϨε import * as s3 from "aws-cdk-lib/aws-s3"; import { NagSuppressions

    } from "cdk-nag"; export class CdkBranchStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const myBucket = new s3.Bucket(this, "MyGrapefruitBucket", {}); NagSuppressions.addResourceSuppressions(myBucket, [ { id: "AwsSolutions-S1", reason: "άϨʔϓϑϧʔπΛ֨ೲ͢ΔόέοτͷͨΊɺϩάग़ྗෆཁ" }, ]); } } NagSuppressionsΛΠϯϙʔτ αϓϨεର৅ͷϦιʔε αϓϨεର৅ͷϧʔϧID αϓϨεཧ༝ʢ10จࣈҎ্ඞਢʣ NagSuppressions.addResourceSuppressions Λར༻
  15. ࡉཻ͔͍౓ͷαϓϨε const myIamPolicy = new iam.ManagedPolicy(this, "MyStrictIAMPolicy", { statements: [

    new iam.PolicyStatement({ resources: [myBucket.bucketArn, `${myBucket.bucketArn}/*`], actions: ["s3:Get*", "s3:ListBucket"], effect: iam.Effect.ALLOW, }), ], }); NagSuppressions.addResourceSuppressions(myIamPolicy, [ { id: "AwsSolutions-IAM5", reason: "όέοτͷશΦϒδΣΫτ΁ͷGetΞΫγϣϯΛڐՄ͢Δඞཁ͕͋Δ", appliesTo: ["Action::s3:Get*"], }, ]); IAMϦιʔεʹର͠ɺ ಛఆͷAction, Resource, PolicyͷΈΛαϓϨε ৄ͘͠͸ϒϩάͰʂ
  16. ࢠϦιʔεͷαϓϨε const myFunction = new lambdaNodejs.NodejsFunction(this, "ServeCoffeeFunction", { entry: "functions/serve-coffee-function.ts",

    }); NagSuppressions.addResourceSuppressions( myFunction, [ { id: "AwsSolutions-IAM4", reason: “AWSLambdaBasicExecutionRole͸࢖༻ͯ͠໰୊ͳ͍", appliesTo: ["Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/ AWSLambdaBasicExecutionRole"], }, ], true ); ໌ࣔతʹ࡞੒ͨ͠ϦιʔεͰ͸ͳ͘ɺͦͷࢠϦιʔεͷΞϥʔτΛαϓϨε ʢ͜͜Ͱ͸Lambdaؔ਺ͷ࣮ߦϩʔϧʣ addResourceSuppressions ͷୈ3Ҿ਺ applyToChildren? ʹ true Λ౉͢ ৄ͘͠͸ϒϩάͰʂ
  17. CDK͕উखʹ࡞ΔϦιʔεͷαϓϨε const myFunction = new lambdaNodejs.NodejsFunction(this, "ServeCoffeeFunction", { logRetention: logs.RetentionDays.SIX_MONTHS,

    entry: "functions/serve-coffee-function.ts", }); NagSuppressions.addResourceSuppressionsByPath( this, "/CdkBranchStack/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/Resource", [ { id: "AwsSolutions-IAM4", reason: "CDK؅ཧͷϦιʔε", appliesTo: [“Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/ AWSLambdaBasicExecutionRole"], }, ] ); NagSupprssions.addResourceSuppressionsByPath Λར༻ ৄ͘͠͸ϒϩάͰʂ
  18. cdk-nagΛ࢖͍࢝Ίͨޙ Ϧιʔεͷઃఆʹ ߟྀ࿙Ε͕ͳ͍͜ͱʹࣗ৴Λ࣋ͯΔ 😌

  19. CloudFormation͕ ϚϧνόΠτจࣈΛѻ͑ͳ͍໰୊ ͓·͚

  20. NagSuppressions.addResourceSuppressions(myBucket, [ { id: "AwsSolutions-S1", reason: "άϨʔϓϑϧʔπΛอ؅͢ΔόέοτͷͨΊɺϩάग़ྗ͸ෆཁ" }, ]); "Metadata":

    { "aws:cdk:path": "CdkBranchStack/MyGrapefruitBucket/Resource", "cdk_nag": { "rules_to_suppress": [ { "id": "AwsSolutions-S1", "reason": "άϨʔϓϑϧʔπΛอ؅͢ΔόέοτͷͨΊɺϩάग़ྗ͸ෆཁ" } ] } } CfnςϯϓϨʔτ cdk deploy cdk diff Resources [~] AWS::S3::Bucket MyGrapefruitBucket MyGrapefruitBucket489DEE06 └─ [~] Metadata └─ [~] .cdk_nag: └─ [~] .rules_to_suppress: └─ @@ -1,6 +1,6 @@ [ ] [ [ ] { [ ] "id": "AwsSolutions-S1", [-] "reason": "????????????????????????????" [+] "reason": "άϨʔϓϑϧʔπΛอ؅͢ΔόέοτͷͨΊɺϩάग़ྗ͸ෆཁ" [ ] } [ ] ]
  21. "Metadata": { "aws:cdk:path": "CdkBranchStack/MyGrapefruitBucket/Resource", "cdk_nag": { "rules_to_suppress": [ { "reason":

    "44Kw44Os44O844OX44OV44Or44O844OE44KS5L+d566h44GZ44KL44OQ44Kx44OD44OI 44Gu44Gf44KB44CB44Ot44Kw5Ye65Yqb44Gv5LiN6KaB", "id": "AwsSolutions-S1", "is_reason_encoded": true } ] } } Stack CdkBranchStack There were no differences CfnςϯϓϨʔτ cdk deploy cdk diff मਖ਼͢ΔPR͕ແࣄϚʔδ͞Ε·ͨ͠🎉(v2.18.0~) NagSuppressions.addResourceSuppressions(myBucket, [ { id: "AwsSolutions-S1", reason: "άϨʔϓϑϧʔπΛอ؅͢ΔόέοτͷͨΊɺϩάग़ྗ͸ෆཁ" }, ]); αϓϨεཧ༝ʹϚϧνόΠτจࣈ͕
 ؚ·Ε͍ͯΕ͹Base64Τϯίʔυ