☰
aws-cdk-examples 实战:用 TypeScript 一键搭建 AWS WAF(CloudFront 与 Regional 双栈)
2026/10/15 2:12:17 网站建设 项目流程

【免费下载链接】aws-cdk-examples

Example projects using the AWS CDK

项目地址:https://gitcode.com/gh_mirrors/aw/aws-cdk-examples
点击查看免费下载

本篇技术指南以 typescript/waf 示例为对象,讲解如何通过 AWS CDK 以基础设施即代码的方式创建两个 WAFv2 Web ACL:一个用于 CloudFront 分发,一个用于 Application Load Balancer 等 Regional 资源。读完本文,你将掌握 WAF 栈的构建与部署流程、AWS 托管规则组与自定义规则(地理限制、速率限制)的配置写法、CloudFormation Export 导出机制,以及如何把 WAF 关联到 CloudFront 分发与 AppSync API。

示例概览:一份代码,两种作用域

示例的核心思路是创建两个“几乎完全相同”的 WAF 栈,分别服务于两类防护场景:

  • waf-cloudfront.ts(WafCloudFrontStack):创建scope为CLOUDFRONT的 Web ACL,用于 CloudFront 分发;
  • waf-regional.ts(WafRegionalStack):创建scope为REGIONAL的 Web ACL,用于 Application Load Balancer、API Gateway、AppSync 等 Regional 资源。

两个栈共用一个makeRules()方法生成规则列表,仅在scope、命名和描述上做了针对性定制。入口文件 app.ts 同时实例化两个栈,并统一指定部署区域为us-east-1:

const app = new cdk.App(); new WafRegionalStack(app, 'WafRegionalStack', {env:{region:"us-east-1"}, description:"WAF Regional"}); new WafCloudFrontStack(app, 'WafCloudFrontStack', {env:{region:"us-east-1"}, description:"WAF CloudFront"});

这里有一个关键的 AWS 约束:当scope为CLOUDFRONT时,WAFv2 资源必须创建在 us-east-1(美国东部弗吉尼亚北部)区域。源码注释中对此有明确说明,这也是示例统一使用us-east-1的原因。

注意:示例 README 顶部带有 Experimental 稳定性标记,其基于标记为“Experimental”的 Construct 库编写,可能不随最新破坏性变更同步更新;如果构建失败,可到仓库提交 issue 反馈问题。

环境准备与构建

在示例根目录typescript/waf下依次执行以下命令完成构建:

npm install -g aws-cdk npm install cdk synth
  • 第一条命令全局安装 AWS CDK CLI;
  • 第二条命令安装示例自身的依赖(对应 package.json 中声明的aws-cdk-lib、constructs、typescript、jest等);
  • 第三条命令cdk synth将 CDK 代码合成为 CloudFormation 模板,产物输出到cdk.out目录。

如果想要单独查看某个栈的 YAML 格式模板,可以把栈名作为参数传给cdk synth:

cdk synth WafCloudFrontStack cdk synth WafRegionalStack

当前示例的 cdk.json 配置了启动命令npx tsc && npx tsx app.ts,即先由 TypeScript 编译器检查编译,再通过 tsx 直接运行app.ts生成应用定义。需要说明的是:示例代码使用 CDK v2 的aws-cdk-lib导入方式,而 README 中遗留的关联代码片段仍为 CDK v1 风格(@aws-cdk/core),实际使用时请以仓库内 waf-cloudfront.ts 的 v2 写法为准。

部署

在示例目录下执行:

cdk deploy

该命令会将栈部署(或重新部署)到你的 AWS 账户。部署完成后,生成的 WAF Web ACL 不会自动挂载到任何资源,需要你手动将 WAF 关联到 CloudFront 或 Load Balancer(关联方式见后文“将 WAF 关联到其他资源”一节)。

WAF 规则详解

AWS 托管规则组:开箱即用的基线防护

示例规则列表以 AWS 托管规则组为主体。在 waf-cloudfront.ts 中,通过listOfRules数组声明了 6 个托管规则组,每个规则组包含name、priority、overrideAction和excludedRules四个字段:

规则组名称优先级防护能力
AWSManagedRulesCommonRuleSet10通用规则集,覆盖 OWASP 常见攻击模式
AWSManagedRulesAmazonIpReputationList20AWS 威胁情报 IP 信誉列表
AWSManagedRulesKnownBadInputsRuleSet30已知恶意输入规则集
AWSManagedRulesAnonymousIpList40匿名 IP(VPN、代理、Tor 出口节点等)
AWSManagedRulesLinuxRuleSet50Linux 操作系统特定攻击
AWSManagedRulesUnixRuleSet60Unix 操作系统特定攻击

优先级数字越小执行越靠前,示例中按 10~60 依次排列,保证托管规则先于自定义规则被评估。两个栈的托管规则组列表完全一致,只是作用域不同。

