网站开启 SSL 访问后,如果用户手动输入网站的 HTTP 网址,或者从其它地方点击了 HTTP 链接,这个时候并不会自动的完成从 http 跳转到安全的 https 访问,这个时候需要 301 跳转,将所有的 http 链接 301 到 https 链接。
在网站的 conf 文件,正常的 80 端口的 server 段落里加上如下代码,即会将链接从http 网址 301 跳转到 https 网址。
return 301 https://$server_name$request_uri;
但是301跳转的弊端就是,中间需要一次跳转,同样对于搜索引擎也是跳转了一次,这对于资源或者优化的角度并不是太有利。
可以通过 HSTS(HTTP Strict Transport Security)来解决,HSTS 是一个响应头。使用HSTS会让浏览器知道,必须通过 HTTPS 协议来访问。
在网站的 conf 文件,ssl 的443 端口的 server 的段落里加上如下代码即可开启 HSTS。
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
max-age,单位是秒,用来告诉浏览器在指定时间内,这个网站必须通过 HTTPS 协议来访问。也就是对于这个网站的 HTTP 地址,浏览器需要先在本地替换为 HTTPS 之后再发送请求。
includeSubDomains,可选参数,如果指定这个参数,表明这个网站所有子域名也必须通过 HTTPS 协议来访问。
preload,可选参数
HSTS 的要求和注意事项
- HSTS 这个响应头只能用于 HTTPS 响应;
- 网站必须使用默认的 443 端口;
- 必须使用域名,不能是 IP。
- 启用 HSTS 之后,一旦网站证书错误,用户无法选择忽略。
如果在使用HSTS后造成,域名或子域名HSTS异常无法访问的情况,可以参考这篇文章:Chrome HSTS异常导致子域名无法访问
HSTS Preload List
可以看出 HSTS 可以很好的解决 HTTPS 的链接跳转,但是对于网站的首次 HTTP 请求,依然无法进行跳转,因为这个时候用户并不是通过 HTTPS 访问的, HSTS 还没生效。
浏览器厂商们为了解决这个问题,提出了 HSTS Preload List 方案:在浏览器内置一份定期更新的域名列表,列表中的域名,即使用户之前没有访问过,也会使用 HTTPS 协议。
目前 HSTS Preload List 由 Google 在维护,Chrome、Firefox、Safari、IE 11 和 Microsoft Edge 等主流浏览器都在使用。如果要想把自己的域名加进 HSTS Preload List,需要满足以下条件:
- 以顶级域名进行申请
- 拥有合法的证书(如果使用 SHA-1 证书,过期时间必须早于 2016 年);
- 将所有 HTTP 流量重定向到 HTTPS;
- 确保所有子域名都启用了 HTTPS;
- 输出 HSTS 响应头:
max-age 不能低于 18 周(10886400 秒);
必须指定 includeSubdomains 参数;
必须指定 preload 参数;
满足条件的同学,可以点击这里进行申请提交
最后,不得不打击各位的是,即便满足了上述所有条件,也不一定能进入 HSTS Preload List,所以海天建议如果是安全要求很高的网站,还是 301 和 HSTS 共同使用吧。
[…] 想了下,可能是之前设置主域名ssl的时候,使用了 HSTS来进行了跳转(具体见:HSTS完成SSL中http到https的跳转),造成了顶级域名被浏览器记录了响应头,造成了就算浏览子域名的时候也强制要求使用https进行访问。 […]
80端口可以装个nginx,反响代理到https
@世纪之光 但是反向代理 对于搜搜引擎不太友好吧
@haitian 为啥不友好呀,倒是没有深究这个问题,主要我也不太关心搜索引擎,哈哈。
@世纪之光 额 好像我说错了 反向代理 蜘蛛好像识别不了吧
@世纪之光 不对啊 反向代理 但是网站的url还是80端口的http啊