大型网站的HTTPS实践四:协议层以外的实践
1 前言
网上介绍 https 的文章并不多,更鲜有分享在大型互联网站点部署 https 的实践经验,我们在考虑部署 https 时也有重重的疑惑。
本文为大家介绍百度 HTTPS 的实践和一些权衡,希望以此抛砖引玉。
2 协议层以外的实践工作
2.1 全站覆盖 https 的理由
很多刚接触 https 的会思考,我是不是只要站点的主换了 https 就可以?答案是不行。
https 的目的就是保证传输过程的安全,如果只有主上了 https,但是主域名加载的资源,比如 js,css,图片没有上 https,会怎么样?
从效果上来说,没有达到保证网站传输过程安全的目的,因为你的 js,css,图片仍然有被劫持的可能性,如果这些内容被篡改 / 嗅探了,那么 https 的意义就失去了。
浏览器在设计上早就考虑的这样的情况,会有相应的提示。具体的实现依赖浏览器,例如地址栏锁形标记从绿色变为黄色, 阻止这次请求,或者直接弹出非常影响用户体验的提示 (主要是 IE),用户会感觉厌烦,疑惑和担忧安全性。
很多用户看见这个链接会习惯性的点”是”,这样非 https 的资源就被禁止加载了。非 ie 的浏览器很多也会阻止加载一些危害程度较高的非 https 资源(例如 js)。我们发现移动端浏览器的限制目前会略松一些。
所以这里要是没做好,很多情况连网站的基本功能都没法正常使用。
2.2 站点的区别
很多人刚接触 https 的时候,觉得不就是部署证书,让 webserver 支持 https 就行了吗。
实际上对于不同的站点来说,https 的部署方式和难度有很大的区别。对于一个大型站点来说,让 webserver 支持 https,以及对 webserver 在 https 协议特性上做一些优化,在迁移的工作比重上,可能只占到 20%-40%。
我们考虑下以下几种情况下,部署 https 的方案。
2.2.1 简单的个人站点
简单的定义:资源只从本站的主域或者主域的子域名加载。
比如 axyz 的个人 blog,域名是 axyzblog.com。加载主域名下的 js 和图片。
这样的站部署 https,在已有证书且 webserver 支持的情况下,只需要把主域名替换为 https 接入,然后把资源连接修改为 https:// 或者 //。
2.2.2 复杂的个人站点
复杂的定义:资源需要从外部域名加载。
这样就比较麻烦了,主域资源容易适配 https,在 cdn 上加载的资源还需要 cdn 服务商支持 https。目前各大 cdn 的服务商正在逐渐提供 https 的支持,需要迁移的朋友可以看看自己使用的 cdn 是否提供了这项能力。一些 cdn 会对 https 流量额外收费。
Cdn 使用 https 常见的方案有:
1 网站主提供私钥给 cdn,回源使用 http。
2 cdn 使用公共域名,公共的证书,这样资源的域名就不能自定义了。回源使用 http。
3 仅提供动态加速,cdn 进行 tcp 代理,不缓存内容。
4 CloudFlare 提供了Keyless SSL的服务,能够支持不愿意提供私钥, 不想使用公共的域名和证书却又需要使用 cdn 的站点了。
2.2.3 简单的大型站点
简单的定义: 资源只从本站的主域, 主域的子域,或者自建 / 可控的 cdn 域名加载,几乎没有第三方资源。如果网站本身的特性就如此,或愿意改造为这样的类型,部署 https 就相对容易。Google Twitter 都是非常好的范例。优点:已经改成这样的站点,替换 https 就比较容易。缺点:如果需要改造,那么要很大的决心,毕竟几乎不能使用多样化的第三方资源了。
2.2.4 复杂,访问速度重要性稍低的大型站点
复杂的定义:从本站的非主域,或者第三方站点的域名有大量的第三方资源需要加载,多出现在一些平台类,或者有复杂内容展现的的网站。
访问速度要求:用户停留时间长或者强需求,用户对访问速度的耐受程度较高。比如门户,,在线交易类(比如火车票 机票 商城)网站。
这样的站点,可以努力推动所有相关域名升级为支持 https。我们用下图举例说明下这样修改会导致一个网站的链接发生怎样的改变。
负责流量接入的团队将可控的接入环境改造为 http 和 https 都支持,这样前端工程的工作相对就少一些。大部分时候将链接从 http:// 替换为 // 即可. 在主域名是 https 的情况下,其它资源就能自动从 https 协议下加载。一些第三方资源怎么办?一般来说只有两种选择,一迁移到自己的 cdn 或者 idc 吧,二强制要求第三方自己能支持 https。
以全站 https 接入的 facebook 举例。第三方厂商想在 facebook 上线一个游戏。facebook:请提供 https 接入吧。第三方想:能赚钱啊,还是提供下 https 接入吧。所以,足够强势,有吸引力,合作方也有提供 https 的能力的话,这是完全可行的。如果你的平台接入的都是一些个人开发者,而且还赚不到多少钱的情况下,这样就行不通了。
优点:前端改动相对简单,不容易出现 https 下还有 http 的资源问题。
缺点:通常这样的实现下,用户的访问速度会变慢,比如从 2.5 秒变为 3 秒,如上述的理由,用户还是能接受的。对第三方要求高。
2.2.5 复杂,访问速度有严格要求的大型站点
复杂的定义:同上。
访问速度要求:停留时间不长,用户对访问速度的心理预期较高。
但是如果用户把网站当作工具使用,需要你很快给出响应的时候,这样的实现就不好了。后续几个部分我们介绍下这些优化的抉择。
2.3 域名的选择
域名对访问速度的影响具有两面性:域名多,域名解析和建立连接的时间就多;域名少,下载并发度又不够。
https 下重建连接的时间成本比 http 更高,对于上面提到的简单的大型站点, 可以用少量域名就能满足需求,对于百度这样富展现样式较多的来说,页面可能展示的资源种类太多。而不同类型的资源又是由不同的域名 (不同的产品 或者第三方产品) 提供的服务,换一个词搜索就可能需要重新建立一些资源的 ssl 链接,会让用户感受到卡顿。
如果将域名限制在有限的范围,维持和这些域名的连接,合并一些数据,加上有 spdy,http2.0 来保证并发,是可以满足我们的需求的。