Nginx用proxy_pass实现CDN源站反向代理,核心是充当合规源站:保持原始URI路径、透传Host头、关闭自身缓存、转发请求至真实后端(如OSS或Web服务器),并按后端要求调整Host头与鉴权逻辑。

在 Nginx 中用 proxy_pass 实现静态资源 CDN 的源站反向代理,核心是让 Nginx 充当“源站服务器”,把原本直接访问源站的请求(比如图片、JS、CSS)转给 CDN 域名回源,同时确保响应头、路径、缓存行为符合 CDN 要求。这不是简单的转发,而是要模拟一个合规的源站行为。
明确反向代理的角色定位
CDN 回源时,会以自己的节点 IP 向你的 Nginx 发起请求(如 GET /images/logo.png),Nginx 需将该请求再转发给真实后端(如对象存储、另一台 Web 服务器或本地文件系统)。关键点:
- Nginx 不直接提供静态文件,而是作为“代理源站”——它不读磁盘,只做协议中转
- 必须保留原始请求的 URI 路径,不能重写丢失层级(例如
/static/js/app.min.js必须原样传给后端) - 需透传 Host 头(CDN 回源常带自有域名,但后端可能依赖 Host 判断租户或环境)
- 建议关闭 Nginx 自身的缓存(
proxy_cache off),由 CDN 统一控制缓存策略
基础 proxy_pass 配置示例
假设你的真实静态资源托管在 https://oss.example.com,CDN 回源地址为 origin.yourcdn.com,Nginx 监听 80 端口:
server {
listen 80;
server_name origin.yourcdn.com;
<pre class="brush:php;toolbar:false;">location / {
# 保持原始 URI,不加尾随斜杠或路径截断
proxy_pass https://oss.example.com;
# 强制透传 Host,避免后端收到 oss.example.com
proxy_set_header Host $host;
# 传递真实客户端 IP(CDN 回源时通常是其节点 IP)
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 关闭 Nginx 缓存,交由 CDN 管理
proxy_cache off;
# 可选:设置超时,避免 CDN 等待过久
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
# 确保响应头允许 CDN 缓存(如 Cache-Control)
proxy_pass_request_headers on;
}}
⚠️ 注意:proxy_pass 末尾是否加 / 决定路径重写行为。这里不加斜杠,才能保证 /img/a.jpg 完整转发到 https://oss.example.com/img/a.jpg。
适配常见后端类型
不同后端对请求格式要求不同,需微调配置:
-
对象存储(如阿里 OSS、腾讯 COS、S3):通常要求
Host头为存储桶域名(如my-bucket.oss-cn-hangzhou.aliyuncs.com),此时应写proxy_set_header Host my-bucket.oss-cn-hangzhou.aliyuncs.com; -
自建 Web 服务器(如另一台 Nginx):若后端也用
server_name匹配,建议保持Host为原始值(即$host),并确保后端有对应server块监听该域名 -
需要鉴权的源站(如带签名 URL):可在
proxy_pass前用rewrite或map注入临时 token,或用auth_request模块校验 CDN 请求合法性
验证与调试要点
上线前务必验证回源行为是否符合预期:
- 用
curl -H "Host: origin.yourcdn.com" http://your-nginx-ip/images/test.png模拟 CDN 回源请求,检查返回状态码和内容 - 开启
error_log /var/log/nginx/proxy.log debug;(临时),查看proxy_pass实际转发的 URL 和头信息 - 确认 CDN 控制台中“回源 Host”设置与 Nginx 的
proxy_set_header Host一致,否则可能 403 或 404 - 检查响应头中
Content-Length、Content-Type是否正确(Nginx 默认自动处理,但若后端缺失,可加proxy_force_ranges on;支持断点续传
不复杂但容易忽略。











