发布于5小时前5小时 背景:加速正常,不代表源站边界正确网站接入 CDN 或反向代理后,页面访问通常没有问题,但服务器侧容易留下三个配置缺口:源站仍允许公网直连;Nginx 将用户提交的请求头当成真实 IP;应用、限流和日志使用了不同的客户端地址。这些问题不需要复杂的漏洞利用就能暴露。一次授权上线检查中,只要分别测试“经 CDN 访问”和“直连源站访问”,往往就能发现边界不一致。本文围绕网站建设和服务器运维,给出一套可复核的检查方法,不涉及绕过第三方站点防护。假设链路为:访客 → CDN → Nginx 源站 → 本机应用。应用监听 127.0.0.1:8080,HTTPS 在 Nginx 终止。下文域名与 IP 均为文档示例,操作时替换为自己有权限测试的资源。一、问题定位:先分清连接地址和业务地址在未启用 realip 模块时,Nginx 的 $remote_addr 通常是 CDN 回源节点地址。启用并正确配置信任关系后,它才可能被替换为客户端地址。原始连接对端可通过 $realip_remote_addr 保留。$remote_addr:经过 realip 处理的客户端地址,可供应用和限流使用。$realip_remote_addr:实际与源站建立连接的对端,用于核查回源路径。$http_x_forwarded_for:收到的原始请求头,只能作为排查材料,不能直接当作可信身份。常见错误是配置 set_real_ip_from 0.0.0.0/0;。这相当于允许任意连接方参与声明客户端 IP。若源站可以直连,攻击者便可能影响日志、IP 限流或基于 IP 的业务判断。二、技术分析:可信地址必须有明确的生产者正确的信任关系不是“请求头里写了什么就相信什么”,而是“只有受信代理发来的指定字段才允许参与地址解析”。至少要同时确认以下两项:源站只信任当前 CDN 的实际回源地址段,不能因为某个网段属于云厂商就整体放行。CDN 对转发地址头的处理有明确约定:覆盖、追加,还是使用专有客户端地址头。不能凭字段名称猜测。下面配置假设 CDN 使用 X-Forwarded-For,并保证将实际客户端地址追加到链尾。real_ip_recursive on 会依据可信代理列表寻找最后一个非可信地址。若服务商要求使用专有头,应按其回源文档调整,不能直接照搬这套假设。三、操作步骤:先加观测,再改信任先检查模块和现有配置,确认有没有旧的全网信任配置、重复的转发头设置,以及额外的公网监听端口。nginx -T 可能输出证书路径、内部域名等信息,不要直接贴到公开论坛。nginx -V 2>&1 | grep -- --with-http_realip_module sudo nginx -T 2>&1 | grep -nE 'set_real_ip_from|real_ip_header|real_ip_recursive|proxy_set_header|listen' sudo ss -lntp下面片段放在 Nginx 的 http 上下文中。其中 192.0.2.0/24 只是文档网段,必须替换为服务商公布并确认用于回源的真实地址段,同时覆盖实际使用的 IPv6 回源地址。# 示例占位,不能直接用于生产。 set_real_ip_from 192.0.2.0/24; real_ip_header X-Forwarded-For; real_ip_recursive on; log_format origin_audit escape=json '{"time":"$time_iso8601",' '"request_id":"$request_id",' '"client":"$remote_addr",' '"peer":"$realip_remote_addr",' '"xff":"$http_x_forwarded_for",' '"host":"$host",' '"uri":"$uri",' '"status":$status,' '"upstream":"$upstream_addr"}';在已有 HTTPS 虚拟主机中启用该日志,并向本机应用传递归一化地址。这里有意不继续追加用户提供的 X-Forwarded-For,而是向单一应用上游发送源站确认后的地址,降低应用解析多级代理链时出错的概率。# 合并到现有 server 中,保留原有证书及 TLS 配置。 access_log /var/log/nginx/origin_audit.log origin_audit; location / { proxy_pass proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Request-ID $request_id; }应用也要同步调整:只信任本机 Nginx,统一使用约定的地址字段,不要再从其他客户端可提交的头中挑选 IP。应用端口应只监听回环地址,避免用户绕开 Nginx 直接提交伪造头。以上协议设置以 CDN 到源站同样使用 HTTPS 为前提。如果回源走 HTTP,$scheme 就是 http,不能用它表示访客侧协议;需要另行确认 CDN 的可信协议字段。sudo nginx -t && sudo systemctl reload nginx sudo tail -f /var/log/nginx/origin_audit.log四、验证方法:正常访问与伪造头必须一起测在自己控制的测试终端执行下面三组请求。测试路径应提前配置为无副作用、不可缓存的检查端点,避免 CDN 缓存命中导致源站没有日志。查询参数仅用于标记测试,不保证所有 CDN 都会因此绕过缓存。# 1. 正常经 CDN 访问。 curl -sS -o /dev/null -w '%{http_code}\n' \ ' # 2. 经 CDN 提交伪造地址,检查是否影响源站判定。 curl -sS -o /dev/null -w '%{http_code}\n' \ -H 'X-Forwarded-For: 198.51.100.77' \ ' # 3. 绕过 DNS 直连自己的源站,保留正确的 Host 与 TLS SNI。 curl --connect-timeout 5 \ --resolve \ ' -k 掩盖证书错误。若源站使用仅供 CDN 验证的私有 CA,应通过 --cacert 提供正确的信任链。证书验证失败本身不能证明源站已经限制公网访问。正常请求:peer 应属于受信回源网段,client 应为测试终端的实际出口地址。伪造头请求:client 不应变成 198.51.100.77。原始 xff 中可能仍出现该值,但它不能影响业务身份。源站直连:完成网络收口后,非受信公网终端应无法访问业务。若仍能正常返回内容,说明还有直连入口。如果多名用户的 client 都是同一个 CDN 地址,优先检查回源网段是否遗漏、头字段是否选错,以及 CDN 前面是否还存在另一层代理。不要为了让日志“看起来正常”而扩大信任范围。五、风险与修复建议:源站收口不能只靠请求头在网络层限制业务端口。通过安全组或防火墙,仅允许 CDN 回源地址访问源站 443;80 端口如无必要应关闭,如需保留,也要明确证书续期和回源用途。SSH 单独限制为运维出口,不要套用业务规则。覆盖所有入口。检查 IPv6、备用公网 IP、8080/8443 等历史端口。只限制主域名解析没有意义,知道源站地址的人仍可能直连。注意 realip 对访问控制的影响。启用后,Nginx 的地址访问控制通常面对的是改写后的客户端地址。不要把“只允许 CDN 网段”的 allow/deny 规则机械地放进同一配置,优先在连接层完成回源限制。共享回源网段不是专属身份。允许 CDN 地址只能证明连接来自该服务商网络。若需要确认请求来自自己的 CDN 配置,应进一步使用服务商支持的回源双向 TLS、私有回源链路或等效认证机制。更新网段要可回滚。从官方来源获取并审核回源列表;更新前校验规则,保留带外管理通道,避免误封业务或运维入口。日志按需保留。示例使用 JSON 转义,并仅记录 URI 路径,不记录查询串、Cookie 或 Authorization。完整转发链仍属于可控输入和个人数据,排查结束后应评估是否继续保留。总结网站加速上线验收,不应止于页面能打开。至少要留下三项可重复的证据:普通公网不能直连源站业务入口;伪造地址头不能改变应用识别结果;Nginx 和应用日志能够通过请求 ID 对齐。把这些检查放进部署清单,比故障或安全事件发生后再猜测请求经过了哪一层更可靠。 服务器、云资产与权限边界梳理示意 网络请求、日志与边界流量分析示意
创建帐户或登录后发表意见