电商网站https实践之路——系统改造篇(代码片段)

皖南笑笑生 皖南笑笑生     2022-12-06     399

关键词:

首先是要让系统支持HTTPS。 需要有接入层来统一处理TLS握手。页面资源的替换也存在一些坑。对于不同的域证书选择上也要注意,最好的方式是提前整理好域列表绑定成一张支持多域名和泛域名的证书。大多数互联网公司的CDN资源都是租用的,CDN上证书如何来处理。最后,HTTPS的测试策略如何实施,来保证页面不会出现Mix content阻塞和net: ERR_INSECURE_RESPONSE错误。

1. HTTPS接入层的设计

开通服务端的443端口,用户发起HTTPS请求服务端才能正常响应。然而,一般的电商网站可不仅仅只是一台Tomcat,都会考虑性能和各种架构优化。基本上会是:客户端 -> CDN(静态缓存+动态加速) -> 四层负载均衡(F5/Ctrix/LVS) -> 七层负载均衡(Niginx)-> Web服务器(Apache) -> 应用服务器(Tomcat)-> 数据层。难道每一层都需要开启443端口进行TLS握手嘛?我们知道TLS握手过程会徒增至少两次RTT时间,这样的性能损耗我们是不能接受的。
因此,需要尽早完成TLS握手,对于后端仍使用HTTP通信。包括Facebook淘宝等都提到过统一接入层的架构来“卸载”TLS协议。如下图所示,我们的接入层设计在CDN之后,应用服务器之前,是内外网之间的屏障。对于静态资源,命中CDN缓存后直接得到响应;对于动态回源请求,在HTTPS接入层完成握手过程,upstream到系统走80端口。


通过HTTPS接入层的建设,
1. 性能得到提升。一方面,传输的RTT减少了,另一方面,应用系统本身不存在握手来消耗cpu;
2. 实现了流量的统一调度。未来优化、升级、管控流量都集中在HTTPS接入层上。

2. 页面资源的替换

2.1 令人讨厌的Mix Content

混淆内容(Mix Content),简单来说是指HTTPS页面中混淆了HTTP请求。
通常当用户代理通过一个安全信道(如HTTPS)从一个特定站点加载一个资源(如Web页面)时,用户代理可以获得关于该资源的用户安全和隐私状态的三种判断:认证性(authenticated)、加密性(encrypted)及数据完整性(data integrity)。这些判断对于防止资源内容被篡改或窃听,抵御中间人攻击非常重要。但如果这些经过认证和加密的资源再通过一个非安全的信道(如HTTP)请求其他的子资源(如脚本、图片等),该资源的安全性就不再能够得到保证,从而处在一个混合状态,而事实上这一情况非常普遍。
因此,W3C颁布了针对Mix Content的安全标准,描述了用户代理、浏览器在处理加密和认证的文档时,如何禁止(disallow)对经过非加密方式或非授权连接所加载的子资源进行渲染或执行。
浏览器遵循Mix Content标准,并在控制台打印出报错信息:

Mixed Content: The page at 'https://product.suning.com/0000000000/129564647.html?srcpoint=index3_homepage1_32618213038_prod01' was loaded over HTTPS, 
but requested an insecure image 'http://image.suning.cn/uimg/PCMS/prmtExposition/149310522123830711.png'. 
This content should also be served over HTTPS.

Mix Content又可以分为两类:
Blockable:浏览器严格禁止加载这类资源。比如JavaScript、CSS
Optionally-blockable:可商榷的混淆内容,现代浏览器默认会加载这类资源,同时会在控制台打印警告信息。比如<img><video><audio><source>标签加载的内容。
值得注意的是,IE 8及以下并不属于现代浏览器范畴,不区分BlockableOptionally-blockable,都会弹框警告。

2.2 解决Mix Content

在你确定全站都支持HTTPS,并且全站替换为HTTPS访问前(当然这是一个相对漫长,需要过渡的过程)。解决Mix Content最好的方案是使用相对协议。对于同时支持HTTPS和HTTP的资源,引用的时候要把引用资源的URL里的协议头去掉,浏览器会自动根据当前场景是HTTPS还是HTTP来给资源URL补上协议头的,可以达到无缝切换。
比如:

