You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为AWS托管内部CloudFront的API添加HSTS安全头方案咨询

解决方案:为Edge-Optimized API Gateway添加HSTS等安全头

核心限制说明

Edge-Optimized API Gateway自动创建的CloudFront分发由AWS托管,用户无法直接通过Terraform修改该分发的响应头策略——因为这个分发不在你的Terraform状态管理范围内,也不允许直接编辑其配置。

可行解决方案

方案1:改用自定义域名 + 自行管理CloudFront分发(推荐)

这是最可控的方案,完全通过Terraform管理整个链路,步骤如下:

  1. 为API Gateway创建自定义域名,获取其区域目标域名;
  2. 自行创建CloudFront分发,将源指向API Gateway的自定义域名目标;
  3. 创建CloudFront响应头策略,配置HSTS、XSS保护等安全头;
  4. 将响应头策略关联到CloudFront的缓存行为中。

Terraform代码示例:

# 创建CloudFront响应头策略
resource "aws_cloudfront_response_headers_policy" "security_headers" {
  name = "api-security-headers"

  strict_transport_security {
    access_control_max_age_sec = 31536000
    include_subdomains         = true
    preload                    = true
    override                   = true
  }

  xss_protection {
    mode_block = true
    protection = true
    override   = true
  }

  content_security_policy {
    content_security_policy = "default-src 'self'; script-src 'self'"
    override                = true
  }

  # 可按需添加其他安全头,如X-Frame-Options、X-Content-Type-Options等
}

# 创建CloudFront分发,关联API Gateway自定义域名
resource "aws_cloudfront_distribution" "api_distribution" {
  enabled             = true
  is_ipv6_enabled     = true

  origin {
    domain_name = aws_api_gateway_domain_name.api_custom.regional_domain_name
    origin_id   = "api-gateway-origin"

    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "https-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }
  }

  default_cache_behavior {
    target_origin_id       = "api-gateway-origin"
    viewer_protocol_policy = "redirect-to-https"

    response_headers_policy_id = aws_cloudfront_response_headers_policy.security_headers.id

    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
    cached_methods   = ["GET", "HEAD"]
  }

  # 配置自定义域名证书与TLS版本
  viewer_certificate {
    acm_certificate_arn = aws_acm_certificate.api_cert.arn
    ssl_support_method   = "sni-only"
    minimum_protocol_version = "TLSv1.2"
  }
}

方案2:直接在API Gateway层面配置响应头

如果不想更换CloudFront分发,可以在API Gateway的方法响应或集成响应中添加安全头,CloudFront会自动转发这些头到客户端。

Terraform代码示例(为单个API方法配置安全头):

# 在方法响应中声明要返回的安全头
resource "aws_api_gateway_method_response" "example" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  resource_id = aws_api_gateway_resource.example.id
  http_method = aws_api_gateway_method.example.http_method
  status_code = "200"

  response_parameters = {
    "method.response.header.Strict-Transport-Security" = true
    "method.response.header.X-XSS-Protection" = true
  }
}

# 在集成响应中设置头的具体值
resource "aws_api_gateway_integration_response" "example" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  resource_id = aws_api_gateway_resource.example.id
  http_method = aws_api_gateway_method.example.http_method
  status_code = aws_api_gateway_method_response.example.status_code

  response_parameters = {
    "method.response.header.Strict-Transport-Security" = "'max-age=31536000; includeSubDomains; preload'"
    "method.response.header.X-XSS-Protection" = "'1; mode=block'"
  }
}

注意:这种方式需要为每个API方法单独配置,适合API数量较少的场景。

方案3:使用Lambda@Edge添加安全头

通过Lambda@Edge在CloudFront的响应阶段注入安全头,无需更换现有域名:

  1. 创建部署在us-east-1区域的Lambda函数,在origin-response事件中添加安全头;
  2. 将Lambda函数关联到API Gateway自动创建的CloudFront分发上。

Lambda函数代码示例(Node.js):

exports.handler = (event, context, callback) => {
  const response = event.Records[0].cf.response;
  const headers = response.headers;

  // 添加HSTS头
  headers['strict-transport-security'] = [{
    key: 'Strict-Transport-Security',
    value: 'max-age=31536000; includeSubDomains; preload'
  }];

  // 添加XSS保护头
  headers['x-xss-protection'] = [{
    key: 'X-XSS-Protection',
    value: '1; mode=block'
  }];

  callback(null, response);
};

Terraform代码示例(部署Lambda@Edge并关联到CloudFront):

# 获取API Gateway自动创建的CloudFront分发(通过执行域名查找)
data "aws_cloudfront_distribution" "api_gateway_dist" {
  domain_name = aws_api_gateway_rest_api.example.execute_api_domain_name
}

# 创建Lambda函数(必须部署在us-east-1区域)
resource "aws_lambda_function" "security_headers_edge" {
  filename      = "lambda.zip"
  function_name = "api-security-headers-edge"
  role          = aws_iam_role.lambda_edge_role.arn
  handler       = "index.handler"
  runtime       = "nodejs18.x"
  region        = "us-east-1"
}

# 关联Lambda到CloudFront的origin-response事件
resource "aws_cloudfront_distribution_association" "lambda_edge" {
  distribution_id = data.aws_cloudfront_distribution.api_gateway_dist.id
  event_type      = "origin-response"
  lambda_arn      = "${aws_lambda_function.security_headers_edge.arn}:${aws_lambda_function.security_headers_edge.version}"
}

注意:需要为Lambda配置允许CloudFront调用的IAM权限。

可行性总结

  • 方案1:完全可行,是长期维护的最优解,代价是需要切换到自定义域名;
  • 方案2:可行,适合快速验证或API数量少的场景,但配置繁琐;
  • 方案3:可行,无需更换域名,但需要管理Lambda@Edge的部署和权限。

内容的提问来源于stack exchange,提问作者Ahad Mammadov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:57:53