首页 用 X-Origin-Protection Header 保护 ALB 源站
文章
取消

用 X-Origin-Protection Header 保护 ALB 源站

背景

在 CloudFront + ALB 的 Web 架构中,直接通过 ALB 域名访问可以绕过 CDN 的 WAF 规则、缓存策略和 TLS 证书,让源站直接暴露在攻击者面前。一个常见的安全实践是让 CloudFront 在转发请求时带上一个自定义 Header,ALB 端只有携带该 Header 的请求才会被路由到后端。

架构链路

1
用户 → CloudFront (HTTPS) → ALB (HTTP, 校验 X-Origin-Protection Header) → EC2 (Frontend:80 / Backend:8080)

三层防护:

  1. ALB Security Group — 仅允许 CloudFront 的 IP 前缀列表访问
  2. ALB Listener 默认动作 — 不携带正确 Header 的请求返回 403
  3. ALB Listener Rule — 携带正确 Header 的请求才被路由到目标组

实现

CloudFront 侧:Origin 添加自定义 Header

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
resource "aws_cloudfront_distribution" "main" {
  origin {
    domain_name = var.alb_dns_name
    origin_id   = "alb-origin"

    custom_header {
      name  = "X-Origin-Protection"
      value = var.cloudfront_header_secret
    }

    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "http-only"
    }
  }
}

CloudFront 在每次转发请求到 ALB 时,都会自动注入 X-Origin-Protection Header。

ALB 侧:安全组限制入站来源

1
2
3
4
5
6
7
8
9
resource "aws_security_group_rule" "alb_http" {
  description       = "HTTP/HTTPS from CloudFront"
  type              = "ingress"
  from_port         = 80
  to_port           = 443
  protocol          = "tcp"
  prefix_list_ids   = [data.aws_ec2_managed_prefix_list.cloudfront_origin.id]
  security_group_id = aws_security_group.alb.id
}

使用 AWS 托管前缀列表 cloudfront_origin,自动包含 CloudFront 所有边缘节点的 IP 段。

ALB 侧:Listener 规则

ALB 监听器(端口 80)的配置有三层:

优先级条件动作
默认无(fallback)固定响应 403 Forbidden
50Path /api/*转发到后端目标组(8080)
100Header X-Origin-Protection转发到前端目标组(80)

默认返回 403 确保了没有携带正确 Header 的请求被直接拒绝。携带了 Header 的请求按路径规则路由。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.main[0].arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type = "fixed-response"
    fixed_response {
      content_type = "text/plain"
      message_body = "Forbidden"
      status_code  = "403"
    }
  }
}

验证测试

部署后用 curl 验证:

1
2
3
4
5
6
7
8
9
10
11
# 直接访问 ALB(无 Header)→ 安全组丢包,无响应
$ curl http://<alb-dns>
# 无响应(TCP 连接超时)

# 如果放开安全组允许公网访问 → 返回 403
$ curl http://<alb-dns>
Forbidden

# 带正确 Header → 正常路由
$ curl -H "X-Origin-Protection: <secret>" http://<alb-dns>
# 返回页面内容

注意:当前安全组只允许 CloudFront IP 入站,公网直接访问 ALB 会被安全组拦截,到不了 listenr 规则层。Header 校验是额外的纵深防御层。

纵深防御的设计思路

层级机制绕过难度
Security Group仅允许 CloudFront 前缀列表高(需控制 CloudFront IP)
Listener 默认动作无 Header 返回 403中(需知道 Header 名称和值)
Listener Rule匹配 Header 路由到后端

即使某层被绕过,后续还有另一层拦截。

密钥管理

X-Origin-Protection 移到 AWS Secrets Manager 或 SSM Parameter Store 中,通过 STS 动态获取。

总结

CloudFront 自定义 Header 配合 ALB 监听规则和 Security Group,是防止源站被直接访问的有效手段。三者配合实现了一个成本低、实施简单的纵深防御方案,适合中小型 Web 应用的源站保护场景。

本文由作者按照 CC BY 4.0 进行授权

AWS Secrets Manager 与 Parameter Store 选型指南

OpenCode Go 订阅接入 Claude CLI & Claude Desktop & IDE 扩展