跳转到帖子

咖啡馆实战:网站接入 CDN 后的源站暴露、代理信任与日志留痕排查

精选回复

发布于

背景

网站接入 CDN、WAF 或反向代理后,常见误区是把“域名已经走 CDN”当成“源站已经隐藏”。在授权渗透测试中,经常能看到三类边界问题:源站仍可被公网直接访问、应用无条件信任客户端提交的 X-Forwarded-For、源站日志只记录代理节点地址。

这些问题会削弱访问控制与审计能力。例如管理后台虽然在 CDN 上配置了 IP 白名单,但攻击者如果能够直连源站,就可能绕过边缘策略;如果限速逻辑直接读取未经校验的代理头,还可能被伪造地址干扰。

以下检查应仅针对已获授权的域名、IP 和服务器进行。验证重点是确认配置边界,不进行高并发探测或破坏性操作。

问题定位

假设站点架构为“客户端 → CDN/WAF → Nginx → 应用”,测试时先核对以下信息:

  • 当前业务域名解析到哪些 CDN 地址,源站公网地址是否仍有必要保留。
  • 源站安全组是否只允许 CDN 回源网段和运维出口地址。
  • Nginx 是否仅信任明确的代理网段,而不是信任任意来源的转发头。
  • 应用鉴权、限速和审计使用的是哪个客户端地址变量。
  • 访问日志是否同时保留 TCP 对端地址、原始转发头和解析后的客户端地址。

授权验证步骤

先记录通过业务域名访问时的响应特征,包括状态码、证书、Server 头、响应长度和一个稳定的页面摘要。随后仅对资产清单中确认属于该项目的源站地址进行定向验证。使用 resolve 固定连接目标,可避免修改本机 hosts。

# 通过正常域名访问
curl -skD /tmp/cdn.headers -o /tmp/cdn.body \
  

# 在授权范围内,将同一域名定向到已知源站地址
curl -skD /tmp/origin.headers -o /tmp/origin.body \
  --resolve  \
  

# 对比状态码、关键响应头和正文摘要
sed -n '1,20p' /tmp/cdn.headers
sed -n '1,20p' /tmp/origin.headers
sha256sum /tmp/cdn.body /tmp/origin.body

如果源站直连能够返回完整业务页面,不代表一定存在漏洞,但至少说明边缘 WAF、访问频率限制、地理封禁等控制可能不是唯一入口。还应检查源站是否对未知 Host 返回默认站点,避免同机其他虚拟主机泄露。

代理头信任边界分析

X-Forwarded-For 只是 HTTP 请求头,客户端可以自行提交。只有请求确实来自受信任代理时,服务端才能使用该头推导真实客户端地址。Nginx 的 realip 模块应明确限定可信代理网段,并使用递归解析处理多级代理链。

# /etc/nginx/conf.d/realip.conf
# 以下仅为文档示例网段,部署时替换为 CDN 官方公布并定期同步的回源网段
set_real_ip_from 192.0.2.0/24;
set_real_ip_from 2001:db8:100::/48;

real_ip_header X-Forwarded-For;
real_ip_recursive on;

不建议配置 set_real_ip_from 0.0.0.0/0。该配置等同于相信所有访问者提供的 X-Forwarded-For,容易影响后台白名单、限速、风控和日志审计。

在测试环境中,可分别发送普通请求与带伪造代理头的请求,然后检查应用日志中的 remote_addr、realip_remote_addr 和转发头。若请求并非来自可信代理,解析后的客户端地址不应变成伪造值。

# 仅用于自有测试环境验证日志行为
curl -sk 
curl -sk -H 'X-Forwarded-For: 198.51.100.77' \
  

# 检查配置语法并平滑加载
nginx -t && nginx -s reload

日志留痕配置

排障时不要只记录 $remote_addr。启用 realip 后,该变量可能已经被替换为解析后的客户端地址,而 TCP 直连对端可通过 $realip_remote_addr 保留。建议同时记录两者以及原始转发头,便于判断请求经过了哪一层代理。

