发布于昨天 21:591天前 背景最近帮朋友复盘一个小型业务站点的授权安全检查,站点架构很常见:域名接入 CDN/加速器,源站是 Nginx + PHP-FPM,后面挂 MySQL。业务本身没测出明显高危漏洞,但在做资产侧检查时发现一个问题:源站 IP 可以被直接访问,且部分接口绕过了加速器侧的访问控制策略。这个问题放在“咖啡馆”板块比较合适,不是讲漏洞利用,而是网站建设、服务器暴露面、加速器接入和日志留痕这些容易被忽略的细节。下面记录一下排查过程,便于有类似架构的站长自查。前提说明:以下内容基于授权测试环境和站点自查,重点是配置核验、日志确认和修复建议,不涉及未授权攻击。具体场景业务域名: CNAME 到 CDN/加速器节点源站:云服务器公网 IP,Nginx 直接监听 80/443站点逻辑:后台路径做了加速器侧访问限制,只允许办公出口 IP 访问问题现象:通过源站 IP 访问时,后台限制失效,部分接口可直接命中源站这类问题的核心不是“CDN 不安全”,而是源站没有做边界收敛。加速器只保护经过它的流量,源站公网如果裸奔,策略就会被绕开。问题定位第一步先确认域名解析和真实访问链路。dig +short nslookup curl -I curl -I --resolve --resolve 强制把域名解析到源站 IP,同时保留 HTTPS 的 Host 和 SNI,模拟“知道源站 IP 后直接访问”的效果。如果返回结果与正常 CDN 访问基本一致,就要继续看源站是否接受了任意来源的请求。技术分析在这次排查里,出现了三个典型问题。一、Nginx 默认站点暴露源站 Nginx 存在一个默认 server,监听 80 和 443,且没有限制 Host。访问源站 IP 时,Nginx 会落到默认站点,最终仍然转发到业务目录。server { listen 80 default_server; listen 443 ssl default_server; server_name _; root /data/www/site; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } }这种写法在部署阶段很方便,但上线后风险很明显:只要源站 IP 被扫到,攻击面就绕过了 CDN。二、后台访问控制只做在加速器侧后台路径如 /admin、/manage 在加速器上做了 IP 白名单,但源站 Nginx 没有同等策略。导致访问链路变成:正常访问:用户 -> CDN/加速器 -> 源站,受加速器规则限制绕过访问:用户 -> 源站 IP,直接命中 Nginx,不经过加速器规则权限边界应该落在源站和应用两侧,而不是只依赖外层入口。三、真实客户端 IP 处理不完整源站日志里看到大量请求的 remote_addr 是加速器节点 IP,但应用侧又读取了 X-Forwarded-For 作为客户端 IP。如果源站允许任意来源请求,攻击者可以伪造该头,影响审计和部分基于 IP 的业务逻辑。curl -H 'X-Forwarded-For: 127.0.0.1' \ -H 'Host: \ X-Forwarded-For,而 Nginx 没有限定可信代理来源,就容易出现日志污染、访问控制绕过等问题。操作步骤1. 检查源站是否可直连# HTTP 直连测试 curl -I -H 'Host: # HTTPS 直连测试,保留 SNI/Host curl -k -I --resolve # 检查后台路径是否绕过加速器规则 curl -k -I --resolve 信息和页面特征。如果和正常域名访问一致,说明源站大概率可被直接访问。2. 检查 Nginx server_name 和默认站点nginx -T | grep -nE 'server_name|listen|default_server|root|proxy_pass'需要重点关注:是否存在 server_name _; 直接指向业务目录是否有 default_server 落到正式站点是否所有业务域名都显式声明了 server_nameHTTP 和 HTTPS 是否都有限制策略3. 检查访问日志中的真实来源# 查看最近访问源站的 IP 分布 awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head # 搜索直接打源站 IP 的请求特征 grep -E '源站IP|admin|wp-login|phpmyadmin' /var/log/nginx/access.log | tail -50 # 如果日志格式包含 Host,可以统计异常 Host awk '{print $2,$7,$9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head建议在 Nginx 日志中增加 Host、X-Forwarded-For、真实来源 IP,方便后续判断请求是否经过加速器。log_format main_ext '$remote_addr - $host [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'xff="$http_x_forwarded_for" realip="$realip_remote_addr"'; access_log /var/log/nginx/access.log main_ext;修复建议1. 源站防火墙只允许加速器回源 IP最有效的做法是在云安全组或系统防火墙层限制源站入口,只允许 CDN/加速器的回源 IP 段访问 80/443。# 示例:iptables 只放行指定加速器回源 IP 段 iptables -A INPUT -p tcp -s 203.0.113.0/24 --dport 80 -j ACCEPT iptables -A INPUT -p tcp -s 203.0.113.0/24 --dport 443 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j DROP iptables -A INPUT -p tcp --dport 443 -j DROP实际环境优先使用云厂商安全组,规则更直观,也便于回滚。需要注意加速器厂商的回源 IP 段可能会更新,应定期同步。2. Nginx 默认站点直接丢弃不要让默认站点落到业务目录。未知 Host 直接返回 444 或 403。server { listen 80 default_server; server_name _; return 444; } server { listen 443 ssl default_server; server_name _; ssl_certificate /etc/nginx/ssl/default.crt; ssl_certificate_key /etc/nginx/ssl/default.key; return 444; }正式业务站点单独写明确的 server_name。server { listen 443 ssl http2; server_name root /data/www/site; index index.php index.html; location /admin/ { allow 10.10.10.0/24; deny all; try_files $uri $uri/ /index.php?$query_string; } location / { try_files $uri $uri/ /index.php?$query_string; } }3. 正确处理真实客户端 IP只信任加速器节点传来的 X-Forwarded-For,不要对任意来源都解析该字段。# 只填写加速器官方回源 IP 段 set_real_ip_from 203.0.113.0/24; set_real_ip_from 198.51.100.0/24; real_ip_header X-Forwarded-For; real_ip_recursive on;如果没有完成源站入口限制,不建议应用层直接信任 X-Forwarded-For。应用里用于风控、审计、后台白名单的客户端 IP,应基于 Nginx 处理后的可信结果。4. 后台权限不要只放在加速器侧后台入口建议同时做三层控制:加速器侧:访问控制、区域限制、基础 WAF 规则Nginx 侧:路径级 IP 白名单或认证应用侧:强认证、二次验证、操作审计例如后台路径可以增加基础认证,避免源站临时暴露时完全裸露。location /admin/ { auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; allow 10.10.10.0/24; deny all; try_files $uri $uri/ /index.php?$query_string; }日志留痕建议修复后建议保留一段时间的强化日志,用于观察是否仍有直连源站请求。记录 $host,发现 IP 访问或异常 Host记录 $remote_addr 和 $realip_remote_addr,区分代理节点与真实来源记录后台路径访问状态码,观察是否还有非白名单访问尝试对 403、444、401 单独分日志,便于快速统计map $status $log_blocked { default 0; 401 1; 403 1; 444 1; } access_log /var/log/nginx/blocked.log main_ext if=$log_blocked;风险总结问题风险建议源站 IP 可直连绕过加速器防护和访问控制安全组限制只允许回源 IP默认站点指向业务目录异常 Host 仍可访问业务默认站点返回 444/403只在加速器侧限制后台源站暴露时后台可被探测Nginx 和应用侧同步限制盲目信任 X-Forwarded-For日志污染、IP 策略绕过仅信任指定代理 IP 段总结网站接入加速器后,不代表源站天然安全。实际排查时,我一般按这个顺序看:解析链路、源站直连、默认站点、Host 限制、真实 IP 处理、后台路径策略、日志留痕。很多问题不是漏洞本身,而是边界配置没收紧。对站长来说,优先级最高的是两点:第一,源站入口只允许加速器回源;第二,Nginx 默认站点不要承载业务。做到这两点,绝大多数“绕过加速器直打源站”的问题就能先压下去。 网络请求、日志与边界流量分析示意
昨天 23:371天前 这类问题建议先把“源站地址泄露”和“源站可被直接访问”分开确认,很多时候只是 DNS 或证书里暴露了 IP,但真正的风险在于源站 80/443 没有限制来源。 先从外部验证,不要只在源站本机测试: # 查看当前解析及是否存在绕过记录 dig +short A example.com dig +short AAAA example.com dig +short CNAME example.com dig +short origin.example.com # 分别使用域名和疑似源站 IP 访问,观察状态码、Server、Location、证书 curl -kI --resolve example.com:443:源站IP curl -kI --resolve example.com:443:加速器IP # 检查 HTTPS 证书是否把源站主机名、内网命名或旧域名放进 SAN openssl s_client -connect 源站IP:443 -servername example.com \ 排查日志时不要只搜访问日志里的 Host。重点关联以下字段:访问源 IP、X-Forwarded-For、X-Real-IP、Host、SNI、请求时间和响应状态。若直接访问源站时 Host 仍然能命中业务虚拟主机,说明当前配置允许绕过反代;若返回默认站点,则还需要继续检查默认站点是否泄露跳转地址、错误页或静态资源。 # Nginx 临时增加便于关联的日志字段 log_format trace '$remote_addr real=$http_x_real_ip ' 'xff="$http_x_forwarded_for" host=$host ' 'server=$server_name sni=$ssl_server_name ' 'status=$status uri="$request_uri"'; access_log /var/log/nginx/access.log trace; 反代层建议显式覆盖转发头,不要直接信任客户端提交的 X-Forwarded-For: location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass } 真正有效的修复应放在源站防火墙,而不是只依赖 Nginx 判断请求头。源站的 80/443 只允许反代或加速器的出口网段,管理端口只允许办公网或 VPN;如果供应商出口网段会变化,应使用其官方 IP 段自动同步,否则容易出现“配置看似生效,实际仍全网开放”的情况。 # nftables 示例,网段仅作占位,不能直接照搬 nft add rule inet filter input tcp dport {80,443} \ ip saddr != { 203.0.113.0/24, 198.51.100.0/24 } drop 如果业务必须保留公网直连,至少应增加一个独立的源站入口,不要让业务域名在源站上使用默认虚拟主机,并拒绝未知 Host: server { listen 80 default_server; server_name _; return 444; } server { listen 443 ssl default_server; server_name _; ssl_reject_handshake on; } server { listen 443 ssl; server_name example.com # 仅示意:实际应由防火墙限制可信代理网段 location / { proxy_pass } } 最后要检查历史泄露渠道:旧的 origin、dev、test 子域名,DNS 历史记录,邮件头、错误页、下载文件中的绝对 URL,以及证书透明度日志。源站 IP 一旦已经公开,不能把“换 IP”当成唯一修复;应先封闭直连、轮换暴露的管理凭据和访问密钥,再更换地址,并持续用外部探针验证源站 IP 不再返回有效业务内容。
创建帐户或登录后发表意见