当前,电商平台会采用基于Docker的容器技术来承载618大促期间的一些关键业务版块,包括最简单的商品图片展现、订单详情页面等等。web
经过容器化改造,电商平台的每一个业务版块解耦,能够独立开发、部署和上线,从而让后台业务系统具有更高的稳定性、可扩展性和安全性,即使某个环节出现问题,也能保障平台高峰值期间的平稳运行。算法
镜像是Docker容器的基石,只有经过它才能够建立容器,而Registry是存放Docker镜像的仓库。但在实际应用中,因为须要频繁地从Registry下载镜像运行容器应用(好比发布新版本,打补钉等情形),其间的文件传输成为镜像分发的瓶颈,安全
P2P加速镜像下载是有效的解决方案,但如何确保用户数据在公有云环境下的P2P传输安全性尤其关键,本文主要从链路层和业务层的安全加固,阐述了公有云Docker镜像P2P加速的安全性。服务器
在使用Docker运行容器化应用时,宿主机一般先要从Registry服务(如Docker Hub)下载相应的镜像(image)。这种镜像机制在开发环境中使用仍是颇有效的,团队成员之间能够很方便地共享一样的镜像。然而在实际的生产环境中,当大量主机须要同时从Registry下载镜像运行容器应用时(好比发布新版本,打补钉等情形),Registry 服务每每会成为镜像分发的瓶颈,应用镜像须要较长时间才能传送到全部主机上,使得应用发布的周期大大延长。网络
很多企业提出了P2P加速镜像下载的解决方案,但都是私有云及内部环境的使用场景,在公有云未获得使用。其中很大一部分缘由是公有云使用P2P的安全性问题,如何确保用户数据在P2P传输中是安全的成为了其中的难点。咱们就该问题设计实现了确保用户数据安全的P2P镜像分发系统。本文就其安全性展开阐述。架构
华为P2P容器镜像分发系统示例图分布式
华为P2P容器镜像分发系统包含3个组件:客户端代理(Proxy)、BT客户端和BT Tracker。加密
客户端代理(Proxy)spa
客户端代理部署在集群的每一个节点中,配置为Docker的Http Proxy,截获Docker Daemon的镜像下载请求,通知Client下载,并最终将镜像导入到Docker daemon中。设计
BT客户端
部署在集群节点的BT客户端和Tracker共同组成了一个完整的P2P文件传输系统。在整个镜像的分发过程当中,它们利用BT协议完成镜像下载。
BT Tracker
Tracker是BT系统的一部分,它存储了BT客户端下载过程当中所须要的元数据信息和种子信息,并协助各个BT客户端完成整个通讯过程。
首先,咱们限制了跨集群的P2P下载,最大限度防止租户间的数据泄露。
以后,在链路层面的安全性和业务层面的安全性作了加强。
一想到链路安全,咱们首先会想到的是加密。
对称加密服务端和客户端采用相同的秘钥加密和解密,只要这个秘钥不公开,而且秘钥足够安全,那么链路就是安全的。可是在网络中都使用相同的对称加密秘钥,无异于公开传输,若是秘钥被劫持,那么就能够篡改链路的全部数据。
而后咱们确定会想到HTTPS,它是怎么实现安全的?咱们先来了解下HTTPS的实现方式。
在具体的数据传输过程当中,HTTPS采用的是对称加解密的方式,可是它在链接创建时增长了握手协商的过程。
什么是公钥:
公钥是非对称加密中的概念。非对称加密算法方式基于一个秘钥对,数据经过一个秘钥加密,只有经过另一个秘钥才能解密。服务端保存私钥,公钥发给客户端。
咱们假设一个场景,咱们生成秘钥对,客户端经过公钥加密数据,服务端经过私钥解密。那么即便用户劫持到公钥,他没法劫持篡改用户的数据。然而从服务端到客户端的链路仍是不安全的。
HTTPS借助了非对称加密的这个特性,确保对称机密秘钥的传输是安全的,最后采用对称加密传输数据。
证书的意义:
然而,这又产生了一个新的问题,公钥被劫持了怎么办?
HTTPS固然不会这么简单就被劫持,为了解决上诉问题,它引入了数字证书和第三方机构。证书是由第三方认证机构经过公钥签发的,其中不只包含公钥,还包含签名( 由签发节点的私钥加密产生)、有限期、签发机构、网址、失效日期等。
HTTPS返回的不在是私钥,而是证书。当客户端接收到证书,会对证书作一个校验。在各个机器中都会维护一个权威的第三方机构列表(包括它们的公钥),当客户端须要公钥时,可根据颁发机构信息本地查找到公钥。客户端经过颁发机构的公钥验证签名的有效性和证书的完整性,保证公钥未被篡改。
HTTPS经过私钥、证书、和CA(签发机构)确保了链路的安全性。在P2P场景下,BT Client之间是对等的,他们相互传输数据,更应该是服务端校验客户端,而不是HTTPS的客户端校验服务端。而且因为BT Client是部署在用户的节点,还须要考虑证书和私钥都被劫持的风险。
咱们是怎么作的
BT Client间传输数据确定是须要加密的,防止链路的数据被劫持。可是只增长HTTPS,虽然链路被加密,可是客户端可能会被假冒,只要假冒者不校验服务端的证书,直接和服务端握手,就能从其余BT Client获取到他想要的数据。
咱们借鉴HTTPS的实现,采用了双向验证的模式。
须要有证书,首先须要一个统一的CA(签发机构),所以咱们在Tracker中保存证书和私钥作为签发机构,Proxy获取种子的同时返回CA,用户校验客户端的证书。
而后,只使用一个证书对而且放在Bt Client是危险的,颇有可能性被入侵截获到证书,所以咱们获取证书的方式改成从Tracker获取,获取种子的同时获取Tracker生成的临时证书私钥对,把它加入BT Client的下载队列。在BT Client开始相互链接时,首先相互确认对方的证书的有效性(签名、签发机构等信息),校验经过后才能请求并相互下载数据。
这种方式下,Client之间的链路是安全的。
咱们在Proxy中须要劫持Docker的请求,由于Docker在不配置时访问Registry采用的是HTTPS,所以Proxy劫持Docker请求就必须和Docker保持HTTPS链接。
咱们让客户端代理只监听localhost端口,杜绝外部使用该代理的可能性。同时,客户端代理绑定一套临时生成的签发给registry域名的自签名证书和CA证书,用于劫持Docker Daemon的请求,并将CA证书添加到机器的信任证书当中。
代理绑定的证书只保存在内存中,即便经过特定方式获取到当前节点的CA证书和服务端证书,也没法截取其余节点数据。
首先,为了确保链路的安全,Regstry、Tracker都绑定从权威第三方机构购买的HTTPS证书私钥对。Proxy和BT Client在访问它们的时候都会去校验证书的有效性,只要在证书有效的状况下才发送请求,这从根源上杜绝了Regstry、Tracker被假冒的可能。
在确保链路安全后,咱们还作了一层业务安全加固。首先咱们先了解下JWT Token。
Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该Token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明通常被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也能够增长一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
在咱们使用Docker命令下载镜像时,Docker首先会到Registy获取Token,在以后的获取镜像层的过程当中,多会带上该Token用于鉴权。其中Token时组要包含如下信息:
利用JWT Token中自带解析Token证书这个特性,咱们在BT Client间通讯又增长了Token的校验。在前文中的证书校验经过后,客户端须要发送Token给服务端用于校验。为了防止Token被假冒,入侵者采用第三方生成,咱们使用服务端截从Docker截取的Token中的证书解析校验客户端的Token,杜绝这种状况。
同时,Proxy 访问Tracker的接口也会带上这个Token,Tracker会校验Token的权限,完成业务层的安全验证,防止证书和种子被盗取。
经过以上链路层和业务层的安全加固,用户数据被盗取的可能性已几乎为零。若是你们有更好的建议,欢迎点评。
点击这里,了解更多精彩内容