log_format edge_audit escape=json
  '{'
  '"time":"$time_iso8601",'
  '"request_id":"$request_id",'
  '"peer_ip":"$realip_remote_addr",'
  '"client_ip":"$remote_addr",'
  '"xff":"$http_x_forwarded_for",'
  '"host":"$host",'
  '"request":"$request",'
  '"status":$status,'
  '"bytes":$body_bytes_sent,'
  '"referer":"$http_referer",'
  '"ua":"$http_user_agent",'
  '"rt":$request_time'
  '}';

access_log /var/log/nginx/edge_audit.log edge_audit;

如果 CDN 提供带签名的客户端地址头,仍需确认源站只接受来自 CDN 回源地址的连接。单独检查某个请求头是否存在并不能证明请求经过了 CDN,因为该头同样可能被客户端构造。

源站访问控制

优先在云安全组、网络 ACL 或主机防火墙层限制回源,而不是只在应用中判断。下列 nftables 片段展示基本思路:先允许已建立连接、运维出口及 CDN 回源网段,再拒绝其他来源访问业务端口。上线前应在控制台保留带外连接,避免误封管理通道。

table inet filter {
  set trusted_origin_peers_v4 {
    type ipv4_addr
    flags interval
    elements = { 192.0.2.0/24, 198.51.100.20 }
  }

  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iifname "lo" accept
    ip saddr @trusted_origin_peers_v4 tcp dport { 80, 443 } accept
    ip saddr 198.51.100.20 tcp dport 22 accept
    counter log prefix "origin-deny " limit rate 10/second drop
  }
}

实际部署还要补充 IPv6 规则。很多环境只限制 IPv4,却保留了可公网访问的 AAAA 记录或源站 IPv6 地址,最终仍能绕过边缘入口。

排查证据与判定

检查项正常表现风险表现
源站直连连接被拒绝,或仅允许受信代理公网任意地址可获得完整业务响应
未知 Host返回 444、403 或空默认站点暴露其他虚拟主机或默认管理页
伪造 X-Forwarded-For非可信来源不会改变 client_ip任意客户端可控制鉴权使用的地址
访问日志同时保留 peer_ip、client_ip、xff 和 request_id只记录代理节点,无法回溯请求链路
IPv6 边界与 IPv4 使用一致的回源限制AAAA 或源站 IPv6 可被公网直连

风险与修复建议

  • 在安全组或防火墙中仅允许 CDN/WAF 官方回源网段访问 80、443,并建立网段变更同步机制。
  • 为源站配置独立回源证书,条件允许时启用双向 TLS,避免仅依赖来源 IP。
  • 默认虚拟主机拒绝未知 Host,业务虚拟主机显式声明 server_name。
  • realip 模块只信任明确代理网段,不使用全网信任配置。
  • 后台白名单、限速与风控统一读取经过可信代理链解析后的地址,同时保留 TCP 对端地址。
  • 日志携带 request_id,并让 CDN、Nginx 与应用层透传同一标识,便于关联排查。
  • 修改防火墙前备份规则、保留带外管理入口,并先在灰度源站验证健康检查与回源是否正常。

总结

CDN 加速解决的是分发与边缘防护问题,并不会自动建立可靠的源站权限边界。一次完整的授权检查应同时覆盖源站网络暴露、Host 处理、代理头信任、IPv4/IPv6 一致性以及日志证据链。修复时优先收紧网络入口,再规范代理地址解析和日志字段,这样既能降低绕过风险,也能在出现异常时还原真实请求路径。

服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意
网络流量与边界分析示意图
网络请求、日志与边界流量分析示意

这类排查建议把“源站是否可直连”和“客户端 IP 是否可信”分开验证。接了 CDN 不等于源站自动隐藏,尤其要同时检查历史 DNS、IPv6、旁路端口和证书信息。

1. 先确认源站是否还能绕过 CDN

拿疑似源站 IP 配合正确的 Host/SNI 直接请求,不能只访问 IP 首页:

curl -vk --resolve example.com:443:203.0.113.10 
curl -v  --resolve example.com:80:203.0.113.10  

# IPv6 也要单独测
curl -6vk --resolve example.com:443:[2001:db8::10] 