<a href="//product.suning.com/0000000000/129564647.html?srcpoint=index3_homepage1_32618213038_prod01" >

简而言之,就是将URL的协议(http、https)去掉,只保留//及后面的内容。这样,在访问https的网站时,浏览器会通过https加载请求,在访问http的网站时,浏览器会通过http加载请求。
相对协议同样适用于css样式中,比如:

.imgview .mask-rright:0;cursor:url(images/next.cur),pointer;cursor:url(//res.suning.cn/project/pdsWeb/csspc/images/next.cur),pointer\\0    

另外,在使用相对协议的时候存在一个坑。App原生接口并不能默认适配相对协议,比如,

OkHttp.Request.Builder() .url(//image.suning.com/1.jpg) .build()

恐怕客户端就要抛异常出来了。而大多数情况下存在这样的场景,客户端加载的请求是通过服务端返回的报文获取的,如下图所示,对于服务端系统相对协议是全局替换的,这样就会导致客户端加载请求失败。因此,就需要客户端开发对底层进行再封装,适配相对协议。

2.3 X-Request-Url的定义和使用

除了Mix Content问题,在实际HTTPS页面改造过程中,我们也遇到了另一类问题,其引发的原因是:TLS握手在统一层处理完毕,后端应用服务器无法获取原始请求协议。即是说,无论是HTTPS请求亦或是HTTP请求到达后端应用服务器都是HTTP请求。
这会造成什么问题呢?我们有部分业务逻辑跳转是在服务端根据Url拼接的,这就会导致有可能一个HTTPS请求302跳转到HTTP,触发Mix Content,最终阻塞。
我们以单点登录系统鉴权过程为例,用户在未登录情况下访问https://my.suning.com/如下图所示。

1. 用户未登录情况下,访问https://my.suning.com/,authID不存在,;
2. 请求经过接入层处理后,卸载为http://my.suning.com到业务系统,注意这时候s就已经丢失了;
3. 业务系统响应要求用户端跳转到登录系统去鉴权,同时将原页面Url: http://my.suning.com拼接在targetUrl上;
4. 用户端跳转到登录系统,发起登录请求
5. 登录请求到Passport系统,登录完成,302回跳到http://my.suning.com
6. 用户就访问到http://my.suning.com,而不是https://my.suning.com了!
如何解决类似这样的问题?我们在接入层定义了一个X-Request-Url的请求头部:

**Key**:    
X-Request-Url
**Value**:
原始协议头部(https://|http://)+ 域名 + 去参URL

这样保证了服务端能够通过X-Request-Url获取用户原始的协议头部。

3. 证书选择的细节

服务双方TLS握手过程中使用的证书需要得到权威的CA(Certificate Authority)来认证,否则通信过程就会因为证书不可信而被阻塞(自签名证书是最差的方式,不会得到浏览器信任,不在这里考虑)。如下图所示,是证书状态校验的完整过程。

那么,在证书的选择上,我们应该注意哪些细节呢?
首先,证书可以分为三类:
DV证书:Domain Validation Certificate, 信任等级普通,只需验证网站的真实性(即whois信息中的管理员邮箱验证)便可颁发证书保护网站。
OV证书:Organization Validation Certificate,信任等级强,须要验证企业的身份,审核严格,安全性更高。
EV证书:Extended Validation Certificate,认证最为严格,安全级别最高。一般会要求提供纸质材料,一般用于银行证券等金融机构。同时,大部分浏览器只针对EV证书进行CRL/OSCP的吊销检查。
而在选择证书上,我们考虑到以下多个方面:
1. 证书主机名匹配:申请的证书必须与域名匹配,否则访问时会有不匹配警告。只要有一个DNS解析指向你的TLS服务器,就必须保证你的证书包括DNS域名。
2. 是否支持多域名和泛域名:多域名和泛域名是不同的概念。多域名证书是指可以匹配多个不同的域,比如suning.com、suning.cn、suning.vip,而泛域名是指可以通过通配符匹配子域名,比如*.suning.com的泛域名证书可以匹配www.suning.com、passport.suning.com等。
DV、OV和EV对多域名和泛域名的支持如下:

证书类型单域名多域名泛域名多泛域名
DV证书支持支持不支持不支持
OV证书支持支持支持支持
EV证书支持支持不支持不支持

因此建议选择OV类证书。天猫的证书就是采用多泛域名的OV型:

*.tmall.com证书支持的域名:

DNS Name=*.tmall.com
DNS Name=*.1688.com
DNS Name=*.3c.tmall.com
DNS Name=*.alibaba.com
DNS Name=*.aliqin.tmall.com
DNS Name=*.alitrip.com
DNS Name=*.aliyun.com
...
DNS Name=taobao.com
DNS Name=taopiaopiao.com
DNS Name=tmall.hk
DNS Name=ttpod.com
DNS Name=xiami.com
DNS Name=tmall.com

3.签名算法:为了保证证书的有效性,CA在签发证书时会对证书进行数字签名。数字签名安全性依赖两个方面:一个是CA的私钥长度,一个是散列算法的强度。散列算法建议使用SHA256(SHA1由于算法强度等问题已经被CA逐渐废弃)。
SHA256存在的最大问题是兼容性问题,SP2版本及以下的Win XP以及Android 2.3版本以前的移动设备不支持SHA256。
4. 证书链:一般证书链包括域名证书-中间证书-根证书,是一个能追溯到可信根证书的有序证书列表。如下所示:

- Certum Trusted Network CA
-- WoSign OV SSL CA
--- *.suning.com

证书链如果过长会降低TLS握手速度。因此建议证书链只要包含必要的证书即可。

4. CDN上证书的处理方法

CDN(Content Delivery Network, 内容传输网络)是互联网企业都会使用到的网络静态缓存和动态加速平台。然而由于自身能力限制,并不是所有电商都会自建CDN网络(自建网络基础设施的性价比着实不高),大部分电商都会购买第三方商用的CDN资源。
那么问题来了,如果要启用HTTPS,私钥必须要提供给第三方CDN。这就带来了安全隐患,毕竟一旦私钥泄露,HTTPS将一无是处。

那么有没有方案,能避免暴露私钥给到CDN厂商呢?

4.1 CDN使用双证书策略

这是一种治标不治本的方案。如下图所示,通过双证书的方案,CDN相当于反向代理,部署CDN自己的证书和私钥,与用户之间通信。CDN与服务端之间再使用服务端证书和私钥通信。这样,既保证服务端私钥不需要提供给CDN,又保证了HTTPS通信。

然而,CDN自己的私钥泄露后,黑客仍能破译用户的报文,劫持用户信息,进行中间人攻击。

4.2 CDN只启用四层加速

对于动态请求(no cache),CDN通过路径规划可以提高网络传输性能,起到加速的效果,如下图。

对于这类不需要缓存的请求,CDN完全可以基于四层TCP代理,可支持任何基于TCP传输协议的上层协议。这样CDN上就不再需要进行TLS握手,TCP以上层协议对CDN而言是黑盒。适用于购物车、提交订单、登录等场景。

4.3 CDN实现Keyless方案

Keyless解决方案是由CloudFlare公司提出的一种无证书部署解决方案(已经开源,https://github.com/cloudflare/keyless)。可以不把证书私钥给第三方,改为提供一台实时计算的 Key Server 即可。CDN 要用到私钥时,通过加密通道将必要的参数传给 Key Server,由 Key Server 算出结果并返回即可。整个过程中,私钥都保管在自己的 Key Server 之中,不会暴露给第三方。

如上图所示,
第一步 用户向CDN发起TLS握手
第二步 CDN返回公钥和证书给用户
第三步 用户端通过公钥(Public key)生成Premaster secrect(用于解密报文),发送给CDN
第四步 CDN拿到加密的Premaster secrect。由于没有私钥(Privacy Key),将Premaster secrect返回给服务端Keyless服务器。Keyless通过私钥解密出Premaster secrect返回给CDN。
第五步 完成TLS握手,基于Premaster secrect服务双方进行加密通信。

5. HTTPS测试策略

全站HTTPS改造对应用系统的调整还是比较大的,测试覆盖面广。尤其需要注意两方面:一方面是资源加载都需要使用相对协议,否则Mixed Content会阻塞请求加载;另一方面,还要保证到所有接口都支持HTTPS,否则会报net: ERR_INSECURE_RESPONSE错误。
因此,对于测试人员来说,完全依靠手工测试HTTPS不现实,需要通过测试技术,测试策略设计,和测试工具进行保证对应系统的功能质量。如下图所示,全站HTTPS功能测试主要包括四个方面。

1. 开发人员提交代码更新,在构建时,我们会通过Jenkins平台,利用shell脚本扫描SVN代码库,是否还有未修改成相对协议//的http://。
2. 测试环境爬虫验证,研发提测后,使用爬虫程序对对应的应用进行扫描,使用正则表达式和页面请求返回code(Mixed Content/net: ERR_INSECURE_RESPONSE),进行验证,来爬取有问题的页面。
3. 测试环境,核心主流程使用HTTPS,手工验证。当然大部分的bug在前两部中应该可以被修复掉。
4. 最终,HTTPS版本预发到生成环境上,只要我们不做强制HTTPS,用户是感知不到的。再通过引流工具引流用户的HTTP流量,改造成HTTPS流量,进行线上环境的引流测试。

至此,全站HTTPS系统改造篇完结,下一篇我们开启对HTTPS的性能优化。

电商网站https实践之路——灰度上线篇

对于电商而言,不能因为技术的升级就轻易影响了线上业务,毕竟最宝贵的是用户流量。当我们一鼓作气完成了系统的HTTPS改造和优化后,上线过程则是小心翼翼逐步完成的,毕竟这么大的调整动作牵一发而动全... 查看详情

电商网站https实践之路——性能优化篇(代码片段)

...作。很多文章都集中在服务端的性能优化上,但对于电商行业而言,大部分的用户流量源于App,因此客户端的性能优化配合服务端才能使收益最大化。1.HTTPS带来的 查看详情

电商网站https实践之路——性能优化篇

...的工作。很多文章都集中在服务端的性能优化上,但对于电商行业而言,大部分的用户流量源于App,因此客户端的性能优化配合服务端才能使收益最大化。1.HTTPS带来的负担凡事都有两面性。1.1增加的传输延时使用HTTPS传输增加的... 查看详情

申通的云原生实践之路:如何实现应用基于容器的微服务改造?(代码片段)

【题目大意】ByteotianBitBank(BBB)拥有一套先进的货币系统,这个系统一共有(n)种面值的硬币,面值分别为(b1,b2,...,bn).但是每种硬币有数量限制,现在我们想要凑出面值(k)求最少要用多少个硬币.(nle200,1lek,b_ile100000)【分析】看一眼题目,... 查看详情

项目实践记一次对后端服务进行跨域改造和https升级的探究和实践(代码片段)

...于防止跨站脚本攻击(XSS),即攻击者将别的网站缓存在浏览器的信息(token,cookie等)发到自己的服务器上,亦或者利用这些信息伪装成用户进行攻击操作。同源策略禁止了这一可能,就算用户不... 查看详情

(功能篇)回顾bug管理系统mantis优化改造经历(代码片段)

...及跟踪。更重要的是其开源,不需要负担任何费用。官方网站:https://www.mantisbt.org/搭建环境网上很多教程,不再赘述。最初是apache,php,mysql单独安装后,配置使用的。被版本兼容整惨了。最终采用了集成工具wamp。方便省事。优化... 查看详情

项目实践记一次对后端服务进行跨域改造和https升级的探究和实践(代码片段)

...题产生的原因2.跨域问题的解决方案①跨域方案理论②CORS实践二、https接口改造1.Mixed-content错误2.HTTPS原理3.HTTPS实践①升级步骤②获取SSL证书③Spingboot配置④引入插件后记总结起因项目背景是之前做的玛嘉环境物联网平台,其... 查看详情

go-zero成长之路—微服务电商实战系列(六条件查询)(代码片段)

...传送门查看该系列其他文章:go-zero成长之路—微服务电商实战系列(五、RPC定义)go-zero成长之路—微服务电商实战系列(四、API定义)go-zero成长之路—微服务电商实战系列(三、表结构篇)go-zero成长... 查看详情

disconf实践指南:改造篇

上一篇文章Disconf实践指南:使用篇介绍了如何在项目中应用disconf,虽然实现了分布式配置的实时刷新,但是我们希望能够去除所有的配置文件,把配置都交给disconf管理,本地只需要实现配置监听接口就好了。改造包括:统一配... 查看详情

大数据之路之linux篇(代码片段)

目录1.Linux简介篇1.1为什么要学习Linux1.2Linux是什么1.3Linux创始人1.4Linux主要发行版本1.5Linux和Unix前世今生2.Linux系统基础篇2.1Linux安装2.2Linux用户管理、组管理、权限管理2.3Linux磁盘基础知识、分类、分区、挂载、卸载、扩容等操作&#... 查看详情

vue后台管理系统实践方案总结(代码片段)

这个是一个电商管理系统的前端项目的笔记,这个项目主要包括登录/退出功能、主页布局、用户管理模块、权限管理模块、分类管理模块、参数管理模块、商品管理模块、订单管理模块等功能,我把里面部分的功能进行... 查看详情

亿级pv的elk集群实践之路(代码片段)

前言笔者多年前便维护过ELK,但是由于站点日志流量及服务器数量并不是很多基本都是单机搞定。然而光Web服务器就400+,Nginx日志大小每天50G+,加上其他业务系统日志,之前单机ELK显然不足以支撑现有的业务场景。规划篇目前... 查看详情

followmedevops实践之路(代码片段)

...可以大幅度提高开发效率的工具.我们团队也不断探索、实践,最终形成了现有的一套体系,从最初的手动发布到现有的自动化,从起始的繁琐易乱到当下的简洁明了。我们希望将我们曾经踏过的脚印与大家一起分享,为各位展... 查看详情

git+jenkins学习之路(十四)之自动化脚本部署实践(代码片段)

一、环境说明和准备1、环境说明主机名IP地址角色系统deploy-server192.168.56.12发布Centos7.4web192.168.56.13web服务器,nfs服务器Centos7.42、服务器准备工作(1)发布机前期准备a.增加普通用户并配置密码[[email protected]~]#useraddwww[[email... 查看详情

单片机成长之路(51基础篇)-023n76e003系统时钟切换到外部时钟(代码片段)

   N76e003切换到外部时钟的资料很少(因为N76e003的片子是不支持无源晶振的,有源晶振的成本又很高,所以网上很少有对N76e003的介绍)。有图有真相:代码如下:main.c1#include<N76E003.H>2#include<SFR_Macro.h>3#include<Function_... 查看详情

大型网站架构系列:电商网站架构案例

...站架构是一个系列文档,欢迎大家关注。本次分享主题:电商网站架构案例。从电商网站的需求,到单机架构,逐步演变为常用的,可供参考的分布式架构的原型。除具备功能需求外,还具备一定的高性能,高可用,可伸缩,可... 查看详情

大型网站架构系列:电商网站架构案例

...站架构是一个系列文档,欢迎大家关注。本次分享主题:电商网站架构案例。从电商网站的需求,到单机架构,逐步演变为常用的,可供参考的分布式架构的原型。除具备功能需求外,还具备一定的高性能,高可用,可伸缩,可... 查看详情

通过代码审计找出网站中的xss漏洞实战(代码片段)

...,内容有一些关联性,其中手工XSS挖掘篇地址为快速找出网站中可能存在的XSS漏洞实践(一)https://segmentfault.com/a/1190000016095198本文主要记录通过代码审计的方式进行XSS漏洞挖掘,分为了找出关键位置,正 查看详情