公有云Docker镜像P2P加速之路:安全篇
一、问题
在使用Docker运行容器化应用时,宿主机通常先要从Registry服务(如Docker Hub)下载相应的镜像(image)。这种镜像机制在开发环境中使用还是很有效的,团队成员之间可以很方便地共享同样的镜像。
然而在实际的生产环境中,当大量主机需要同时从Registry下载镜像运行容器应用时(比如发布新版本,打补丁等情形),Registry 服务往往会成为镜像分发的瓶颈,应用镜像需要较长时间才能传送到所有主机上,使得应用发布的周期大大延长。
对此,许多企业提出了P2P加速镜像下载的解决方案,但都是私有云及内部环境的使用场景,在公有云未得到使用,主要原因是用户担心数据在P2P传输中会出现安全问题。本文将重点阐述确保用户数据安全的P2P镜像分发系统。
二、架构
华为云容器镜像服务SWR的P2P容器镜像分发系统包含3个组件:客户端代理(Proxy)、BT客户端和BT Tracker。
客户端代理(Proxy)
客户端代理部署在集群的每个节点中,配置为Docker的Http Proxy,截获Docker Daemon的镜像下载请求,通知Client下载,并最终将镜像导入到Docker daemon中。
BT客户端
部署在集群节点的BT客户端和Tracker共同组成了一个完整的P2P文件传输系统。在整个镜像的分发过程中,它们利用BT协议完成镜像下载。
BT Tracker
Tracker是BT系统的一部分,它存储了BT客户端下载过程中所需要的元数据信息和种子信息,并协助各个BT客户端完成整个通信过程。
三、安全
首先,我们限制了跨集群的P2P下载,最大限度的租户间的数据泄露。
之后,在链路层面的安全性和业务层面的安全性做了增强。
1、链路安全
一想到链路安全,我们首先会想到的是加密。
对称加密服务端和客户端采用相同的秘钥加密和解密,只要这个秘钥不公开,并且秘钥足够安全,那么链路就是安全的。但是在网络中都使用相同的对称加密秘钥,无异于公开传输,如果秘钥被劫持,那么就可以篡改链路的所有数据。
然后我们肯定会想到HTTPS,它是怎么实现安全的?我们先来了解下HTTPS的实现方式。
在具体的数据传输过程中,HTTPS采用的是对称加解密的方式,但是它在连接建立时增加了握手协商的过程。
什么是公钥:
公钥是非对称加密中的概念。非对称加密算法方式基于一个秘钥对,数据通过一个秘钥加密,只有通过另外一个秘钥才能解密。服务端保存私钥,公钥发给客户端。
我们假设一个场景,我们生成秘钥对,客户端通过公钥加密数据,服务端通过私钥解密。那么即使用户劫持到公钥,他无法劫持篡改用户的数据。然而从服务端到客户端的链路还是不安全的。
HTTPS借助了非对称加密的这个特性,确保对称机密秘钥的传输是安全的,最后采用对称加密传输数据。
证书的意义:
然而,这又产生了一个新的问题,公钥被劫持了怎么办?
HTTPS当然不会这么简单就被劫持,它引入了数字证书和第三方机构。证书是由第三方认证机构通过公钥签发的,其中不仅包含公钥,还包含签名( 由签发节点的私钥加密产生)、有限期、签发机构、网址、失效日期等。
HTTPS返回的不在是私钥,而是证书。当客户端接收到证书,会对证书做一个校验。在各个机器中都会维护一个权威的第三方机构列表(包括它们的公钥),当客户端需要公钥时,可根据颁发机构信息本地查找到公钥。客户端通过颁发机构的公钥验证签名的有效性和证书的完整性,保证公钥未被篡改。
HTTPS通过私钥、证书、和CA(签发机构)确保了链路的安全性。在P2P场景下,BT Client之间是对等的,他们相互传输数据,更应该是服务端校验客户端,而不是HTTPS的客户端校验服务端。并且由于BT Client是部署在用户的节点,还需要考虑证书和私钥都被劫持的风险。
我们是怎么做的
Client之间
BT Client间传输数据肯定是需要加密的,防止链路的数据被劫持。但是只增加HTTPS,虽然链路被加密,但是客户端可能会被假冒,只要假冒者不校验服务端的证书,直接和服务端握手,就能从其他BT Client获取到他想要的数据。
我们借鉴和HTTPS的实现,采用了双向验证的模式。
需要有证书,首先需要一个统一的CA(签发机构),因此我们在Tracker中保存证书和私钥做为签发机构,Proxy获取种子的同时返回CA,用户校验客户端的证书。
然后,只使用一个证书对并且放在Bt Client是危险的,很有可能性被入侵截获到证书,因此我们获取证书的方式改为从Tracker获取,获取种子的同时获取Tracker生成的临时证书私钥对,把它加入BT Client的下载队列。在BT Client开始相互连接时,首先相互确认对方的证书的有效性(签名、签发机构等信息),校验通过后才能请求并相互下载数据。
这种方式下,Client之间的链路是安全的。
(1)链路经过证书加密,直接截获链路是不可行的
(2)即使仿照BT Client的方式,由于Client每个连接都需要进行双向的证书校验,想通过这个方式截获数据就必须请求Tracker去获取,而访问Tracker首先是HTTPS的,然后我们还做了业务层的安全校验(下文业务层安全会提及),也是不可行的。
Docker Daemon到 Proxy
我们在Proxy中需要劫持Docker的请求,因为Docker在不配置时访问Registry采用的是HTTPS,因此Proxy劫持Docker请求就必须和Docker保持HTTPS连接。
我们让客户端代理只监听localhost端口,杜绝外部使用该代理的可能性。同时,客户端代理绑定一套临时生成的签发给registry域名的自签名证书和CA证书,用于劫持Docker Daemon的请求,并将CA证书添加到机器的信任证书当中。
代理绑定的证书只保存在内存中,即使通过特定方式获取到当前节点的CA证书和服务端证书,也无法截取其他节点数据。
从用户节点到Registry、Tracker
首先,为了确保链路的安全,Regstry、Tracker都绑定从权威第三方机构购买的HTTPS证书私钥对。Proxy和BT Client在访问它们的时候都会去校验证书的有效性,只要在证书有效的情况下才发送请求,这从根源上杜绝了Regstry、Tracker被假冒的可能。
2、业务加密
在确保链路安全后,我们还做了一层业务安全加固。首先我们先了解下JWT Token。
Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
在我们使用Docker命令下载镜像时,Docker首先会到Registy获取Token,在之后的获取镜像层的过程中,多会带上该Token用于鉴权。其中Token时组要包含以下信息:
(1)用户信息
(2)资源信息,为操作的镜像和namespace的名称
(3)权限信息:是否有PULL/PUSH权限
(4)用于解析Token签名的证书
利用JWT Token中自带解析Token证书这个特性,我们在BT Client间通信又增加了Token的校验。在前文中的证书校验通过后,客户端需要发送Token给服务端用于校验。为了防止Token被假冒,入侵者采用第三方生成,我们使用服务端截从Docker截取的Token中的证书解析校验客户端的Token,杜绝这种情况。
同时,Proxy访问Tracker的接口也会带上这个Token,Tracker会校验Token的权限,完成业务层的安全验证,防止证书和种子被盗取。
通过以上链路层和业务层的安全加固,用户数据被盗取的可能性已几乎为零。如果大家有更好的建议,欢迎点评。
华为云容器镜像服务SWR:http://t.cn/RDyMWm0
公有云Docker镜像P2P加速之路:安全篇的更多相关文章
- 这里除了安全,什么都不会发生!Docker镜像P2P加速之路
1.1 问题: 在使用Docker运行容器化应用时,宿主机通常先要从Registry服务(如Docker Hub)下载相应的镜像(image).这种镜像机制在开发环境中使用还是很有效的,团队 ...
- docker使用阿里云Docker镜像库加速
官方镜像下载实在是慢,于是开通了阿里云开发者帐号, 官方帮助 阿里云Docker镜像库 阿里云容器Hub服务:http://dev.aliyun.com/search.html 来自云端的容器Hub服 ...
- 使用阿里Docker镜像加速器加速
在阿里开发者平台注册开发者账号 https://dev.aliyun.com/search.html 注册之后可以访问Docker镜像服务 https://cr.console.aliyun.com/ ...
- docker镜像和加速
首先,需要明确一个问题:Mirror 与 Private Registry 有什么区别? Private Registry 是开发者或者企业自建的镜像存储库,通常用来保存企业内部的 Docker 镜像 ...
- docker镜像下载加速(5)
镜像下载加速 由于 Docker Hub 的服务器在国外,下载镜像会比较慢.幸好 DaoCloud 为我们提供了免费的国内镜像服务. 下面介绍如果使用镜像. 在 daocloud.io 免费注册一个用 ...
- 精简Docker镜像的五种通用方法
http://dockone.io/article/8163 精简Docker镜像的好处很多,不仅可以节省存储空间和带宽,还能减少安全隐患.优化镜像大小的手段多种多样,因服务所使用的基础开发语言不同而 ...
- 关于docker安装、docker镜像、docker容器等
1.Ubuntu安装docker sudo apt install docker.io 注意以下命令需在root下进行 sudo -s 2.查看docker当前容器 docker ps -a 3.启动 ...
- docker-compose & docker 镜像/加速
docker-compose: http://sanwen.net/a/nuwruoo.html docker加速: http://guide.daocloud.io/dcs/daocloud-915 ...
- Centos7.0 配置docker 镜像加速
在Docker Hub官网上注册帐号,即可下载使用仓库里的全部的docker镜像.而因为网络原因,国内的开发者没办法流畅的下载镜像,经常会出现下载中断的错误.解决方法就是使用国内的容器Hub加速服务, ...
随机推荐
- Java事务的原理与应用
Java事务的原理与应用 一.什么是Java事务 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 (isolation ...
- Rename Oracle Managed File (OMF) datafiles in ASM(ZT)
Recently I was asked to rename a tablespace. The environment was Oracle version 11.2.0.3 (both datab ...
- 12-01Js表单验证和JsWindow
一.表单验证form 1.创建一个新的表单: <form id="id是唯一的,不可重复" name=“可重复”,method="post/get",ac ...
- openGL 预定义变量04
OpenGL4.0 GLSL预定义变量 GLSL为不同的渲染阶段定义了一些特定的变量.这些预定义(也叫做内置变量)有特定的属性. 所有的预定义变量都以gl_开头.用户定义的变量不能以此开头. 下面分类 ...
- struct-config.xml配置文件的解析
//定义了xml文件的版本和编码<?xml version="1.0" encoding="UTF-8"?>//配置文件中的元素必须按照下述doc指 ...
- if __name__ == "__main__": 的使用
#!/usr/bin/env python from qq.lib.a2 import register from qq.lib.a3 import login def main(): while T ...
- SQLiteopenhelper创建database的过程
首先由于SQLiteOpenHelper是一个抽象类,所以我们要创建一个自己的类实现它,并实现抽象方法, public void onCreate(SQLiteDatabase db) public ...
- Angular07 利用angular打造管理系统页面
1 创建一个新的angular应用 ng new adminSystem 2 利用WebStorm打开adminSystem应用 3 借助AdminLTE这个开源项目来辅助开发 AdminLTE项目: ...
- css 层叠式样式表(1)
实用css有三种格式:内嵌:内联:外部: 分类:内联:写在标记的属性位置,优先级最高,重用性最差内嵌:写在页面的head中,优先级第二,重用性一般外部:写在一个以css结尾的文件中,通过引用来建立文件 ...
- EZOJ #79
传送门 分析 在经过若干次操作之后一定会产生一堆环 而我们又发现从一个点到另一个点实际可以经过所有环 于是问题就转换成了$k_1s_1 + k_2s_2 + ... + len = t$ 其中$s_i ...