2. Network Firewall架构解析

AWS Network Firewall 并不是一个“打开开关就生效”的托管服务,它的安全能力由一组彼此解耦、又必须按固定顺序协同的对象共同构成。理解这些对象之间的依赖关系,是后续做规则调优、排障和成本控制的前提。本节把架构拆成五个层次来看:防火墙端点决定流量从哪里被拦截,无状态引擎做第一道粗筛,有状态引擎做精细判定,规则组与策略是承载这些判定的配置载体,日志架构则决定你能否看清每一次放行或丢弃的原因。

防火墙端点:流量进入检查的物理入口

创建 Network Firewall 时,必须把它关联到一个 VPC,并至少指定一个子网。防火墙会在该子网中创建一个防火墙端点(Firewall Endpoint),本质是一个由 AWS 托管的 VPC 终端节点,拥有独立的弹性网络接口和 IP 地址。端点分为两种:可用区端点部署在你指定的每个子网内,用于检查同可用区的流量;区域端点由 AWS 自动创建,用于检查跨可用区或来自互联网网关、NAT 网关等非 VPC 内部路径的流量。

关键点在于:防火墙端点不会自动接管流量。你必须通过修改路由表,把需要检查的流量“引导”到端点。典型做法是在防火墙子网的路由表中,把目标为 0.0.0.0/0 的路由指向 Internet Gateway 或 NAT Gateway,而在业务子网的路由表中,把目标为 0.0.0.0/0 的路由指向防火墙端点。这样,出站流量先到防火墙,检查通过后再由防火墙子网转发出去。如果路由配置错误,流量会绕过防火墙,规则再严格也无效。

无状态与有状态引擎:两道不同粒度的检查

Network Firewall 的检查分为两个阶段。第一阶段是无状态引擎(Stateless Engine),它逐包检查,不维护连接状态,依据五元组(源 IP、目的 IP、源端口、目的端口、协议)以及 TCP 标志位做匹配。无状态规则组可以执行三种动作:pass(放行并跳过后续无状态规则)、drop(丢弃)、forward(交给有状态引擎继续处理)。由于不维护状态,无状态引擎适合做高速粗筛,例如直接丢弃来自已知恶意 IP 的流量,或放行不需要深度检查的备份流量。

第二阶段是有状态引擎(Stateful Engine),它维护连接跟踪表,能够理解“这是已建立连接的返回包”,因此可以基于域、协议、TCP 标志、甚至 Suricata 兼容规则做精细判定。有状态规则组的动作包括 pass、drop、alert 和 reject。默认情况下,有状态引擎采用“默认放行”还是“默认丢弃”,由策略中的 StatefulDefaultActions 决定,这一点直接决定安全基线是白名单还是黑名单模式。

Network Firewall 流量处理顺序与引擎分工 业务子网 EC2 / 容器 路由表引导 0.0.0.0/0 → 端点 防火墙端点 可用区端点 / 区域端点 ENI + 独立 IP 无状态引擎(逐包) 五元组 + TCP 标志匹配 动作:pass / drop / forward 有状态引擎(连接跟踪) 域 / 协议 / Suricata 规则 动作:pass / drop / alert / reject 默认动作由策略决定 规则组(Rule Group) 无状态规则组 / 有状态规则组 可复用、可版本化、可引用 策略(Policy)绑定规则组 + 默认动作 日志架构:Flow Logs / Alert Logs / TLS Logs 发送至 CloudWatch Logs、S3 或 Kinesis Data Firehose,用于审计、排障与规则命中分析 日志记录的是“哪条规则、什么动作、什么五元组”,是验证策略是否生效的唯一依据 forward drop 记录 绑定 无状态规则组 放行出口 IGW / NAT GW pass / 默认放行 丢弃 / 拒绝 流量终止 drop / reject

规则组与策略:配置的复用与绑定

规则组是规则的容器,分为无状态规则组和有状态规则组,两者不能混用。规则组可以被多个防火墙策略引用,因此适合把“通用阻断列表”“业务白名单”做成独立规则组,在不同 VPC 的防火墙之间复用。策略(Firewall Policy)则是把无状态规则组、有状态规则组和默认动作组合在一起的顶层对象,防火墙本身只引用策略,不直接引用规则组。

策略中有一个容易被忽视但影响巨大的参数:StatefulDefaultActions。如果设置为 aws:drop-established,则所有未被有状态规则显式放行的已建立连接都会被丢弃,形成白名单模式;如果保留默认的 aws:pass,则未匹配流量会被放行,形成黑名单模式。生产环境通常建议先以黑名单模式上线观察日志,确认规则覆盖度后再切换为白名单模式。

流量处理顺序:先无状态,后有状态

一个数据包进入防火墙端点后,处理顺序是固定的:先经过无状态引擎,按规则组顺序逐条匹配。如果命中 drop,直接丢弃并记录;如果命中 pass,跳过后续无状态规则,直接进入有状态引擎的“已放行”路径;如果命中 forward 或没有命中任何规则,则交给有状态引擎。有状态引擎再按规则组优先级匹配,最终执行放行、丢弃、告警或拒绝。理解这个顺序的意义在于:无状态规则可以显著降低有状态引擎的负载,把明显恶意的流量在最外层就丢掉,而不是让所有流量都进入连接跟踪表。

日志架构:让每一次判定可追溯

Network Firewall 支持三类日志:Flow Logs 记录通过防火墙的流量元数据,包括五元组、动作和命中的规则;Alert Logs 记录有状态规则中 alert 动作触发的告警;TLS Logs 记录 TLS 握手相关的元数据,用于分析加密流量的 SNI 和证书信息。日志可以发送到 CloudWatch Logs、S3 或 Kinesis Data Firehose。排障时最常用的判断路径是:先在 Flow Logs 中确认流量是否到达防火墙、命中了哪条规则、动作是什么;如果流量根本没出现,问题多半在路由表或安全组,而不是防火墙规则本身。

建议在策略上线初期同时开启 Flow Logs 和 Alert Logs,并把日志发送到 S3 做长期留存。Flow Logs 的字段中包含 event.flow.src_ip、event.flow.dest_ip、event.flow.proto 和 event.flow.verdict.action,可以直接用于验证某条规则是否按预期命中。

一个可参考的策略配置示例

下面给出一个简化的策略结构示例,用于说明规则组与策略的绑定关系。示例中的 IP 和域名均为教学假设值,不代表真实环境。

FirewallPolicy: prod-edge-policy
├── StatelessDefaultActions: aws:forward_to_sfe
├── StatelessFragmentDefaultActions: aws:forward_to_sfe
├── StatelessRuleGroups:
│   ├── rg-block-known-bad-ips   (priority 100)
│   │   └── drop 203.0.113.0/24, 198.51.100.0/24
│   └── rg-allow-backup          (priority 200)
│       └── pass tcp 10.0.0.0/8 -> 10.0.1.0/24:22
└── StatefulRuleGroups:
    ├── rg-domain-allowlist      (priority 100)
    │   └── pass tcp any -> .amazonaws.com:443
    └── rg-threat-signatures     (priority 200)
        └── drop alert http any -> any (Suricata SID 2000001)
StatefulDefaultActions: aws:drop-established

在这个示例中,无状态规则组先丢弃已知恶意 IP,再放行备份流量;其余流量交给有状态引擎,先匹配域名白名单,再匹配威胁特征规则,最后未匹配的已建立连接被默认丢弃。这样的顺序既保证了性能,也保证了安全基线。实际部署时,应先用黑名单默认动作观察日志,确认没有误杀业务流量后,再切换为 aws:drop-established。