发布于5小时前5小时 背景网站接入 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 一致性以及日志证据链。修复时优先收紧网络入口,再规范代理地址解析和日志字段,这样既能降低绕过风险,也能在出现异常时还原真实请求路径。 服务器、云资产与权限边界梳理示意 网络请求、日志与边界流量分析示意
5小时前5小时 这类排查建议把“源站是否可直连”和“客户端 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 请求应正常,公网直连应在网络层被拒绝,而不是返回一个可识别源站的软件错误页。
创建帐户或登录后发表意见