在 nginx 中适配 cdn 回源,核心做法是将 cdn 提供的回源域名配置为 server_name,并配合 x-forwarded-for 头处理以识别真实用户 ip。这样做能确保 nginx 正确匹配请求并记录日志,同时防止非 cdn 流量直接访问源站。

Nginx 如何配置 server_name 以匹配 CDN 回源域名
将 CDN 厂商分配的回源域名(如 origin.example.com)直接写入 server_name 指令即可实现精准匹配。Nginx 会优先使用精确匹配的域名,若未找到则尝试通配符或正则表达式匹配,最终回退到默认服务器块。

server {
listen 80;
# 配置 CDN 回源域名
server_name origin.example.com;
location / {
root /var/www/html;
index index.html;
}
}
上述配置中,当 CDN 节点向 origin.example.com 发起请求时,Nginx 会命中此 server 块。若 CDN 配置了多个回源域名,只需将它们全部列在 server_name 后,用空格分隔。例如:server_name origin.example.com backup.example.com;。这样无论 CDN 从哪个域名回源,Nginx 都能正确处理。
如何验证 CDN 回源请求的真实客户端 IP
CDN 回源时,HTTP 请求的源 IP 是 CDN 节点的 IP,而非最终用户的 IP。为了获取真实用户 IP,需依赖 CDN 传递的 X-Forwarded-For 或 X-Real-IP 头部。Nginx 可通过 realip_module 或日志格式配置来提取这些信息。

# nginx.conf 全局配置
http {
# 设置信任的 CDN 节点 IP 段
set_real_ip_from 192.168.1.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
access_log /var/log/nginx/access.log main;
}
在上面的配置中,set_real_ip_from 指定了哪些 IP 地址被认为是可信的代理(即 CDN 节点)。当请求到达时,Nginx 会检查 X-Forwarded-For 头,并将最左侧的非代理 IP 视为 $remote_addr。这样,日志中的 $remote_addr 就是真实用户的 IP,便于后续分析和安全策略。
如果 CDN 回源域名与源站主域名不同,如何处理跨域和缓存键?
当 CDN 回源域名(如 cdn.example.com)与源站主域名(如 www.example.com)不同时,需确保 Nginx 不拒绝这些请求,并正确设置缓存键以避免缓存污染。通常,CDN 会将回源域名作为 Host 头发送,Nginx 应接受该 Host 并返回内容,同时忽略 Host 对缓存键的影响。
server {
listen 80;
server_name cdn.example.com www.example.com;
location / {
root /var/www/html;
index index.html;
# 确保缓存键基于 URL 而非 Host
proxy_cache_key $scheme$request_method$host$request_uri;
# 或者更严格地,忽略 host
# proxy_cache_key $scheme$request_method$request_uri;
}
}
在此配置中,server_name 同时包含 CDN 回源域名和主域名。对于缓存,建议使用 proxy_cache_key 明确指定缓存键组成。如果希望不同域名共享同一份缓存内容,可以移除 $host 变量,仅基于 $scheme、$request_method 和 $request_uri 生成缓存键。这样,即使通过不同域名访问相同资源,也能命中缓存,提升效率。同时,需确保 CDN 配置中缓存键与 Nginx 一致,避免缓存不一致问题。











