cdn回源需校验host头以防恶意请求绕过限制导致信息泄露或缓存污染;nginx推荐用map指令预定义合法host白名单,并在server块中用if判断$ is_valid_host拒绝非法请求,返回444更安全。

为什么 CDN 回源要校验 Host 头?
CDN 节点回源到你的 Nginx 服务器时,会带上 Host 请求头,值通常是用户访问的域名(比如 cdn.example.com 或 www.example.com)。如果你的 Nginx 同时托管多个站点,或启用了泛解析、多租户架构,不校验 Host 就可能被恶意构造请求绕过限制,直接打到后端服务,造成信息泄露或缓存污染。
在 Nginx 中开启 Host 校验的两种常用方式
核心思路是:只允许合法的 Host 值通过,其余全部拒绝(返回 444 或 403)。
- 用 if + valid_referers 不适用:valid_referers 验证的是 Referer,不是 Host,别混淆
- 用 map 指令预定义白名单(推荐):性能好、可读性强、支持正则和通配
- 用 if + $host 判断(简单场景可用):适合规则少、无正则需求的情况,但 if 在 location 外有局限性
推荐方案:用 map 实现 Host 白名单校验
把 Host 校验逻辑提前到 server 块之外,避免重复判断,也方便复用:
map $host $is_valid_host {
default 0;
example.com 1;
www.example.com 1;
~^cdn\.[a-z0-9\-]+\.(example\.com)$ 1;
}
然后在 server 或 location 中使用:
server {
listen 80;
server_name example.com www.example.com;
<pre class="brush:php;toolbar:false;">if ($is_valid_host = 0) {
return 444; # 直接断连,比 403 更安静
}
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}}
注意:
– 444 是 Nginx 特有状态码,表示“关闭连接”,不发响应体,对恶意扫描更友好
– 如果 CDN 自带固定回源 Host(如 always origin.example.com),就把这个值加进 map 白名单
– 正则匹配需以 ~^ 开头,且注意转义点号
CDN 厂商常见回源 Host 行为与应对
不同 CDN 对 Host 头的处理不同,需针对性适配:
- Cloudflare:默认回源用原始请求 Host;开启「Always Use HTTPS」或「Origin Rules」后可自定义,建议在 Page Rule 中设「Origin Header: Host → origin.example.com」
-
阿里云 CDN / 腾讯云 CDN:控制台有「回源 Host」配置项,可填固定值(如
origin.example.com)或「跟随客户端」;选固定值时,Nginx map 里必须包含该值 -
自建 CDN 或边缘节点:确保反代配置中显式设置了
proxy_set_header Host origin.example.com,不要依赖默认行为
上线前务必用 curl 模拟回源请求验证:
curl -H "Host: evil.com" http://your-server-ip/ # 应返回空响应或 connection reset curl -H "Host: cdn.example.com" http://your-server-ip/ # 应正常返回内容
不复杂但容易忽略