如果返回内容、证书、响应头或错误页与生产站一致,基本可以确认存在直连路径。除当前 A/AAAA 记录外,还应检查旧解析记录、邮件子域、测试域名,以及 8080、8443 等旁路端口。

修复重点应放在源站入站策略,而不是仅靠隐藏 IP:防火墙只允许 CDN 官方地址段访问 80/443;更稳妥的做法是再加一层源站认证,例如 CDN 回源 mTLS 或不可伪造的回源认证头。认证头不能作为唯一措施,因为一旦泄露仍可被复用。

# nftables 示例,实际使用时应自动同步 CDN 地址段
nft add set inet filter cdn_v4 '{ type ipv4_addr; flags interval; }'
nft add element inet filter cdn_v4 '{ 198.51.100.0/24 }'
nft add rule inet filter input tcp dport '{ 80, 443 }' ip saddr @cdn_v4 accept
nft add rule inet filter input tcp dport '{ 80, 443 }' drop

2. 代理信任不要写成“信任所有来源”

常见问题是应用直接读取 X-Forwarded-For,或者 Nginx 配了 set_real_ip_from 0.0.0.0/0。这样攻击者只要能直连源站,就能伪造客户端 IP,影响限速、审计和后台 IP 白名单。

Nginx 应只信任 CDN 出口网段,并按 CDN 实际提供的请求头配置:

# 仅示例,网段和头名称以所用 CDN 官方文档为准
set_real_ip_from 198.51.100.0/24;
set_real_ip_from 2001:db8:1234::/48;

real_ip_header X-Forwarded-For;
real_ip_recursive on;

如果 CDN 提供单值客户端地址头,优先使用该头,链式 X-Forwarded-For 更容易因代理层级配置错误产生歧义。应用框架中的 trust proxy 也应限制到明确代理网段或固定跳数,不能直接全开。

可以用下面的请求检查源站是否错误信任外部传入头:

curl -vk --resolve example.com:443:203.0.113.10 \
  -H 'X-Forwarded-For: 127.0.0.1, 10.0.0.8' \
  -H 'X-Real-IP: 127.0.0.1' \
  

测试时观察应用日志、限速键和后台访问控制使用的是哪个地址。不要只看回显页面,因为应用、中间件和网关可能分别解析出不同结果。

3. 日志同时保留连接地址与解析后的客户端地址

只记录 $remote_addr 会在启用 realip 模块后丢失实际连接到源站的 CDN 节点地址。建议同时记录:

log_format origin_audit escape=json
  '{"time":"$time_iso8601",'
  '"request_id":"$request_id",'
  '"peer_ip":"$realip_remote_addr",'
  '"client_ip":"$remote_addr",'
  '"xff":"$http_x_forwarded_for",'
  '"host":"$host",'
  '"request":"$request",'
  '"status":$status,'
  '"bytes":$body_bytes_sent,'
  '"referer":"$http_referer",'
  '"ua":"$http_user_agent",'
  '"upstream":"$upstream_addr",'
  '"upstream_time":"$upstream_response_time"}';

access_log /var/log/nginx/origin_audit.log origin_audit;

其中 peer_ip 用于确认请求是否确实来自 CDN,client_ip 用于业务审计,原始转发头用于事后复核。最好由边缘层生成请求 ID,并一路传到源站和应用日志;不要直接信任客户端提交的请求 ID,至少要覆盖或校验格式。

排查历史日志时,可以先找不属于 CDN 网段的直连来源,再对比异常 Host、伪造转发头和状态码:

# JSON 日志示例
jq -r 'select(.peer_ip != null) |
  [.time,.peer_ip,.client_ip,.host,.status,.xff,.request_id] | @tsv' \
  /var/log/nginx/origin_audit.log

最后还要检查 CDN 到源站是否启用了严格证书校验。仅使用“灵活 SSL”或不校验回源证书,即使入口限制正确,也可能留下链路劫持和错误回源风险。完成修改后,分别从 CDN、普通公网主机和 IPv6 网络复测:CDN 请求应正常,公网直连应在网络层被拒绝,而不是返回一个可识别源站的软件错误页。

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。

SiteMap HACKHAT © 2026 All rights reserved.