发布于1小时前1小时 背景:加速生效,不等于源站受到保护在一次授权的网站部署检查中,站点通过 CDN 对外提供服务,源站运行 Nginx,应用只监听本机端口。页面访问和证书都正常,但用域名绑定源站 IP 后,仍能直接访问业务。这意味着请求可以绕过 CDN 上的限速、访问规则和部分安全检查。这类问题首先是网站建设和服务器配置问题,不需要扫描大量接口。本文用一个最小部署说明如何验证源站入口、收紧回源权限,并保留能定位问题的日志。所有地址均为文档示例地址,执行时只替换为自己管理或明确授权的资产。网站域名:site.example。源站地址:198.51.100.20。示例回源节点:192.0.2.10。应用监听:127.0.0.1:8080。问题定位:先区分三个信任边界访问入口:源站是否只接受可信回源节点,而不是整个互联网?业务来源:请求是否确实来自自己的 CDN 配置,而不只是同一家 CDN 的某个共享节点?客户端身份:Nginx 是否只信任可信代理写入的客户端 IP 信息?这三个问题不能只靠一条 IP 白名单解决。共享 CDN 的回源网段只能证明连接来自该服务商,不能单独证明请求属于本站;而客户端自己提交的 X-Forwarded-For,也不能直接当作真实来源。验证方法:保持 Host 和 TLS SNI 一致不要只访问 curl 的 --resolve,可以连接指定地址,同时保留正确的域名、Host 和 TLS SNI。# 通过正常 DNS 访问,观察 CDN 链路 curl -sS -D - -o /dev/null # 直连授权源站,仍使用站点域名进行 TLS 和 HTTP 请求 curl --noproxy '*' --resolve site.example:443:198.51.100.20 \ --connect-timeout 5 -sS -D - -o /dev/null \ # 检查应用端口是否只监听回环地址 ss -lntp | grep ':8080'如果直连得到业务页面,说明这条入口确实可用。但返回 403、404 也不能直接算通过:要结合源站日志确认,是入口策略拒绝了请求,还是应用碰巧拒绝了当前路径。若源站使用 CDN 专用 CA 签发的证书,应使用对应的 --cacert 验证,不要把证书错误当成访问控制生效。技术分析:恢复客户端 IP 后,连接来源可能被混淆Nginx 启用 realip 模块后,$remote_addr 可以被替换为代理传入的客户端地址。因此,用它判断“连接是不是来自 CDN”容易出现逻辑错误。$remote_addr:经过可信代理解析后,用于业务审计的客户端地址。$realip_remote_addr:realip 模块保留的原始连接对端地址,适合检查直接连接源站的是谁。另一个常见错误是配置 set_real_ip_from 0.0.0.0/0。这相当于允许任何连接者参与声明客户端地址,可能污染审计记录,以及依赖来源 IP 的访问控制或限流。操作步骤:回源地址与站点凭据同时校验优先在云安全组或主机防火墙上限制 443 端口,只允许实际回源网段。下面的 Nginx 配置作为第二层保护:同时检查原始连接对端、站点回源凭据和域名。CDN 需要在回源时覆盖写入 X-Origin-Verify,不能仅在浏览器没有提交该头时补充。示例要求 Nginx 编译了 http_realip_module,可通过 nginx -V 查看。以下内容放在 http 上下文中;证书路径和占位凭据必须替换。192.0.2.10/32 只是示例,生产环境应使用服务商公布的实际回源网段,并建立更新机制。# http 上下文 set_real_ip_from 192.0.2.10/32; real_ip_header X-Forwarded-For; real_ip_recursive on; # 按原始 TCP 对端判断,不使用改写后的客户端地址 geo $realip_remote_addr $edge_peer_ok { default 0; 192.0.2.10/32 1; } map $http_x_origin_verify $origin_key_ok { default 0; "REPLACE_WITH_RANDOM_ORIGIN_SECRET" 1; } map $host $origin_host_ok { default 0; site.example 1; } map "$edge_peer_ok:$origin_key_ok:$origin_host_ok" $origin_allowed { default 0; "1:1:1" 1; } log_format origin_audit escape=json '{"time":"$time_iso8601","rid":"$request_id",' '"peer":"$realip_remote_addr","client":"$remote_addr",' '"host":"$host","method":"$request_method","uri":"$uri",' '"status":$status,"allowed":$origin_allowed,' '"upstream":"$upstream_addr","up_status":"$upstream_status"}'; server { listen 443 ssl; server_name site.example; ssl_certificate /etc/nginx/tls/site.example.crt; ssl_certificate_key /etc/nginx/tls/site.example.key; access_log /var/log/nginx/origin_access.log origin_audit; # 此处 if 仅用于立即 return,不包含重写或代理逻辑 if ($origin_allowed = 0) { return 403; } location / { proxy_pass proxy_set_header Host site.example; 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; proxy_set_header X-Origin-Verify ""; } }生成凭据可以使用 openssl rand -hex 32。凭据只保存在 CDN 回源设置和受限的服务器配置中,不放进前端代码、仓库或工单截图。上例主动清除了发给应用的回源凭据,并重建转发头,避免应用继续解析未经约束的客户端输入。应用也应只信任本机 Nginx 作为代理。这里的 X-Forwarded-For 配置有前提:CDN 必须按照明确且可靠的规则写入客户端地址。若服务商推荐使用专用客户端 IP 头,应按其文档调整 real_ip_header;不能直接套用一套头部规则到所有服务商。上线与复测:不要只看首页能不能打开# 检查配置,成功后再平滑加载 sudo nginx -t && sudo systemctl reload nginx # 观察入口判定及是否进入上游 sudo tail -n 50 /var/log/nginx/origin_access.log # 再次验证直连路径 curl --noproxy '*' --resolve site.example:443:198.51.100.20 \ --connect-timeout 5 -sS -D - -o /dev/null \ CDN 请求:确认产生了实际回源,而不是只命中边缘缓存;日志中 allowed 应为 1,peer 应为合法回源节点。公网直连源站:若网络层已限制,应无法建立连接;若仍能到达 Nginx,应返回 403,且 upstream 为空或为“-”。从自有测试机伪造 X-Forwarded-For:不应改变其非可信连接身份,更不能因此访问业务。在自有回源测试环境中移除凭据:即使连接来自允许的节点,也应被拒绝。检查 IPv6、其他监听端口及同机虚拟主机,避免只封住 IPv4 的 443,应用端口却仍然公开。测试正常回源时,可以使用站点已有的不缓存健康检查路径,并确认日志确实新增记录。不要为了验证方便,临时开放一个不受回源控制的健康检查接口。风险与修复建议共享回源网段不是站点身份认证。条件允许时,使用站点专属回源客户端证书或私有网络回源;固定头部凭据属于共享秘密方案,需要轮换。日志不要记录回源凭据、Cookie、Authorization。示例记录 $uri 而非 $request_uri,避免默认收集查询参数中的令牌,但路径本身仍可能含敏感信息。来源头解析规则变化会影响限流、封禁和审计。调整 realip 配置后,应同时核对应用看到的客户端地址。回源网段过期可能造成全站故障。更新列表时先校验、再加载,并保留回滚配置;不要以临时放开全部来源作为长期修复。如果采用证书自动续期,提前确认验证方式是否依赖公网直连源站;必要时改用 DNS 验证,避免上线后才发现续期失败。总结网站接入 CDN 后,值得核查的不是“有没有加速响应头”,而是直连源站是否仍能进入业务、客户端身份是否可信、拒绝动作是否留下可解释的日志。把网络入口、站点回源认证和代理头信任分开处理,配置才更容易验证,也更容易在故障时定位责任边界。 服务器、云资产与权限边界梳理示意 网络请求、日志与边界流量分析示意
33分钟前33分钟 这里建议重点核查一个容易漏掉的点:Nginx 启用 Real IP 后,访问控制用的究竟是客户端地址,还是实际回源连接地址。 如果配置了 set_real_ip_from 和 real_ip_header,$remote_addr 可能已经被替换成访客 IP。这时直接在 Nginx 里用 allow CDN网段; deny all;,访问控制判断的也是替换后的地址,可能误拦正常回源。CDN 网段白名单优先放到安全组或主机防火墙;必须在 Nginx 做时,应基于 $realip_remote_addr 判断连接对端,而不是直接照搬这套 allow/deny。 日志建议同时保留还原前后的地址,避免只看“客户端 IP”就误以为流量经过了 CDN。下面配置放在 http 块中,相关变量需要 Real IP 模块支持: log_format origin_check escape=json '{"time":"$time_iso8601",' '"peer":"$realip_remote_addr",' '"client":"$remote_addr",' '"host":"$host",' '"sni":"$ssl_server_name",' '"xff":"$http_x_forwarded_for",' '"request":"$request",' '"status":$status}'; access_log /var/log/nginx/origin_check.log origin_check; peer 用于核对连接来源是否属于 CDN 官方回源网段;client 用于业务溯源。XFF 只作为核查字段,不能直接当作可信身份,尤其不要配置 set_real_ip_from 0.0.0.0/0;。另外,源站四层拦截的请求不会进入 Nginx 日志,要结合安全组流日志或防火墙计数确认。 验证时不要只访问“源站 IP”,还要带上正确的 Host 和 TLS SNI,否则可能只是被默认虚拟主机挡住: # 从非 CDN 的外部网络测试,替换为自己的业务域名和源站地址 curl --noproxy '*' -v --connect-timeout 5 \ --resolve \ 预期应是连接被阻断,或命中明确的拒绝策略,而不是返回正常业务内容;返回跳转也要继续检查是否进入了业务虚拟主机。最后别漏掉 IPv6、80 端口和备用监听端口。若还需要限制“只有自己的 CDN 配置才能回源”,仅放行共享 CDN 网段不够,优先使用 CDN 支持的回源 mTLS 等身份认证能力。
创建帐户或登录后发表意见