托管规则组会持续更新,可用 AWS CLI 快速查询当前账户可用的完整列表:

aws wafv2 list-available-managed-rule-groups --scope CLOUDFRONT aws wafv2 list-available-managed-rule-groups --scope REGIONAL

其中--scope的取值与 Web ACL 的scope一一对应:CLOUDFRONT列出可用于 CloudFront 的规则组,REGIONAL列出可用于 Regional 资源的规则组。查询结果可作为扩充或替换示例规则组列表的依据。

基于国家/地区码的连接限制(GeoMatch)

示例代码内置了一条基于源 IP 地理位置的规则,逻辑是:如果源 IP 不在下面的国家/地区列表中,则阻断该连接。实现方式是notStatement包裹geoMatchStatement,即“不在名单内 → 阻断”。

let ruleGeoMatch: wafv2.CfnWebACL.RuleProperty = { name: 'GeoMatch', priority: 0, action: { block: {} // To disable, change to *count* }, statement: { notStatement: { statement: { geoMatchStatement: { // block connection if source not in the below country list countryCodes: [ "AR", // Argentina "BO", // Bolivia "BR", // Brazil "CL", // Chile "CO", // Colombia "EC", // Ecuador "FK", // Falkland Islands "GF", // French Guiana "GY", // Guiana "GY", // Guyana "PY", // Paraguay "PE", // Peru "SR", // Suriname "UY", // Uruguay "VE", // Venezuela ] } } } }, ... };

这段代码(见 waf-cloudfront.ts)默认放行南美洲区域的国家/地区(阿根廷、玻利维亚、巴西、智利、哥伦比亚、厄瓜多尔、秘鲁、乌拉圭、委内瑞拉等),其余地区的请求一律block。源码注释给出了一个重要的调试技巧:如需临时观察命中情况而非直接阻断,把block: {}改为count: {},WAF 会转为计数模式,仅统计命中请求而不断言拒绝。

countryCodes使用 ISO 3166-1 alpha-2 国家/地区代码,你可以按业务需求自由增删列表项。

基于请求速率的连接限制(Rate Limit)

示例还内置了一条速率限制规则,默认行为是:单个 IP 在 5 分钟窗口内请求数超过 100 次即被阻断。

let ruleLimitRequests100: wafv2.CfnWebACL.RuleProperty = { name: 'LimitRequests100', priority: 1, action: { block: {} // To disable, change to *count* }, statement: { rateBasedStatement: { limit: 100, aggregateKeyType: "IP" } }, ... };

该规则(见 waf-cloudfront.ts)使用rateBasedStatement,核心参数说明如下:

  • limit:单 IP 在评估窗口内允许的最大请求数,示例设为 100;
  • aggregateKeyType: "IP":按源 IP 维度聚合统计请求速率。

源码注释对速率限制的语义有精确描述:limit 是单个 IP 在五分钟周期内允许的最大请求数;该值会被持续评估,一旦达到上限请求即被阻断,当速率回落到限制以下后 IP 会被自动解除阻断。也就是说这是一个动态评估、自动恢复的限流机制,无需人工干预解封。同样的,想先观察再启用,可把action从block改为count。

makeRules():规则工厂方法

两个栈的规则构建逻辑集中在makeRules()方法中(waf-cloudfront.ts 与 waf-regional.ts),输入listOfRules数组,返回可直接挂到 Web ACL 上的RuleProperty[]。其处理流程为:

  1. 遍历托管规则组数组,为每个规则组构造managedRuleGroupStatement(vendorName固定为"AWS");
  2. 设置overrideAction: { none: {} },表示不覆盖托管规则组的默认动作;
  3. 为每条规则开启visibilityConfig,即sampledRequestsEnabled(采样请求)与cloudWatchMetricsEnabled(CloudWatch 指标)均设为true,metricName与规则同名,便于在 CloudWatch 中按规则维度观测;
  4. 依次追加GeoMatch(priority 0)与LimitRequests100(priority 1)两条自定义规则;
  5. 返回完整规则数组。

Web ACL 本身在 waf-cloudfront.ts 中创建:

const wafAclCloudFront = new wafv2.CfnWebACL(this, "WafCloudFront", { defaultAction: { allow: {} }, scope: "CLOUDFRONT", visibilityConfig: { cloudWatchMetricsEnabled: true, metricName: "waf-cloudfront", sampledRequestsEnabled: true }, description: "WAFv2 ACL for CloudFront", name: "waf-cloudfront", rules: this.makeRules(managedRules), });

关键属性说明:

  • defaultAction: { allow: {} }:未命中任何规则的请求默认放行(Web ACL 默认只拦截“命中规则”的流量,属于白名单/黑名单之外的兜底策略);
  • scope:CLOUDFRONT或REGIONAL,决定 Web ACL 可关联的资源类型与部署区域要求;
  • visibilityConfig:开启 Web ACL 级别的 CloudWatch 指标与请求采样;
  • rules:即makeRules()产出的全部规则。

创建完成后,代码还为 Web ACL 打上了三组标签(Tag):Name=waf-cloudfront、Purpose=CloudFront、CreatedBy=CloudFormation(见 waf-cloudfront.ts),方便在控制台与成本报告中识别资源归属。waf-regional.ts中的结构完全一致,仅将scope换成REGIONAL、命名改为waf-regional。

将 WAF 关联到其他资源

通过 CloudFormation Export 导出 WAF ARN

每个 WAF 栈都会产生一个 CloudFormation Export,把 Web ACL 的 ARN 导出到账户级别,供其他栈跨栈引用:

  • WafCloudFrontStack:WafAclCloudFrontArn
  • WafRegionalStack:WafAclRegionalArn

导出逻辑在 waf-cloudfront.ts 中实现:

new cdk.CfnOutput(this, "wafAclCloudFrontArn", { value: wafAclCloudFront.attrArn, description: " WAF CloudFront arn", exportName: "WafCloudFrontStack:WafAclCloudFrontArn" });

attrArn是CfnWebACL暴露的 CloudFormation 属性,可直接获得 Web ACL 的 ARN。其他栈通过cdk.Fn.importValue()按导出名导入即可使用。

关联到 CloudFront 分发

在创建 CloudFront 分发的栈中,先导入 WAF ARN,再通过webACLId参数挂载:

import * as cdk from '@aws-cdk/core'; WafAclCloudFrontArn = cdk.Fn.importValue("WafCloudFrontStack:WafAclCloudFrontArn"); new cloudfront.CloudFrontWebDistribution(this, 'frontendDistribution', { ... webACLId: wafAclCloudFrontArn });

webACLId接受 WAF(含 WAFv2)Web ACL 的 ARN。注意上述片段为 README 中的 CDK v1 写法,实际使用 CDK v2 时应通过aws-cdk-lib的Fn.importValue与cloudfront.Distribution(或CloudFrontWebDistribution)完成同等配置。

关联到 AppSync GraphQL API

Regional 类型的 WAF 可以用CfnWebACLAssociation关联到 AppSync GraphQL API。README 给出了完整模式:先导入 Regional WAF 的 ARN,再创建关联资源:

import * as cdk from '@aws-cdk/core'; import * as appsync from '@aws-cdk/aws-appsync' WafAclAppSyncArn = cdk.Fn.importValue("WafRegionalStack:WafAclAppSyncArn"); const gql = new appsync.GraphqlApi(this, 'NeptuneGraphQLApi', { ... }); new wafv2.CfnWebACLAssociation(this, 'NeptuneGraphQLApiWaf', { resourceArn: gql.arn, webAclArn: wafAclAppSyncArn });

CfnWebACLAssociation接收两个关键参数:

  • resourceArn:被防护资源的 ARN,这里取 GraphQL API 的arn;
  • webAclArn:Web ACL 的 ARN,这里导入自WafRegionalStack:WafAclAppSyncArn。

同样的关联方式也适用于 Application Load Balancer、API Gateway REST API、Amazon Cognito 用户池等支持 WAFv2 关联的 Regional 资源,只需把resourceArn替换为对应资源的 ARN 即可。

使用注意事项

  • 区域约束:CLOUDFRONT作用域的 Web ACL 必须在 us-east-1 创建;Regional 类型的 WAF 也应与目标资源同区域。
  • 默认放行策略:Web ACL 的defaultAction为allow,实际拦截能力完全由规则决定;上线前建议先把block临时改为count,观察 CloudWatch 指标与请求采样确认无误后再启用阻断。
  • Experimental 状态:示例基于 Experimental 标记的构造库编写,若遇到构建失败,建议核对 package.json 中的aws-cdk-lib版本与本地环境,或向仓库提交 issue。
  • 手动关联:cdk deploy只创建 WAF 本身,不自动挂载到 CloudFront 或负载均衡器,关联动作需在部署完成后按上文方式在目标资源栈中完成。

通过本文的配置,你可以在同一套代码里同时获得 CloudFront 与 Regional 两种防护能力:托管规则组覆盖常见攻击面,GeoMatch 实现区域封禁,速率限制抵御单 IP 高频请求,CloudFormation Export 则让 WAF 可以跨栈复用到任意目标资源上。

【免费下载链接】aws-cdk-examples

Example projects using the AWS CDK

项目地址:https://gitcode.com/gh_mirrors/aw/aws-cdk-examples
点击查看免费下载
上一篇:vue-admin-better单元测试入门:组件测试与逻辑测试
下一篇:IDB终极实战指南:高效自动化iOS设备与模拟器管理的完整方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询