devotica-labs/terraform-aws-wafv2

GitHub: devotica-labs/terraform-aws-wafv2

面向金融科技场景的 AWS WAFv2 Web ACL Terraform 模块,提供预置托管规则与速率限制以快速实现边缘安全防护。

Stars: 0 | Forks: 0

# terraform-aws-wafv2 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/devotica-labs/terraform-aws-wafv2/actions/workflows/ci.yml) [![Release](https://static.pigsec.cn/wp-content/uploads/repos/cas/42/42ba98a60a0bb3b0ad908f024db145f9c5b831eb7df822f56ac578ee7d7215b3.svg)](https://github.com/devotica-labs/terraform-aws-wafv2/actions/workflows/release.yml) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE) ## 介绍 用于 AWS **WAFv2 Web ACL** 的 Terraform module —— 即公共边缘的 Web 应用防火墙。它提供了一套自带的、适用于金融科技的默认规则集,可附加到 REGIONAL 资源(ALB / API Gateway / AppSync),或为 CloudFront 分发暴露其 ARN。 它不是一个可以随意传递规则的引擎,而是为边缘至关重要的规则类型提供了专注的输入项:AWS 托管规则组、速率限制、IP 允许/阻止集以及地理位置匹配。 ## 用法 ``` module "wafv2" { source = "devotica-labs/wafv2/aws" version = "~> 0.1" namespace = "dvtca" stage = "prod" name = "edge" scope = "REGIONAL" # Attach to the public ALB. association_resource_arns = [module.alb.alb_arn] # Defaults: AWS managed baseline (Common, KnownBadInputs, SQLi, IP reputation) # in block mode + a 2000-req/5-min rate limit + CloudWatch metrics. tags = { Environment = "production" Project = "edge" Owner = "platform@example.com" CostCenter = "PLATFORM" ManagedBy = "Terraform" } } ``` ## 示例 - [`examples/basic`](examples/basic/main.tf) — ALB 上的托管规则 + 速率限制基线。 - [`examples/complete`](examples/complete/main.tf) — 每个规则的覆盖设置、计数模式的规则组、更严格的速率限制、IP 允许/阻止集、地理封锁以及带有脱敏 header 的 Firehose 日志记录。 ## 重要的默认设置 在 [`variables.tf`](variables.tf) 中标注了 `# Devotica fintech default`: - **托管规则基线,阻止模式** — `AWSManagedRulesCommonRuleSet`、`KnownBadInputsRuleSet`、`SQLiRuleSet`、`AmazonIpReputationList`,全部处于阻止模式。在调试时可将每个规则覆盖为 `count`,或添加更多规则组。 - **开启速率限制** — 每个 IP 在 5 分钟窗口内 2000 次请求,超出即阻止。设置 `rate_limit = null` 可禁用。 - **`default_action = allow`** — WAF 通过规则阻止已知的恶意流量;仅在明确的白名单策略下才切换为 `block`。 - **开启指标 + 采样请求** — 每个规则和 ACL 都会发出 CloudWatch 指标,并保留请求样本以供调查。 一个 `check` 块确保规则的优先级在托管组、速率限制、IP 集和地理规则中保持唯一。 ## 这如何融入 Devotica 目录 ``` internet │ ▼ terraform-aws-wafv2 (Web ACL: managed rules + rate limit + IP/geo) │ associates with (REGIONAL) │ or web_acl_id (CLOUDFRONT) ▼ ▼ terraform-aws-alb CloudFront distribution │ ▼ terraform-aws-ecs-fargate / eks workloads ``` 将 Web ACL 附加到 `terraform-aws-alb` 的 ARN (`association_resource_arns`),或者将 `web_acl_arn` 传递给 CloudFront 分发的 `web_acl_id`。将日志流式传输到 `aws-waf-logs-*` CloudWatch 日志组 / Firehose / S3 存储桶。 ## Makefile 目标 ``` make init # terraform init (no backend) make validate # terraform fmt -check + validate make lint # tflint make test # terraform test (unit + contract, against Terraform 1.9.5) make readme # regenerate the terraform-docs section of README.md ``` ![架构图(从 examples/complete 自动生成)](https://static.pigsec.cn/wp-content/uploads/repos/cas/04/04ed28b42e6c659c6cc6ad783c0f9a4411875e478ccfe55f6c601e8355ff9fa0.png) 由 `.github/workflows/architecture-diagram.yml` 在每次推送到 main 分支时生成。请勿手动编辑此图像 —— 修改 `examples/complete/` 中的 Terraform 代码,机器人会自动重新生成它。 ## 治理 - CI 运行来自 `devotica-labs/terraform-shared-config` 的中央可重用工作流:fmt、validate、tflint、tfsec/trivy、gitleaks、terraform-docs、针对 `devotica-labs/terraform-policies` 的 conftest、terraform test、checkov 以及示例构建。 - 版本由 `release-please` 基于 Conventional Commits 进行发布。每个版本都通过 cosign 进行无密钥签名,并附带 CycloneDX SBOM。 - 一旦 CI 通过,Dependabot PR 将自动批准并自动合并。 ## 用法 ### 基础 ``` # --------------------------------------------------------------------------- # Provider block — 对 CI 友好的 skip flags + non-AWS-shaped placeholder creds。 # --------------------------------------------------------------------------- provider "aws" { region = "ap-south-1" access_key = "not-a-real-aws-key" secret_key = "not-a-real-aws-secret" skip_credentials_validation = true skip_metadata_api_check = true skip_requesting_account_id = true } # 开发期间使用 local path。 # 首次发布后更改为 Registry source: # source = "devotica-labs/wafv2/aws" # version = "~> 0.1" module "wafv2" { source = "../.." # Web ACL name composes to: dvtca-sandbox-edge namespace = "dvtca" stage = "sandbox" name = "edge" scope = "REGIONAL" # Attach to a public ALB (terraform-aws-alb output). association_resource_arns = [ "arn:aws:elasticloadbalancing:ap-south-1:111122223333:loadbalancer/app/dvtca-sandbox/0123456789abcdef", ] # Fintech defaults cover the rest: AWS managed rule baseline (Common, # KnownBadInputs, SQLi, IP reputation) in block mode, a 2000-req/5-min # rate limit, and CloudWatch metrics + sampled requests on. tags = { Environment = "sandbox" Project = "terraform-aws-wafv2" Owner = "platform@devotica.com" CostCenter = "PLATFORM-OSS" ManagedBy = "Terraform" Repo = "https://github.com/devotica-labs/terraform-aws-wafv2" } } ``` ### 完整 ``` # --------------------------------------------------------------------------- # Provider block — 对 CI 友好的 skip flags + non-AWS-shaped placeholder creds。 # --------------------------------------------------------------------------- provider "aws" { region = "ap-south-1" access_key = "not-a-real-aws-key" secret_key = "not-a-real-aws-secret" skip_credentials_validation = true skip_metadata_api_check = true skip_requesting_account_id = true } # 开发期间使用 local path。 # 首次发布后更改为 Registry source: # source = "devotica-labs/wafv2/aws" # version = "~> 0.1" module "wafv2" { source = "../.." # Web ACL name composes to: dvtca-aps1-prod-payments namespace = "dvtca" environment = "aps1" stage = "prod" name = "payments" scope = "REGIONAL" # Managed rule baseline, with one in count mode and a per-rule override. managed_rule_groups = [ { name = "AWSManagedRulesCommonRuleSet" priority = 10 # Let large request bodies through (the API uploads documents). rule_action_overrides = { SizeRestrictions_BODY = "count" } }, { name = "AWSManagedRulesKnownBadInputsRuleSet", priority = 20 }, { name = "AWSManagedRulesSQLiRuleSet", priority = 30 }, { name = "AWSManagedRulesAmazonIpReputationList", priority = 40 }, # Observe-only while tuning. { name = "AWSManagedRulesLinuxRuleSet", priority = 50, count_only = true }, ] # Tighter rate limit for the payments edge. rate_limit = { limit = 1000 priority = 100 } # Always allow the office/VPN ranges; block a known-bad set. ip_allow_list = { addresses = ["203.0.113.0/24"] priority = 1 } ip_block_list = { addresses = ["198.51.100.7/32"] priority = 2 } # Block sanctioned jurisdictions. geo_block = { country_codes = ["KP", "IR", "SY", "CU"] priority = 5 } # Stream logs to a Firehose (name must start with aws-waf-logs-), redacting # the Authorization header. log_destination_configs = [ "arn:aws:firehose:ap-south-1:111122223333:deliverystream/aws-waf-logs-payments", ] redacted_fields = [ { single_header = ["authorization"] }, ] # Attach to the public ALB. association_resource_arns = [ "arn:aws:elasticloadbalancing:ap-south-1:111122223333:loadbalancer/app/dvtca-prod-payments/0123456789abcdef", ] tags = { Environment = "production" Project = "payments" Owner = "platform@devotica.com" CostCenter = "PLATFORM" ManagedBy = "Terraform" Repo = "https://github.com/devotica-labs/terraform-aws-wafv2" } } ``` ## 要求 | 名称 | 版本 | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.0 | | [aws](#requirement\_aws) | >= 5.0.0 | ## Providers | 名称 | 版本 | |------|---------| | [aws](#provider\_aws) | >= 5.0.0 | ## 资源 | 名称 | 类型 | |------|------| | [aws_wafv2_ip_set.allow](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_ip_set) | resource | | [aws_wafv2_ip_set.block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_ip_set) | resource | | [aws_wafv2_web_acl.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl) | resource | | [aws_wafv2_web_acl_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_association) | resource | | [aws_wafv2_web_acl_logging_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_logging_configuration) | resource | ## 输入 | 名称 | 描述 | 类型 | 默认值 | 必填 | |------|-------------|------|---------|:--------:| | [association\_resource\_arns](#input\_association\_resource\_arns) | 仅限 REGIONAL:要与此 Web ACL 关联的资源(例如 ALB)的 ARN。对于 CloudFront,请在分发上设置 web\_acl\_id。 | `list(string)` | `[]` | no | | [attributes](#input\_attributes) | 附加到 id 后的额外属性(例如 ["workers"])。 | `list(string)` | `[]` | no | | [cloudwatch\_metrics\_enabled](#input\_cloudwatch\_metrics\_enabled) | 为 Web ACL 及其每个规则发出 CloudWatch 指标。 | `bool` | `true` | no | | [default\_action](#input\_default\_action) | 对于不匹配任何规则的请求采取的操作:允许或阻止。金融科技的默认设置是 allow —— 规则会阻止已知的恶意流量;仅在白名单策略下才切换为 block。 | `string` | `"allow"` | no | | [delimiter](#input\_delimiter) | 连接 id 各段的分隔符。 | `string` | `"-"` | no | | [description](#input\_description) | Web ACL 的描述。默认为组合的名称。 | `string` | `null` | no | | [enabled](#input\_enabled) | 设置为 false 可使此 module 成为空操作(不创建任何资源)。 | `bool` | `true` | no | | [environment](#input\_environment) | 环境段(例如简短的区域代码)。 | `string` | `null` | no | | [geo\_allow](#input\_geo\_allow) | 仅允许这些国家/地区 —— 阻止所有其他请求(default\_action 应保持 allow;此规则通过 NOT 匹配阻止未列出的国家/地区)。 |
object({
country_codes = list(string)
priority = number
})
| `null` | no | | [geo\_block](#input\_geo\_block) | 阻止来自这些 ISO-3166 国家/地区代码的请求(例如 ["KP","IR"])。 |
object({
country_codes = list(string)
priority = number
})
| `null` | no | | [id\_length\_limit](#input\_id\_length\_limit) | 将组合的 id 截断为最多此字符数。0 表示无限制。 | `number` | `0` | no | | [ip\_allow\_list](#input\_ip\_allow\_list) | 创建一个 IP 集以及一个允许这些 CIDR 的规则(在给定的优先级下先于托管规则进行评估)。 |
object({
addresses = list(string)
priority = number
ip_version = optional(string, "IPV4")
})
| `null` | no | | [ip\_block\_list](#input\_ip\_block\_list) | 创建一个 IP 集以及一个阻止这些 CIDR 的规则。 |
object({
addresses = list(string)
priority = number
ip_version = optional(string, "IPV4")
})
| `null` | no | | [label\_order](#input\_label\_order) | 用于构建 id 的标签段顺序。允许的键:namespace、environment、stage、name、attributes。 | `list(string)` |
[
"namespace",
"environment",
"stage",
"name",
"attributes"
]
| no | | [label\_value\_case](#input\_label\_value\_case) | 应用于组合 id 的大小写:lower、upper 或 none。 | `string` | `"lower"` | no | | [log\_destination\_configs](#input\_log\_destination\_configs) | 日志记录目标的 ARN(CloudWatch 日志组 / Kinesis Firehose / S3)—— 每个名称必须以 `aws-waf-logs-` 开头。为空将禁用日志记录。 | `list(string)` | `[]` | no | | [managed\_rule\_groups](#input\_managed\_rule\_groups) | 要附加的 AWS(或市场)托管规则组。默认为金融科技基线:Common、KnownBadInputs、SQLi 和 Amazon IP 信誉列表 —— 全部处于阻止模式。 |
list(object({
name = string
vendor_name = optional(string, "AWS")
priority = number
# Set true to run the group in count mode (observe only, no blocking).
count_only = optional(bool, false)
# Per-rule action overrides within the group (rule_name => "count"|"allow"|"block").
rule_action_overrides = optional(map(string), {})
}))
|
[
{
"name": "AWSManagedRulesCommonRuleSet",
"priority": 10
},
{
"name": "AWSManagedRulesKnownBadInputsRuleSet",
"priority": 20
},
{
"name": "AWSManagedRulesSQLiRuleSet",
"priority": 30
},
{
"name": "AWSManagedRulesAmazonIpReputationList",
"priority": 40
}
]
| no | | [name](#input\_name) | 解决方案 / 基础名称(例如 "app")。 | `string` | `null` | no | | [namespace](#input\_namespace) | 命名空间 / 组织前缀(例如 "dvtca")。 | `string` | `null` | no | | [rate\_limit](#input\_rate\_limit) | 基于速率的规则:阻止在任何 5 分钟窗口内超过 `limit` 次请求的 IP。设置为 null 可禁用。 |
object({
limit = optional(number, 2000)
priority = optional(number, 100)
aggregate_key_type = optional(string, "IP")
action = optional(string, "block")
})
| `{}` | no | | [redacted\_fields](#input\_redacted\_fields) | 日志中脱敏的字段(例如 Authorization header)。 |
list(object({
method = optional(bool, false)
query_string = optional(bool, false)
uri_path = optional(bool, false)
single_header = optional(list(string))
}))
| `[]` | no | | [regex\_replace\_chars](#input\_regex\_replace\_chars) | 从每个 id 段中剥离的字符正则表达式(格式为 /.../)。 | `string` |"/[^-a-zA-Z0-9]/"` | no | | [sampled\_requests\_enabled](#input\_sampled\_requests\_enabled) | 为每个规则存储已检查请求的样本(可在控制台中查看)。 | `bool` | `true` | no | | [scope](#input\_scope) | REGIONAL(ALB / API Gateway / AppSync)或 CLOUDFRONT。CLOUDFRONT Web ACL 必须在 us-east-1 中创建。 | `string` | `"REGIONAL"` | no | | [stage](#input\_stage) | 阶段 / 账户段(例如 "prod")。 | `string` | `null` | no | | [tags](#input\_tags) | 合并到每个可标记资源的额外标签。 | `map(string)` | `{}` | no | ## 输出 | 名称 | 描述 | |------|-------------| | [ip\_set\_allow\_arn](#output\_ip\_set\_allow\_arn) | 允许列表 IP 集的 ARN(如果没有则为 null)。 | | [ip\_set\_block\_arn](#output\_ip\_set\_block\_arn) | 阻止列表 IP 集的 ARN(如果没有则为 null)。 | | [logging\_configuration\_id](#output\_logging\_configuration\_id) | Web ACL 日志记录配置的 ID(如果禁用日志记录则为 null)。 | | [web\_acl\_arn](#output\_web\_acl\_arn) | WAFv2 Web ACL 的 ARN。对于 CloudFront,将此项设置为分发的 web\_acl\_id。 | | [web\_acl\_capacity](#output\_web\_acl\_capacity) | 规则消耗的 Web ACL 容量单位 (WCU)。 | | [web\_acl\_id](#output\_web\_acl\_id) | WAFv2 Web ACL 的 ID。 | | [web\_acl\_name](#output\_web\_acl\_name) | Web ACL 的名称。 | ## 相关项目 - [terraform-aws-alb](https://github.com/devotica-labs/terraform-aws-alb) — 此 Web ACL 所保护的公共 ALB。 ## 参考 - [AWS WAF Web ACLs](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl.html) - [AWS Managed Rule Groups](https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-list.html) - [Rate-based rules](https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-type-rate-based.html) ## 许可证 Apache-2.0。详见 [`LICENSE`](LICENSE) 和 [`NOTICE`](NOTICE)。
标签:AWS, DPI, ECS, Terraform, WAF, WAF规则