API 网关和 Web 应用防火墙(WAF,Web Application Firewall)解决的是 API 安全中的不同问题。网关负责 API 身份、路由、配额和面向服务的策略;WAF 检查 HTTP 流量中的攻击特征,并执行受管理的规则集。可靠的架构需要明确两者职责,防止客户端绕过任一控制,并预先决定检查变慢或不可用时如何处理请求。
因此,“把 WAF 放在网关前面”并不是完整设计。你还必须说明唯一允许的请求路径、由哪个组件确认客户端 IP、哪些内容能够被检查、重复控制如何配合,以及每类路由在故障时开放还是关闭。
核心要点
- 让 WAF 负责攻击检查,让网关负责 API 身份、授权、路由和配额。
- 只接收明确可信代理提供的转发请求头,并覆盖而不是追加安全敏感上下文。
- 限制网关或源站,防止客户端绕过 WAF 直接访问。
- 根据路由和威胁模型选择故障开放或故障关闭,并通过超时、过载和局部故障测试验证。
- 先以监控模式运行,用代表性流量调优,再通过可观测且可回滚的流程启用拦截。
划分控制职责
| 决策 | 主要负责人 | 原因 |
|---|---|---|
| 已知 HTTP 攻击特征 | WAF | 规则引擎擅长检查请求组件并持续更新攻击规则 |
| Token 验证与客户端身份 | API 网关或身份感知服务 | 身份判断需要签发者、Audience、签名和路由上下文 |
| 路由和方法授权 | API 网关与应用共同负责 | 网关可拒绝粗粒度策略,应用保留对象状态检查 |
| 速率与并发策略 | API 网关 | 限制通常取决于路由、Consumer、租户或服务容量 |
| Schema 与业务不变量 | 网关验证器和应用 | WAF 规则集不了解完整 API 契约和领域状态 |
| 漏洞修复 | 应用负责人 | 过滤只是补偿控制,不能代替代码修复 |
OWASP API Security Top 10 涵盖对象级授权失效、资源消耗不受限等风险。通用 WAF 无法判断对象归属,也不知道某个租户的容量预算。即使 WAF 能拦截注入载荷,也必须在网关和应用中保留相应控制。
选择流量拓扑
位于网关之前的边缘 WAF
1flowchart LR
2 C[客户端] --> W[边缘 WAF]
3 W --> G[API 网关]
4 G --> A[API 服务]这种模式在公网入口统一过滤,并可在恶意流量到达网关前将其丢弃。其安全前提很严格:网关只能接受来自 WAF 路径的公网流量。可以使用私有网络、源站访问控制、防火墙规则或经过认证的源站连接。如果公网仍能直接访问网关域名,WAF 就只是一个可选中转点。
网关集成的 WAF 服务
1flowchart LR
2 C[客户端] --> G[API 网关]
3 G -->|检查请求| W[WAF 服务]
4 W -->|返回 pass 或 reject| G
5 G -->|按配置执行 monitor 或 block 模式| O[继续转发或拒绝请求]这种模式允许网关按路由选择是否检查,并附加规范化后的上下文,但 WAF 的延迟与可用性也会进入请求链路。Apache APISIX 通过 chaitin-waf 插件记录了这一模式:插件连接 SafeLine 节点。SafeLine 返回 pass 或 reject 决策,随后 APISIX 按插件模式处理结果。在 monitor 模式下,插件会记录拒绝结果,但不会拦截请求;在 block 模式下,拒绝结果会导致请求被拦截。它只是一个集成示例,不能推导出所有 WAF 都具有相同契约。
不要默认让两层执行完全相同的规则。重复检查会增加延迟,还可能产生互相冲突的拦截结果。如果确实需要两层,应明确各自范围,例如边缘层处理广泛的互联网威胁,靠近 API 上下文的一层执行路由级检查。
建立可信请求头契约
每个代理节点都可能添加或重写 Forwarded、X-Forwarded-For、X-Forwarded-Proto、Host 和请求关联头。如果网关信任任意客户端提供的这些值,IP 限制、审计记录、重定向和 WAF 例外都可能出现错误。
应按顺序定义契约:
- 列出所有可信代理或负载均衡器的地址范围。
- 在第一个可信节点丢弃客户端提供的安全敏感转发字段。
- 创建规范化的客户端 IP、Scheme、Host 和请求 ID。
- 后续节点只在直接对端可信时才接受这些值。
- 只向应用转发其真正需要的上下文。
当前 APISIX chaitin-waf 文档说明:启用 real_client_ip(默认值)时,插件会发送由连接信息和 apisix.trusted_addresses 共同解析出的客户端 IP;禁用时,插件会发送与 APISIX 直接建立连接的对端 IP。应把此设置视为安全边界,而不是方便选项。测试带伪造转发请求头的直接连接,并确认 WAF、网关和应用日志对客户端上下文的记录一致。
明确检查与隐私边界
记录 WAF 会接收请求的哪些部分:请求头、查询参数、路径、正文以及最大正文大小,然后对数据分类。如果脱敏不完整,Authorization 请求头、Cookie、个人信息、文件上传和支付字段都可能进入 WAF 日志或诊断信息。
为正文与超时设置明确上限。对于超过检查上限的正文,必须定义处理结果:拒绝、只检查元数据、转入专用上传路径,或在记录例外后接收。即使 TLS 已终止,加密或压缩后的应用载荷仍可能无法检查。因此,“通过 WAF”只表示被检查的那部分内容没有触发当前启用的规则。
按路由决定故障行为
WAF 故障没有适用于所有场景的答案。
| 路由类型 | 常见起点 | 必须补充的约束 |
|---|---|---|
| 低敏感公开读取 | 可以评估有边界的故障开放 | 保留网关身份与限流;立即告警;限制持续时间 |
| 登录、支付、管理或写操作 | 故障关闭或返回独立服务错误 | 隔离 WAF 容量并测试恢复,避免故障演变为长时间停机 |
| 健康检查与内部控制端点 | 仅在确有必要时显式绕过 | 使用网络和身份限制;不得继承宽泛的通配符例外 |
恶意请求拦截与检查基础设施故障必须可区分。客户端和运维人员需要不同的状态、原因码、指标与日志字段。还应限制重试,因为对过载 WAF 池持续重试会放大事故。
安全发布规则
不要直接用拦截模式启用大型规则集,而应按生命周期推进:
- 盘点 API 方法、内容类型、正常正文大小和已知机器客户端。
- 在少量路由上启用监控模式。
- 按规则 ID、路由、响应结果和客户端类型统计匹配,同时避免记录密钥。
- 使用脱敏测试用例复现可能的误报。
- 把经过审查的规则子集提升为拦截模式。
- 灰度发布变更,并保留快速且有审计记录的回滚方式。
- 应用完成修复后,使临时例外与虚拟补丁到期。
OWASP Core Rule Set 文档说明,规则调优与异常评分本身就是持续运营工作。为解决一个误报而全局降低敏感度,会削弱其他路由;应优先采用绑定到具体路由和参数的窄范围排除规则。
验证方案
应把架构作为一个整体来测试:
- 正常请求能够到达目标上游;
- 代表性注入载荷在监控模式下被识别,在拦截模式下被拒绝;
- 直接请求无法绕过 WAF 或网关;
- 伪造转发头不会改变可信客户端身份;
- 超大或不支持的正文进入预期处理路径;
- WAF 超时、拒绝连接和过载会触发选定的路由行为;
- 日志能关联 WAF、网关和服务中的同一请求,同时不泄露凭证;
- 禁用或回滚规则的操作可观测且受访问控制。
安全扫描可以用来验证契约,但单次扫描不能证明系统已经安全。规则、代理、TLS、路由或应用变化后都应重新测试。
设计检查清单
- API 是否只有一条允许的公网访问路径?
- 哪个组件创建可信客户端上下文,哪些对端可以提供该上下文?
- 哪些请求字段会被检查,上限是多少?
- 哪些控制仍由网关和应用负责?
- 每类路由是否定义了超时与故障行为?
- WAF 事件能否在不记录密钥或完整敏感正文的情况下关联?
- 规则能否监控、灰度、回滚并自动到期?
- 是否测试了绕过、伪造、过载与恢复?
总结
只有职责不混淆时,WAF 与 API 网关的组合才最可靠。让 WAF 检查攻击,让网关保留身份和 API 感知策略,让应用继续执行业务授权,并使每一次信任转换都可测试。这样形成的是边界清晰的纵深防御,而不是一条默认每个请求都按预期路径流转的设备链。
常见问题
WAF 能否取代 API 身份认证与授权?
不能。WAF 可以拒绝可疑 HTTP 模式,但通常无法判断一个已验证主体是否拥有特定对象,或是否可以执行某项业务操作。
WAF 应该放在 API 网关前,还是集成到网关内?
应根据暴露面、路由上下文、延迟和运维能力选择。边缘 WAF 需要严格限制源站;集成式 WAF 则需要明确同步调用失败时的契约。
集成是否应该故障开放?
只能在完成路由级风险决策后选择。低风险读取可以考虑有限时长的故障开放,而敏感写操作通常需要故障关闭。
后续步骤
继续阅读 API 网关 DDoS 防御,明确 IP 黑白名单的信任关系,并通过 API 网关安全扫描方案验证设计。
