跳转到帖子

一次网站服务器反代与加速器配置导致的真实源站暴露排查

精选回复

发布于

背景

最近帮朋友复盘一个小型业务站点的授权安全检查,站点架构很常见:域名接入 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_name
  • HTTP 和 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 默认站点不要承载业务。做到这两点,绝大多数“绕过加速器直打源站”的问题就能先压下去。

网络流量与边界分析示意图
网络请求、日志与边界流量分析示意

这类问题建议先把“源站地址泄露”和“源站可被直接访问”分开确认,很多时候只是 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 不再返回有效业务内容。

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。

SiteMap HACKHAT © 2026 All rights reserved.