发布于2小时前2小时 背景网站接入 CDN、WAF 或反向代理后,常见链路是“客户端 → CDN/WAF → Nginx → 应用”。这类架构既承担加速,也改变了客户端 IP 的获取方式。如果源站仍可被公网直连,或 Nginx、应用无条件信任 X-Forwarded-For,就可能出现后台 IP 白名单绕过、限速失效、审计日志失真等问题。下面以已获授权的测试环境为例,排查两个具体问题:源站是否只能由 CDN 回源节点访问,以及业务使用的客户端 IP 是否来自可信代理链。问题定位测试前先向运维确认域名、源站测试地址、CDN 回源网段和允许的测试时间,不要通过扫描第三方网段猜测源站。假设测试信息如下:业务域名:demo.example.com测试源站:203.0.113.10管理入口:/admin预期策略:源站 443 端口只允许 CDN 节点访问,管理入口不能单独依赖客户端 IP 完成认证重点检查以下现象:使用源站 IP 配合正确 Host 或 SNI,可以绕过 CDN 直接访问业务。修改 X-Forwarded-For 后,/admin 的状态码、页面长度或跳转位置发生变化。访问日志只记录伪造后的地址,无法还原实际 TCP 对端。限速、地域判断和后台白名单读取了未经规范化的请求头。授权环境下的验证步骤先记录通过 CDN 正常访问时的基线响应,再添加伪造请求头。这里只比较状态码和响应头,避免对业务执行修改操作。# 1. 通过 CDN 获取基线 curl -skI # 2. 注入常见的本地或内网地址,观察响应是否变化 curl -skI \ -H 'X-Forwarded-For: 127.0.0.1' curl -skI \ -H 'X-Forwarded-For: 10.10.10.10' # 3. 已知且已获授权的源站地址,保留域名对应的 TLS SNI curl -skI --resolve demo.example.com:443:203.0.113.10 \ # 4. 输出便于比较的关键字段 curl -sk -o /dev/null \ -w 'code=%{http_code} size=%{size_download} redirect=%{redirect_url}\n' \ \ -H 'X-Forwarded-For: 127.0.0.1'如果第三项能够直接返回正常业务页面,说明“隐藏源站”只停留在 DNS 层,未形成网络访问控制。如果第二项使原本的 401 或 403 变为 200,通常说明代理头参与了权限判断,并且信任边界配置不正确。验证时应使用只读请求和专用测试账号。发现权限变化后即可停止,不需要继续进入后台或读取业务数据。技术分析:X-Forwarded-For 不能直接视为客户端地址X-Forwarded-For 是普通 HTTP 请求头,客户端可以主动提交。可信代理通常会在转发时追加地址,因此它可能形成一个地址链。安全处理的前提不是“取第一个”或“取最后一个”,而是明确哪些 TCP 对端属于可信代理,再从右向左剥离可信节点。常见错误配置如下:# 错误示例:等于信任任意来源提交的代理头 set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; real_ip_recursive on;另一类问题出现在应用层。例如直接读取 X-Forwarded-For 的第一个值,再用于后台白名单:# 风险逻辑示意 client_ip = request.headers.get('X-Forwarded-For', request.remote_addr).split(',')[0] if client_ip in admin_allowlist: allow_admin()即使 Nginx 配置正确,应用再次解析原始请求头,也会绕过 Nginx 已完成的地址规范化。应用应读取反向代理传递的、经过信任链计算后的连接地址,并且后台认证不能只依赖 IP。Nginx 排查与日志留痕先查看实际加载的完整配置,避免只检查某个配置文件而遗漏 include 内容。sudo nginx -T 2>&1 | grep -nE \ 'set_real_ip_from|real_ip_header|real_ip_recursive|proxy_set_header|log_format|allow|deny|limit_req_zone' # 检查 Nginx 是否编译或动态加载 realip 模块 nginx -V 2>&1 | grep -o 'http_realip_module'建议同时记录规范化后的客户端地址、实际 TCP 对端和原始代理头。这样既能判断配置结果,也能发现绕过 CDN 的直连请求。log_format proxy_audit escape=json '{"time":"$time_iso8601",' '"client":"$remote_addr",' '"peer":"$realip_remote_addr",' '"xff":"$http_x_forwarded_for",' '"host":"$host",' '"request":"$request",' '"status":$status,' '"request_id":"$request_id"}'; access_log /var/log/nginx/proxy_audit.log proxy_audit;其中 remote_addr 是 Real IP 模块处理后的客户端地址,realip_remote_addr 保留原始连接地址。若 peer 不是 CDN 网段却能获得正常业务响应,应优先检查源站防火墙和旁路入口。# 查看最近请求,按实际环境安装 jq 或直接读取原始日志 sudo tail -n 200 /var/log/nginx/proxy_audit.log | jq -c \ '{time,client,peer,xff,host,status,request_id}' # 统计直接连接源站的对端地址 sudo jq -r '.peer' /var/log/nginx/proxy_audit.log \ | sort | uniq -c | sort -nr | head正确配置可信代理边界set_real_ip_from 只能填写当前实际使用的 CDN 或负载均衡节点网段,不能使用全网段。下面的地址仅为文档示例,部署时应替换为厂商正式发布并定期同步的回源网段。# /etc/nginx/conf.d/trusted-proxy.conf 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; # 限速应在 Real IP 处理后使用规范化地址 limit_req_zone $binary_remote_addr zone=per_client:10m rate=10r/s; server { listen 443 ssl default_server; server_name _; return 444; } server { listen 443 ssl; server_name demo.example.com; location / { limit_req zone=per_client burst=20 nodelay; proxy_set_header Host $host; proxy_set_header X-Request-ID $request_id; proxy_pass } }配置修改后先执行语法检查,再平滑加载:sudo nginx -t && sudo systemctl reload nginx sudo systemctl status nginx --no-pager sudo tail -n 50 /var/log/nginx/error.log如果链路中还有云负载均衡、Ingress 或服务网格,需要把每一跳都画出来,并分别确认请求头是覆盖、追加还是原样透传。不能机械复制其他环境的 trusted proxy 配置。源站访问控制Nginx 的 Host 校验只能减少错误路由,不能替代网络层限制。更可靠的做法是在云安全组、防火墙或上游 ACL 中,仅允许 CDN 回源网段访问源站的 80、443 端口。运维管理流量应通过 VPN、堡垒机或独立管理网进入。实施限制前,需要单独梳理健康检查、证书验证、监控探针和灾备节点,避免误封正常链路。CDN 网段发生变化时,应通过受控任务更新规则,并保留变更记录和失败回滚。风险判断与修复优先级发现主要影响修复优先级源站可公网直连绕过 CDN/WAF、流量防护和边缘访问策略高信任 0.0.0.0/0 的代理头客户端 IP 可伪造,影响白名单、限速和审计高应用直接解析 X-Forwarded-For代理层规范化失效,多组件判断不一致高日志只记录处理后的地址难以区分 CDN 回源与源站直连中后台仅依赖 IP 白名单代理误配或办公网失陷后缺少第二道认证高修复顺序建议是:先限制源站入口,再收紧可信代理网段,然后统一应用取 IP 的方式,最后补齐日志告警。后台入口应保留账号认证、多因素认证和最小权限控制,IP 白名单只作为附加条件。回归验证通过 CDN 正常访问,日志中的 peer 属于 CDN 网段,client 为测试终端出口地址。客户端自带 X-Forwarded-For 不会改变后台授权结果。从非 CDN 网络直连源站时,由安全组丢弃或明确拒绝连接。未知 Host 命中默认虚拟主机,不返回真实业务内容。限速键使用规范化后的客户端地址,不会把全部用户聚合到 CDN 节点地址。日志平台可同时检索 client、peer、xff 和 request_id,并对异常 peer 触发告警。总结CDN 加速并不天然等于源站隐藏。真正有效的边界由源站网络 ACL、可信代理网段、Real IP 处理、应用认证和可追溯日志共同组成。排查时不要只看页面是否经过 CDN,而要验证“谁可以连接源站”“哪个组件有权声明客户端 IP”“权限判断最终使用了哪个地址”。这三个问题确认清楚,才能避免加速链路反过来成为权限绕过和审计失真的入口。 网络请求、日志与边界流量分析示意 服务器、云资产与权限边界梳理示意
43分钟前43分钟 这类问题建议分开验证“源站是否能被绕过”和“源站是否会信任伪造的客户端 IP”。先用实际源站 IP 保持域名和 TLS SNI 不变,检查能否直连: curl -sS -D- --resolve \ -o /dev/null 把示例 IP 换成自有源站地址;若直连能返回正常业务内容,即使 DNS 已指向 CDN,也仍存在绕过入口。核对历史 DNS、遗留 A/AAAA 记录和暴露在其他服务配置中的源站地址后,优先在安全组或主机防火墙上限制源站仅接受 CDN 回源网段;管理和健康检查流量单独放行。默认虚拟主机也应拒绝未知 Host,避免直连时落到业务站点。 客户端 IP 则要在源站只信任 CDN 网段提供的头,不能仅凭请求里出现 X-Forwarded-For 就认定可信。以 Nginx 和 CDN 的官方回源网段为例: # 将网段替换为 CDN 官方公布并定期更新的回源地址 set_real_ip_from 192.0.2.0/24; real_ip_header CF-Connecting-IP; real_ip_recursive on; log_format edge '$remote_addr peer=$realip_remote_addr ' '"$request" status=$status'; 如果用的是 X-Forwarded-For,要确认 CDN 如何追加或覆盖该头,并只把可信代理网段纳入解析链。最后从 CDN 正常访问时发送一个自造的转发头做验证,确认边缘会覆盖或安全处理它;同时检查日志里的客户端地址和直接连接对端地址是否符合预期。
创建帐户或登录后发表意见