From 42767d7b36dc50d969d21e1960e1525ef63c6874 Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Wed, 28 Aug 2024 10:15:10 -0700 Subject: [PATCH] fix(waf): updating cdn waf --- .../braze-content-proxy/src/main.ts | 15 ++++++++--- infrastructure/client-api/src/main.ts | 27 +++++++++---------- .../src/pocket/PocketALBApplication.ts | 21 ++------------- .../PocketALBApplication.spec.ts.snap | 9 ++----- 4 files changed, 28 insertions(+), 44 deletions(-) diff --git a/infrastructure/braze-content-proxy/src/main.ts b/infrastructure/braze-content-proxy/src/main.ts index 1cecc7606..63ac9beab 100644 --- a/infrastructure/braze-content-proxy/src/main.ts +++ b/infrastructure/braze-content-proxy/src/main.ts @@ -74,7 +74,7 @@ class BrazeContentProxy extends TerraformStack { const allowListIPs = new wafv2IpSet.Wafv2IpSet(this, 'AllowlistIPs', { name: `${config.name}-${config.environment}-AllowList`, ipAddressVersion: 'IPV4', - scope: 'REGIONAL', + scope: 'CLOUDFRONT', tags: config.tags, addresses: brazeIPList, }); @@ -95,11 +95,20 @@ class BrazeContentProxy extends TerraformStack { }, }; + // When we are ready to block, make the default action block and remove this. const blockAllIps = { name: `${config.name}-${config.environment}-ipBlockAll`, priority: 2, action: { count: {} }, //doing a count before we do a block. - statement: {}, + statement: { + not_statement: { + statement: { + ip_set_reference_statement: { + arn: allowListIPs.arn, + }, + }, + }, + }, visibilityConfig: { cloudwatchMetricsEnabled: true, metricName: `${config.name}-${config.environment}-ipBlockAll`, @@ -110,7 +119,7 @@ class BrazeContentProxy extends TerraformStack { return new wafv2WebAcl.Wafv2WebAcl(this, `${config.name}-waf`, { description: `Waf for ${config.name} ${config.environment} environment`, name: `${config.name}-waf-${config.environment}`, - scope: 'REGIONAL', + scope: 'CLOUDFRONT', defaultAction: { allow: {} }, visibilityConfig: { cloudwatchMetricsEnabled: true, diff --git a/infrastructure/client-api/src/main.ts b/infrastructure/client-api/src/main.ts index c3bdd66a0..a2a2c7048 100644 --- a/infrastructure/client-api/src/main.ts +++ b/infrastructure/client-api/src/main.ts @@ -8,6 +8,8 @@ import { dataAwsKmsAlias, dataAwsSnsTopic, dataAwsSubnets, + wafv2IpSet, + wafv2WebAcl, } from '@cdktf/provider-aws'; import { provider as localProvider } from '@cdktf/provider-local'; import { provider as nullProvider } from '@cdktf/provider-null'; @@ -22,11 +24,6 @@ import { App, S3Backend, TerraformStack } from 'cdktf'; import { Construct } from 'constructs'; import fs from 'fs'; -import { Wafv2IpSet } from '@cdktf/provider-aws/lib/wafv2-ip-set'; -import { - Wafv2WebAclRule, - Wafv2WebAcl, -} from '@cdktf/provider-aws/lib/wafv2-web-acl'; class ClientAPI extends TerraformStack { constructor(scope: Construct, name: string) { super(scope, name); @@ -102,15 +99,15 @@ class ClientAPI extends TerraformStack { const ipList = config.environment === 'Prod' ? ipListProd : ipListDev; - const allowListIPs = new Wafv2IpSet(this, 'AllowlistIPs', { + const allowListIPs = new wafv2IpSet.Wafv2IpSet(this, 'AllowlistIPs', { name: `${config.name}-${config.environment}-AllowList`, ipAddressVersion: 'IPV4', - scope: 'REGIONAL', + scope: 'CLOUDFRONT', tags: config.tags, addresses: ipList, }); - const ipAllowListRule = { + const ipAllowListRule = { name: `${config.name}-${config.environment}-ipAllowList`, priority: 1, action: { allow: {} }, @@ -126,8 +123,8 @@ class ClientAPI extends TerraformStack { }, }; - const regionalRateLimitRule = { - name: `${config.name}-${config.environment}-RegionalRateLimit`, + const cloudfrontRateLimitRule = { + name: `${config.name}-${config.environment}-CloudfrontRateLimit`, priority: 2, action: { count: {} }, statement: { @@ -147,22 +144,22 @@ class ClientAPI extends TerraformStack { }, visibilityConfig: { cloudwatchMetricsEnabled: true, - metricName: `${config.name}-${config.environment}-RegionalRateLimit`, + metricName: `${config.name}-${config.environment}-CloudfrontRateLimit`, sampledRequestsEnabled: true, }, }; - return new Wafv2WebAcl(this, `${config.name}-waf`, { + return new wafv2WebAcl.Wafv2WebAcl(this, `${config.name}-waf`, { description: `Waf for client-api-proxy ${config.environment} environment`, name: `${config.name}-waf-${config.environment}`, - scope: 'REGIONAL', + scope: 'CLOUDFRONT', defaultAction: { allow: {} }, visibilityConfig: { cloudwatchMetricsEnabled: true, metricName: `${config.name}-waf-${config.environment}`, sampledRequestsEnabled: true, }, - rule: [ipAllowListRule, regionalRateLimitRule], + rule: [ipAllowListRule, cloudfrontRateLimitRule], }); } @@ -192,7 +189,7 @@ class ClientAPI extends TerraformStack { secretsManagerKmsAlias: dataAwsKmsAlias.DataAwsKmsAlias; snsTopic: dataAwsSnsTopic.DataAwsSnsTopic; cache: string; - wafAcl: Wafv2WebAcl; + wafAcl: wafv2WebAcl.Wafv2WebAcl; }): PocketALBApplication { const { region, caller, secretsManagerKmsAlias, cache, snsTopic, wafAcl } = dependencies; diff --git a/packages/terraform-modules/src/pocket/PocketALBApplication.ts b/packages/terraform-modules/src/pocket/PocketALBApplication.ts index 61200a3ee..837678058 100644 --- a/packages/terraform-modules/src/pocket/PocketALBApplication.ts +++ b/packages/terraform-modules/src/pocket/PocketALBApplication.ts @@ -255,11 +255,7 @@ export class PocketALBApplication extends Construct { this.alb = alb; if (config.cdn) { - const cdn = this.createCDN(albRecord); - // If we have a CDN, add the WAF to the CDN - if (config.wafConfig) { - this.createWAFCDN(cdn, config.wafConfig.aclArn); - } + this.createCDN(albRecord); } // If we don't have a CDN add the WAF to the ALB @@ -407,20 +403,6 @@ export class PocketALBApplication extends Construct { ); } - private createWAFCDN( - cdn: cloudfrontDistribution.CloudfrontDistribution, - webAclArn: string, - ) { - new wafv2WebAclAssociation.Wafv2WebAclAssociation( - this, - 'application_waf_association', - { - webAclArn: webAclArn, - resourceArn: cdn.arn, - }, - ); - } - /** * Creates the ALB stack and certificates * @private @@ -510,6 +492,7 @@ export class PocketALBApplication extends Construct { aliases: [this.config.domain], priceClass: 'PriceClass_200', tags: this.config.tags, + webAclId: this.config.wafConfig?.aclArn ?? undefined, origin: [ { domainName: albRecord.fqdn, diff --git a/packages/terraform-modules/src/pocket/__snapshots__/PocketALBApplication.spec.ts.snap b/packages/terraform-modules/src/pocket/__snapshots__/PocketALBApplication.spec.ts.snap index 0f0ea59a4..eb30f0b4b 100644 --- a/packages/terraform-modules/src/pocket/__snapshots__/PocketALBApplication.spec.ts.snap +++ b/packages/terraform-modules/src/pocket/__snapshots__/PocketALBApplication.spec.ts.snap @@ -9413,7 +9413,8 @@ exports[`PocketALBApplication renders an external application with a CDN and a w "acm_certificate_arn": "\${aws_acm_certificate.testPocketApp_cdn_certificate_F1CBB9BB.arn}", "minimum_protocol_version": "TLSv1.1_2016", "ssl_support_method": "sni-only" - } + }, + "web_acl_id": "some-arn" } }, "aws_cloudwatch_dashboard": { @@ -9723,12 +9724,6 @@ exports[`PocketALBApplication renders an external application with a CDN and a w "name_prefix": "testapp-ECSSecurityGroup", "vpc_id": "\${data.aws_vpc.testPocketApp_pocket_vpc_C4E157E3.id}" } - }, - "aws_wafv2_web_acl_association": { - "testPocketApp_application_waf_association_03F7C3FB": { - "resource_arn": "\${aws_cloudfront_distribution.testPocketApp_cloudfront_distribution_FD7F01BF.arn}", - "web_acl_arn": "some-arn" - } } } }"