“全站 HTTPs”俨然成了目前的热门话题,很多网站都在摩拳擦掌要实行全站 HTTPs。凑巧,我们(沪江)也在推行这个计划。

  一开始大家想得都很简单,把证书购买了、配好了,相应的路径改一改,就没有问题。事实也确实如此,单个独立站点的 HTTPs 改造是很容易的。一旦走向“全站”,才发现事情远远比想象的要复杂,全站意味着所有资源面对所有客户端,涉及的因素异常多,网络上又没有太多资料,只能自己摸索。下面我简单讲讲遇到的几个问题,提供一些经验给大家参考。

  HSTS

  如果一个网站既提供了 HTTP 服务,又提供了 HTTPs 服务(在过渡期通常如此),怎样引导用户访问 HTTPs 的站点呢?这就是 HSTS(HTTP Strict Transport Security)的作用。通过 Web 服务器上的设置,在收到 HTTP 访问请求时,返回的 header 里带有 Strict-Transport-Security 字段,告知浏览器必须使用 HTTPs 进行访问。

  但是,HSTS 并不能避免首次跳转时遇到的劫持。要彻底解决这个问题,可以申请加入 Preload List(预加载列表)。

  Preload List 是由 Google Chrome 维护的“HTTPs 站点列表”,Chrome, Firefox, Safari, Edge, IE 11 均在使用。一旦浏览器发现要访问的站点在 Preload List 上,默认就会发起 HTTPs 链接。这样,就避免了 HSTS 的首次跳转被劫持的隐患。

  SSL 卸载

  通常的方案里,HTTPs 的加密传输只限于客户端出发的公网阶段,在内网的通讯流量仍然采用非加密的 HTTP 传输。这种“把加密流量转换为非加密流量”的过程,就是常说的 SSL/TLS 卸载(Offloading,以下简称“SSL 卸载”)。

  有一些公司会采用 F5 来做负载均衡,F5 应付单纯的 L4 和 L7 的流量是没有问题的,但进行 SSL 卸载时性能往往会急剧降低,F5 可以提供专门的加速卡来解决这个问题,但价格不便宜。所以,还需要专门环节来进行 SSL 卸载,常见的 Nginx 和 HAProxy 都可以执行这个任务。

  2010 年 Intel 出品的 Westmere 系列处理器之后,CPU 支持 AES-NI (Advanced Encryption Standard New Instructions)指令集,可以极大提高软件进行 SSL 加解密的速度(通常的数据是 5 倍左右)。但是,单纯采用 CPU 并不会直接享受这种好处,还需要对应的 OpenSSL 提供支持。想要知道自己的 OpenSSL 是否利用了 AES-NI 加速,可以用 OpenSSL 的命令行调试,加上-evp 参数,测试速度是否有明显变化即可。

# without EVP API

openssl speed aes-256-cbc 

Doing aes-256 cbc for 3s on 16 size blocks: 14388425 aes-256 cbc's in 3.00s

# with EVP API

openssl speed -evp AES256

