Nginx 与 CDN 完成重定向:从 HTTP 重定向到 HTTPS、从 WWW 重定向到根
文章推荐:在 DNS 侧配置重定向
通过 Cloudflare DNS 重定向规则可以更方便配置好重定向。详看这篇文章:域名 DNS 服务托管至 Cloudflare 以及 301 重定向的配置
今天填了一个一直想填的坑,就是把博客域名的重定向、CDN 回源设置给弄好和捋顺了。以前的做法是 www.uuanqin.top 和 uuanqin.top 同时使用,CDN 也配置两条域名,但我总感觉不优雅、也不安全。通过学习一些网络相关知识,我自己尝试动手实验,绘制了域名解析流程图(把 DNS 迭代查询和递归查询简化拉平了)。此外把一些关键的具体配置分享出来并简要分析。
镇楼图先放出来:
上图即为本站域名跳转关系,呕心沥血绘制。看着很复杂,实际…这张图体现的配置我还是感觉不太完美,限于目前的知识储备也就这样了,希望路过的大佬们在评论区指点迷津!!
本文目的在于分享交流,所有操作仅供参考。
如果你是萌新站长,建议不要直接上手本篇文章内容,先弄明白这几篇文章循序渐进开始:
- 拥有了域名,配置主机 A 记录,直接指向源站:新手引导 (aliyun.com)
- 使用 CDN 服务,并加速域名:内容分发网络 CDN 从零开始配置 CDN-快速入门-文档中心-腾讯云 (tencent.com)
- 网站使用 HTTPS:SSL 证书使用指南 (aliyun.com)
环境
我的整个博客项目不同服务由不同服务商提供,之所以没选择 All in one 除了想自己边折腾边学习外,还是想让各种服务松耦合起来。
博客使用的服务以及部分软件系统版本如下:
DNS 域名解析 | SSL 证书 | CDN 服务 | 云服务器 | Web 服务 |
---|---|---|---|---|
阿里云 | 阿里云 | 腾讯云 | 阿里云 ECS(Linux) | Nginx 1.22.1 |
不管是阿里云还是腾讯云,相关服务的使用大差不差,本文只是给个思路。
配置效果与原因
理想的域名配置效果应该是这样的:
- 用户在地址栏输入 www.uuanqin.top 时会直接重定向到 uuanqin.top,地址栏不显示 www 地址
- 所有 http 不安全链接自动指向 https 链接
- 使用 HSTS 在尽可能保证安全的同时减少重定向次数
- 精简 CDN 回源配置
如果想直接看操作过程的跳下一节,想看原因的请继续往下阅读。
301 重定向的优点(www 重定向到不带 www 的地址)
你会发现互联网上一些网站的输入 www 开头网址跳转后,地址栏 www 会消失(或相反:不输 www 反而跳到显示 www,例如 baidu.com)。它们都使用了一种非常重要的「自动转向」技术——301 重定向。
301 重定向(301 Move Permanently),指页面永久性转移,表示为资源或页面永久性地转移到了另一个位置。301 是 HTTP 协议中的一种状态码,当用户或搜索引擎向服务器发出浏览请求时,服务器返回的 HTTP 数据流中头信息(header)中包含状态码 301 ,表示该资源已经永久改变了位置。
过程如图:
利用 301 重定向设置网站别名有利于网站首选域的确定,对于同一资源页面多条路径的 301 重定向有助于 URL 权重的集中,利于网站 SEO。
302 重定向(302 Move Temporarily),指页面暂时性转移,表示资源或页面暂时转移到另一个位置,常被用作网址劫持,容易导致网站降权,严重时网站会被封掉,不推荐使用。
搜索引擎是这样对待两种重定向的:
重定向方式 | 搜索引擎抓取操作 |
---|---|
301 页面永久性转移 | 抓取新内容的同时也将旧的网址替换成重定向之后的网址 |
302 页面暂时性转移 | 抓取新的内容而保存旧的网址并认为新的网址只是暂时的 |
HTTP 跳转到 HTTPS
HTTP 协议也就是超文本传输协议,是一种使用明文数据传输的网络协议,不提供任何方式的数据加密。如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。
为了数据传输的安全,另一种协议 HTTPS(安全套接字层超文本传输协议)诞生。HTTPS 在 HTTP 的基础上加入了 SSL/TLS 协议,SSL/TLS 依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
HTTP 和 HTTPS 使用的是完全不同的连接方式,同时使用的端口也不同,网络模型工作层不同:
协议 | 传输方式 | 端口 | 工作层 |
---|---|---|---|
HTTP 超文本传输协议 | 明文传输 | 80 | 应用层 |
HTTPS 安全套接字层超文本传输协议 | SSL/TLS 协议加密 | 443 | 传输层 |
HTTPS 有利于搜索排名的提升。百度和谷歌两大搜索引擎都已经明确表示,HTTPS 网站将会作为搜索排名的一个重要权重指标。也就是说 HTTPS 网站比起 HTTP 网站在搜索排名中更有优势。
为什么使用 CDN?
当用户直接访问源站中的静态内容时,可能面临的体验问题:
- 客户离服务器越远,访问速度越慢。
- 客户数量越多,网络带宽费用越高。
- 跨境用户访问体验较差。
CDN 如何改善您的网络体验:
- CDN 缓存内容后,用户仅需要访问就近的 CDN 节点即可获取静态内容。
- 缓解源站带宽压力,网络费用更低。
- 分布全球的跨境节点提升跨境访问体验。
为什么不要用 CDN?
CDN 增加网站的被攻击风险,若安全措施没有实施到位,容易产生高额账单。比如在 2024 年,本站遭遇大量恶意攻击并造成一定程度的财产损失。
HSTS 是什么?
上文提到 HTTPS 可以提高安全性,是“更加安全的 HTTP”,但 HTTPS 提供服务也不是安全的。
最初网站是通过 HTTP 协议提供服务,为了安全起见,网站升级为 HTTPS 协议,可是当用户在浏览器中输入网址时,例如 www.uuanqin.top ,而不是输入完整的 www.uuanqin.top ,浏览器会向网站发起一次 HTTP 请求,这时浏览器获取到一个重定向到 HTTPS 的请求(就像上文我们说的 301 重定向),然后再使用 HTTPS 协议通信。在这个过程中,我们使用了一次明文的 HTTP 请求和重定向,而这个过程很容易被攻击者利用,攻击者可以以中间人的方式劫持这次请求,从而进行后续的攻击,例如窃听数据,篡改请求和响应,跳转到钓鱼网站等。
为了避免这个问题,我们希望浏览器做到:当用户输入网址时(不带 https:// )将其转换成 HTTPS 请求,从而绕过明文的 HTTP 请求和重定向。我们使用 HSTS 可以告诉浏览器这个网站是否是使用的 HTTPS。
HSTS 的全称是 HTTP Strict-Transport-Security,它是一个 Web 安全策略机制。HSTS 的核心是HTTP 响应头(HTTP Response Header),它告诉浏览器在接下来的一段时间,这个域名只能通过 HTTPS 进行访问,如果该域名在浏览器中出现不安全访问,HSTS 会强制用户的访问。
HSTS Header 中可以设置其过期时间,比如 1 年。注意如果网站 SSL 证书出现问题,那么用户在一年的时间里都没法正常访问你的网站了,当然,除非用户清除了浏览器缓存。
HSTS 也并不安全。假设浏览器中没有该域名的 HSTS 信息时,用户第一次访问该网站时,依然需要使用明文的 HTTP 请求和重定向,解决方法是 Preload List,感兴趣的同学可以自己搜索,这里就不再赘述。
网址转换过程
DNS 解析链接地址的大致流程如下:
如果我们把上面 DNS 递归解析、迭代解析的过程拉平,并取出其中的主要结点,那么可以得到下图:
过程图解析:
浏览器有无 HSTS 缓存 | 用户在地址栏输入 | 路径 |
---|---|---|
❌ | http://uuanqin.top | 腾讯云 CDN 将其重定向至 HTTPS 再访问 CDN 边缘节点,同时浏览器存储 HSTS 缓存 |
✅ | http://uuanqin.top | 浏览器直接转换成 HTTPS 访问 CDN |
- | https: //uuanqin.top | 直接访问 CDN |
❌ | http:// www. uuanqin.top | 直接访问到服务器主机,Nginx 重定向至 https://uuanqin.top 进行访问。过程中浏览器会存储 HSTS 缓存 |
✅ | http:// www. uuanqin.top | 浏览器直接转换成 HTTPS,并直接访问到服务器主机,Nginx 重定向至 https://uuanqin.top 进行访问 |
- | https: // www. uuanqin.top | 直接访问到服务器主机,Nginx 重定向至 https://uuanqin.top 进行访问 |
其中 uuanqin.top 为 CDN 加速域名。通常第一次访问时没有 HSTS 缓存。
Q&A
为什么不在 CDN 同时设置两个加速域名?
很长一段时间以来一直都是这样设置,但是我觉得每次刷新都要同时刷新两个域名很不优雅,且耗费更多回源流量。此外还无法设置 301 重定向,造成 www 与不含 www 的域名同时存在。
当然,流程图这种方式可能会暴露公网 IP,这是我认为本篇配置需要改变的原因。
为什么 www 域名不使用 CNAME 指向?
CNAME 不能达到“用户浏览器只显示无 www 网址”的目的。(虽然这点好像不太重要,但我总是有这个执念)
操作
作为新站长,一口气配置正确是不可能的,本文开头给出了循序渐进的配置参考,每一步都做正确了,配置才能逐渐成型。
我们可以将上一小节的目标简要拆解成以下三个配置任务:
a. 用户输入 http://uuanqin.top 必须跳转到 https: //uuanqin.top
b. 用户输入 http://www.uuanqin.top 必须跳转到 https: //uuanqin.top
c. 用户输入 https: //www.uuanqin.top 必须跳转到 https: //uuanqin.top
DNS 解析配置
DNS 解析设置了这两条记录:
主机记录 | 记录类型 | 记录值 |
---|---|---|
@ | A | 服务器 IP 地址 |
www | CNAME | CDN 结点地址 |
CNAME 记录的配置详看 CDN 中的要求。
CDN 加速设置
我假设你已经尝试过 CDN 了,你应该懂得啥是加速域名了吧。CDN 我只设置一个加速域名 uuanqin.top
在 HTTPS 设置中开启 301 强制跳转和 HSTS:
到此则完成了任务 a.
Nginx 配置
打开 Nginx 的配置文件(不同版本的 Nginx 配置文件路径不太一样,1.22.1 的在/etc/nginx/conf.d/default.conf 中)
处理 CDN 在进行源站回源时的请求:
1 | server { |
将 https: //www. uuanqin.top 重定向到 https: //uuanqin.top,完成任务 c.:
1 | server { |
其中 301 重定向关键:rewrite ^(.*) https://uuanqin.top$1 permanent;
HSTS 配置:add_header Strict-Transport-Security "max-age=3001";
,解释:
- 添加一个名为
Strict-Transport-Security
的 HTTP 响应头,并设置了 HSTS 的相关选项 max-age
是必选参数,是一个以秒为单位的数值,它代表着 HSTS Header 的过期时间includeSubDomains
是可选参数,如果包含它,则意味着当前域名及其子域名均开启 HSTS 保护preload
是可选参数,只有当你申请将自己的域名加入到浏览器内置列表的时候才需要使用到,指示浏览器将网站添加到 HSTS 预加载列表中,以便所有浏览器都将始终使用 HTTPS 与网站建立连接。
将 http: //www. uuanqin.top 重定向到 https: //uuanqin.top,完成任务 b.。
1 | # 首次访问 |
其他操作提示
清除浏览器(Chrome、Edge)的 HSTS 307 缓存
配置 HSTS 后我们可以打开浏览器开发者工具,监视网络中包发送情况即可。有时候我们也需要清除 HSTS 的缓存。
Chrome 浏览器打开 chrome://net-internals/#hsts (Edge 浏览器直接点这个链接也没问题,它会自动重定向)
先在 Query HSTS/PKP domain 查你被 307 Internal Redirect 的域名
- 如果是 Not Found,这个就不是你要的答案
- 如果有內容,如下图,那就到 Delete domain security policies 输入你被 307 Internal Redirect 的网址,然后 Delete 它。
现在你能使用 HTTP 访问该网址了。
Nginx 安装配置
可参考这篇文章:Nginx 的安装与反向代理配置
百度站长
弄好之后可以在百度站长弄个 HTTPS 认证,测试自己的成果。
腾讯云 CDN 配置 HTTPS
网站的图床也可以自定义域名和 HTTPS 等设置。
在 Cloudflare DNS 配置重定向
详看这篇文章:域名 DNS 服务托管至 Cloudflare 以及 301 重定向的配置
本文参考
- 什么是 301 和 302 重定向,都有哪些用途? - 知乎 (zhihu.com)
- 搞懂 HTTP 重定向 - 如何优雅地使用 301-腾讯云开发者社区-腾讯云 (tencent.com)
- HTTP 和 HTTPS 有什么区别? - 知乎 (zhihu.com)
- 内容分发网络 CDN 新手指引-文档中心-腾讯云 (tencent.com)
- HSTS 详解原理及配置 HTTP 到 HTTPS 再到 HSTS - 新手站长网 (xinshouzhanzhang.com)
- 清除 chrome 的 HSTS 307 缓存 - 前端小记 - SegmentFault 思否
- 如何在 Nginx 中启用 HSTS?-腾讯云开发者社区-腾讯云 (tencent.com)
- Nginx 环境开启 ssl 后强制 https 301 全部指向 www 的方法-腾讯云开发者社区-腾讯云 (tencent.com)