如何为整站(含HTML)配置CloudFront CDN?解决DNS与Nginx循环问题
解决CloudFront分发全静态网站的DNS循环与Nginx配置问题
完全可以用CDN(包括CloudFront)分发整个静态网站(含渲染后的HTML页面)。你遇到的403错误核心原因是DNS回源循环:主域名example.com指向CloudFront,而CloudFront又把example.com作为源站,导致回源请求解析到CloudFront节点,无法获取真实内容。下面是针对你的场景的具体解决方案:
一、先解决DNS循环:新增专用回源域名
首先要打破循环,不能让CloudFront回源到主域名example.com,需要给源站设置一个仅用于回源的专用域名(比如origin.example.com):
在Route53中调整DNS记录:
@(根域名):A记录别名指向你的CloudFront分发域名(xxxxxxx.cloudfront.net)www:A记录别名指向CloudFront分发域名(或设置重定向到@)- 新增
origin.example.com:A记录直接指向你的源站服务器公网IP(这个域名仅用于CloudFront回源,无需对外宣传)
二、调整CloudFront配置
- 修改源站设置:将原有的源站域名从
example.com改为origin.example.com - 添加自定义回源头:在CloudFront源站的"自定义HTTP头"中添加
X-CloudFront-Access: YourUniqueSecretToken(这个令牌自行设定,比如一串随机字符串,用于Nginx验证请求是否来自CloudFront) - 配置缓存策略:
- 确保HTML页面被缓存:默认CloudFront可能不缓存HTML,需要创建缓存策略,设置合适的TTL(比如3600秒,根据内容更新频率调整)
- 根据需求配置缓存键:比如多语言页面,可添加
Accept-Language到缓存键,确保不同语言的HTML被分别缓存
- 确保CloudFront使用有效的SSL证书(覆盖
example.com和www.example.com,可通过AWS ACM免费申请)
三、Nginx配置:区分回源请求与普通请求
修改Nginx配置,实现两个核心逻辑:
- 允许来自CloudFront的回源请求(通过
origin.example.com且携带正确自定义头)直接返回内容 - 禁止普通访客直接访问源站,将其重定向到主域名(走CloudFront)
1. 回源域名的Server块
server { listen 443 ssl; server_name origin.example.com; # 替换为你的SSL证书路径(origin域名需包含在证书中,或单独申请证书) ssl_certificate /etc/nginx/ssl/origin.example.com.crt; ssl_certificate_key /etc/nginx/ssl/origin.example.com.key; # 验证请求是否来自CloudFront if ($http_x_cloudfront_access != "YourUniqueSecretToken") { return 301 https://example.com$request_uri; } # 你的网站根目录和现有静态资源配置 root /var/www/your-site; index index.html; location / { try_files $uri $uri/ =404; # 保留你现有的静态资源缓存配置(如CSS/JS/图片的过期头) } }
2. 主域名的Server块(调整现有配置)
# HTTP跳转HTTPS server { listen 80; server_name example.com www.example.com; return 301 https://example.com$request_uri; } # www跳转非www server { listen 443 ssl; server_name www.example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; return 301 https://example.com$request_uri; } # 主域名处理:拦截直接访问源站的请求,重定向到CloudFront server { listen 443 ssl; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; # 判断是否为非CloudFront的直接请求 set $redirect_to_cdn 0; if ($http_x_cloudfront_access != "YourUniqueSecretToken") { set $redirect_to_cdn 1; } # 直接访问源站的请求重定向到主域名(已指向CloudFront) if ($redirect_to_cdn = 1) { return 301 https://example.com$request_uri; } # 以下配置其实很少触发,因为主域名已指向CloudFront, # 仅当有人通过源站IP直接访问example.com时生效 root /var/www/your-site; index index.html; location / { try_files $uri $uri/ =404; } }
四、测试与验证
- 保存Nginx配置并重启:
sudo nginx -s reload - 清除CloudFront缓存:在CloudFront控制台的分发详情中,选择"Invalidations",创建一个
/*的无效请求 - 访问
https://example.com,检查响应头是否包含X-Cache(来自CloudFront的标识),确认内容正常加载 - 尝试直接访问源站IP,应该会被重定向到
https://example.com,走CDN
内容的提问来源于stack exchange,提问作者Michal Palus
相关产品推荐
相关产品推荐