Doing aes-256-cbc for 3s on 16 size blocks: 71299827 aes-256-cbc's in 3.00s

  客户端证书

  HTTP 的服务是很好验证的。一般来说,无论客户端是浏览器,还是其它工具,还是程序代码,同样的行为,结果都是相同的。所以只要一种客户端验证通过,基本就可以认为这个服务是没有问题的。HTTPs 的站点则不是如此。

  与 HTTP 不同,HTTPs 的连接建立是需要进行证书验证的,一定要从根证书开始形成完整的信任链条,连接才可以建立成功。然而,浏览器、普通工具、程序类库,它们所信任的根证书在管理上是互相独立的。比如,与浏览器不同的是,C#信任的根证书在 local machine store 或者 current user store 中,Java 信任的根证书在 JDK 安装目录下的 cacerts 目录中。

  因为浏览器的证书在使用中又可以持续更新,用户往往感知不到,如果“想当然”认为浏览器验证通过就万事大吉,很可能会出问题。比如国内有不少网站使用 WoSign 签发的证书,但老版本的 JDK 并步信任 WoSign 的根证书,用浏览器浏览没问题的网站,程序就会报错,除非手动导入证书。因为 WoSign 行为不端,前几天 Firefox, Chrome, Safari 等主流浏览器又取消了对它的信任,也就意味着 WoSign 证书有安全风险,所以已经内置 WoSign 根证书的程序也应当做对应的设置。

  服务器端证书

  还是上面的现象:用浏览器验证没有问题的 HTTPs 站点,用程序访问就有问题。这是为什么?

  在服务器上证书配置错误,只有最终证书,而缺少中级证书的情况,我见过几次了。通常,最终证书里包含了中级证书相关的信息,所以如果缺少中级证书,浏览器为了建立证书链,会做一次耗时的操作来获取中级证书,而且这一切都发生在 HTTPs 连接真正建立之前。更糟糕的是,不少浏览器为了“表现更好”,会想办法绕过这个问题。所以缺少中级证书的情况一直存在,一直不会被发现,而程序调用的速度总是上不去,甚至有一定几率报错(我就遇到过这个诡异的问题)。

  如果把证书链配置完全,还要注意证书链的大小。有一些网站的完整证书异乎寻常地大,达到若干 kb 甚至几十 kb,也就是说,在建立连接之前,就必须先传输这么多的数据。如果做单纯的 PC 网页浏览,或许不会有问题。但对于移动端和程序调用来说,这就是一场灾难。最好的办法,是用 OpenSSL 配合 WireShark 之类的工具,自己动手来测试。如果你熟悉 TCP 相关的知识,往往可以得到更好的优化方案。

  OCSP 和 CRL 也不可忽略。这两项技术用来保证撤回证书(让证书失效)的有效性。如果你仔细观察,会发现证书里都指定了对应的 OCSP 或者 CRL 的 URL,用来检查证书是否失效。按道理说,在每次建立 HTTPs 连接时,都应当进行 OCSP 或 CRL 检查。返回结果通常在 1k 左右,如果请求非常频繁,这个因素也应当考虑。

  SNI

  大家都熟悉“虚拟主机”的概念,它可以让多个域名对应到同一个 IP,让同一台服务器服务多个站点。在 HTTP 时代,可以在 header 中通过 host 来指定需要访问的域名,一切看起来都那么完美。

  但是在 HTTPs 时代,却没有这样的好事,传统的 HTTPs 服务很难让多个域名对应到同一个 IP。在进行到 HTTP 通讯之前,必须先建立验证证书建立连接。如果一个 IP 上绑定了多个域名,这个阶段服务器根本没法知道请求对应的是哪个域名,无疑会造成极大的不便。

  为了解决这种问题,SNI (Server Name Identification)应运而生了。这种技术说起来复杂,大家可以把它简单理解为“建立 SSL/TLS 通讯时的 host header”,这样就解决了一个 IP 只能配单张证书的问题。

  然而 SNI 的诞生历史并不长,许多客户端的支持都存在奇怪的问题。比如 JDK7 支持 SNI,但是 JDK8 的支持又有 bug。而且这种支持往往需要调用原生的 API 才可以实现,Resteasy 之类的类库并不支持。如果对 SNI 的支持有问题,即便配置正确也可能无法建立连接,因为服务端并不能识别此请求需要的证书。

  CDN

  CDN 已经是业界流行的技术了,对稍微大一点的网站来说,没有 CDN 几乎是不可想象的。HTTP 时代的 CDN 方案相当成熟,HTTPs 的情况则不是如此。

  要使用 HTTPs 的 CDN 服务,就要决定是否将证书交给 CDN 提供商。基于中国目前的商业信誉水平,把证书交给 CDN 提供商的风险不可步考虑。恶意揣测,别有用心的人一旦拿到证书,可以很方便地通过 DNS 劫持发起中间人攻击,而完全不被感知到。

  另外,HTTP 时代大家都喜欢将资源分散到多个不同的域名,因为建立连接的成本很低,而同一个域名的并发连接数有限。在 HTTPs 环境下,每次建立连接的成本高了很多,频繁下载和验证证书对移动设备和移动网络影响很大(尤其是证书很大的情况)。如果域名非常分散,影响就更加显著。所以在 HTTPs 时代,把域名收缩集中反而是更好的办法。

  内容及其它

  因为 HTTPs 的内容中无法引用 HTTP 的资源,所以应当保证网页中资源文件的链接都是 HTTPs 的。遗留的许多系统很可能并不注意这些事情,资源都采用绝对地址的形式,这样改起来工作量很大。如果要修改,最好一步到位,直接改成“协议相对 URL”。

  绝对地址 URL:http://www.a.com/b.css

  协议相对 URL://www.a.com/b.css

  这样浏览器就可以根据当前的协议,自动生成资源的绝对地址,无论是 HTTP 还是 HTTPs,都可以自由切换。

  如果资源都是自有的,切换 HTTPs 就相对容易。如果存在外部,尤其是 UGC 的资源,切换到 HTTPs 就很麻烦。如果是超链接,通常采用专门的跳转服务,也就是下面这样:

  https://link.my.com/target=www.you.com

  如果是图片这类资源,可以设定专门的程序将其抓取过来存放在自己的服务器上,再将地址替换掉即可。但是,这样做很可能要自己承担流量压力,同时还要承担恶意程序攻击的风险。

  如果是视频、游戏等富文本、交互复杂的资源,如果源站没有提供 HTTPs 的服务,多半只能忍痛割爱,放弃内嵌展现的形式了。

  最后再补充两点经验:

  1. 如果真的决定上 HTTPs,最好有个人把 OpenSSL 玩熟,否则很多问题会让你摸不着头脑,OpenSSL 是很好的调试工具,很方便定位问题。

  2. HTTPs 能解决运营商内容劫持的问题,如果是 DNS 劫持,要不要抱着“吾与汝偕亡”的态度上 HTTPs,需要慎重考虑,我知道不少网站是 HTTP 与 HTTPs 可以随时切换的,进可攻,退可守。

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-11/137212.htm

全站HTTPs,没那么简单相关推荐

  1. 10分钟免费开启全站https

    title: 10分钟开启全站https date: 2018-05-25 16:03:31 tags: https ubuntu 持续了1个多月的备案,今天收到短信终于下来了. 上篇水文,大概的记录 ...

  2. DZ全站HTTPS可行,基于网上教程的修改

    看了一下网上的修改方法,始终没有完成全站的HTTPS,浏览器依然没有显示绿色,虽然没有学过PHP,但是有些简单的地方还是看得懂的,比如三元运算符.经过在网上教程上的修改,终于全站HTTPS了,虽然说占 ...

  3. Redis 分布式锁没这么简单,网上大多数都有 bug

    Redis 分布式锁这个话题似乎烂大街了,不管你是面试还是工作,随处可见,「码哥」为啥还写? 因为看过很多文章没有将分布式锁的各种问题讲明白,所以准备写一篇,也当做自己的学习总结. 在进入正文之前,我 ...

  4. 聊聊全站HTTPS带来的技术挑战

    日前写的文章里了讨论了数据传输的安全性的问题,最后一部分提到了通过HTTPS解决数据传输安全性的方案.那么一个新问题又来了,实施全站HTTPS的过程中,我们可能会遇到哪些技术问题?所以我今天和大家一起 ...

  5. 安全开发Java:日志注入,并没那么简单

    本文分享自华为云社区<Java云服务开发安全问题解析--日志注入,并没那么简单>,原文作者:breakDraw. 案例故事 某个新系统上线了,小A在其中开发了个简单的登录模块,会在日志里记 ...

  6. 全站 HTTPS 来了(转载)

    全站 HTTPS 来了(转载) 转载:本文为腾讯Bugly原创文章. 最近大家在使用百度.谷歌或淘宝的时候,是不是注意浏览器左上角已经全部出现了一把绿色锁,这把锁表明该网站已经使用了 HTTPS 进行 ...

  7. 免费申请 HTTPS 证书,开启全站 HTTPS

    HTTP 报文以明文形式传输,如果你的网站只支持 HTTP 协议,那么就有可能遭受到安全攻击.你可以使用 Google 浏览器打开一个 HTTP 协议网站,会发现 Chrome 在网址的左边将这个网站 ...

  8. 网站域名服务器加密,网站实现全站https加密可以防止DNS劫持吗?

    DNS劫持一般指域名劫持,它是互联网攻击的一种方式,通过攻击域名解析服务器(DNS),或伪造域名解析服务器的方法,把目标网站域名解析到错误的IP地址从而实现用户无法访问目标网站的目的或者蓄意或恶意要求 ...

  9. 阿里独家揭秘:淘宝全站HTTPS 改造细节

    2015年阿里巴巴将旗下淘宝.天猫(包括移动客户端)全站启用HTTPS加密,并顺利通过"双十一"考验,成为全球最大的电商平台全站HTTPS改造案例.近日,阿里云栖社区发布一篇技术贴 ...

最新文章

  1. android获取地址api,如果在Android中使用位置API给出纬度和经度,如何获取地址
  2. 计算机与USB沟通方式
  3. python装饰器 property_Python中@property装饰器的使用技巧性解析(代码示例)
  4. python字符串操作符结果没显示_Python字符串格式化 (%操作符)
  5. Python3的tkinter写一个简单的小程序
  6. oracle缓存怎么看,Oracle从缓存里面查找真实的执行计划
  7. python字符串find_Python字符串find()
  8. 正在启动文档服务器,正在启动远程服务器
  9. 短视频无水印解析网站源码
  10. 计算机科学导论实验,《计算机科学导论》实验.doc
  11. python解码gbk_python编码:gbk编码与解码
  12. Windows实用工具推荐
  13. CNA, FCoE, TOE, RDMA, iWARP, iSCSI等概念及 Chelsio T5 产品介绍
  14. 30岁人生进度条_你的人生进度条,只剩下最后的1%
  15. Java:如果优雅地打印出完美日志
  16. Python实战——全球疫情数据采集, 并做可视化
  17. 【HTML响应式项目】成人教育官网前端页面(HTML+CSS+JS实现三端适应)
  18. Docker中搭建RTMP直播流服务器
  19. u盘linux反应好慢,U盘加载速度缓慢的原因及解决小技巧
  20. ASP.NET C#物流管理系统 web快递物流系统源码

热门文章

  1. suse linux10安装教程,Windows 10现已支持安装SUSE Linux子系统 附安装教程
  2. 一站式管理上千连锁门店的北极星指标
  3. 烧开水理论-证明自己存在的三个过程
  4. Linux access()函数 使用 http://blog.163.com/lqy_super/blog/static/199751021201302351831330/
  5. 基于matlab的心电信号处理毕业论文,浅议仿真基于MATLAB的“数字信号处理”仿真实验毕业论文范文...
  6. 魅族手机文件删除-通知栏警告流程分析(上)
  7. Spring Cloud Gateway系列【4】初始化加载流程源码解析
  8. 手机剪辑快手短视频如何批量去掉片头和片尾
  9. 数学建模第一天:数学建模工具课之MATLAB的入门
  10. Dart 学习笔记一(操作符、方法与异常)