代码数据存在云端,如何保障它的安全?
部分企业管理者对于云端代码托管存在一丝担心:我的代码存在云端服务器,会不会被泄露?
接下来,我们将从代码服务及代码安全角度出发,看看云效代码加密技术如何解决这一问题。
一、前言
1. 代码托管服务
什么是代码托管服务?
代码托管服务是运行在公共环境,提供软件版本控制管理的服务。
代码托管服务核心要解决的两个问题:
- 存档:需要具备存档的能力,也就是,把我们当前工作产出的某个副本保存下来,用于复制、追溯等等。
- 协作:可以让不同的人,基于同一个对象内容进行工作,他们的成果可以一起体现在这个内容之上。
Git 自诞生以来,就和“开源”、“共享”这些词紧紧地联系在一起,它之所以能快速推广,并成为主流的软件版本控制工具,正是得益于它改变了传统软件版本控制工具的协作方式,让软件贡献与协作变得更加高效与便捷。
2. 代码托管服务的两种形态
代码托管服务通常有两种形态:
- 使用开源产品或购买私有部署产品,架设在用户完全可控的部署环境上来提供服务。
- 使用云托管服务产品,只拥有对服务的使用权,而不必关注服务的运维。
2.1 自建代码托管服务
代码资产作为企业资产的重要组成部分,一直备受重视。许多企业、机构都会有自运维的代码托管服务。无论是从完全控制还是数据安全的心理上来说,私网服务似乎更加可信与无懈可击,但随之而来的稳定性、可靠性的问题,却往往让中小企业焦头烂额。
企业发展之初,也许只需要一个服务器资源,搭建一个可用的代码托管服务,即可满足一定的日常研发需求;但随着企业规模不断扩大,遇到的问题逐步增多,开始需要投入专人来管理这个服务;而企业研发人员发展到千人以上的规模,甚至需要投入一个小的团队,来负责代码托管服务的运维及定制化开发工作。这无疑是一笔不小的成本开销。
此外,由于自建服务配套不完善,很容易产生局部运维权限过大而引发安全风险,删库跑路等恶性事件,部分IT从业者可以仅凭一己之力蒸发公司上亿的市值,无时无刻在为我们敲响警钟。
2.2 云代码托管服务
而云代码托管服务,以云共享的方式,提供更大范围的服务能力;同时,由于其背后往往都拥有一支经验深厚的运维管理及产品团队,其可靠性远胜于企业自建的托管服务。
但相比较而言,由于云代码托管服务对用户而言只有使用权,无法登录存储服务器,无法感知其背后的存储和复制机制,又由于代码本身的敏感性,对云代码托管服务的信任问题(如认为代码数据对服务提供方运维人员可见)始终是一些中大型企业的症结。
3. 代码托管服务的演进方向
随着云计算不断演进,通过云原生技术理念的应用可以最大化享受云计算的技术红利,包括弹性伸缩、按量付费、无厂商绑定、高SLA等。
而在实践云原生理念时,势必需要:
- 采取DevOps领域的最佳实践来管理研发和运维流程。
- 通过CICD工具链做到应用的快速迭代和持续交付。
GitOps、Iac(Infrastructure as code)现在越来越多地被众多企业所采纳,代码托管服务也逐渐成为了一种具备软件版本控制能力与协作能力的存储基础设施,其在可靠性及跨地域访问方面的能力,也逐渐成为各大云代码托管服务的核心衡量指标。而这方面的能力,也正是自建代码托管服务所不能满足的地方。
那么,如何打造云代码托管安全体系,来提升用户的信任感呢?
4. 云代码托管安全体系
为了更好地支撑代码托管服务的存档能力,云代码托管体系通常会按照以下四个方面来建设:
访问安全:
访问安全包括但不限于认证、权限控制、数据传输等等,它主要解决用户的身份识别,最小限度地赋予指定用户所需的合理权限,在事前最大程度保证代码资产的安全性,同时通过对传输过程数据加密(如常见的https、openssl加密)等手段,避免中间人截取或篡改用户的数据。
数据可信:
在访问安全的基础上,还需要通过一些额外的手段,确保代码提交及代码归属的可信度(如仅接受特定属主的代码,或要求必须对提交记录进行GPG签名),从而进一步降低因为账号泄露等导致的风险。
存储安全:
作为云代码托管服务最核心的能力,存储安全不但要保证服务的可靠性,数据资产不丢失,更可以通过存储快照及备份等手段,降低用户使用过程中的风险。同时,如何保障存储于物理设备的数据,不产生数据泄露风险,也是用户最为关心的问题。
审计风控:
在事前及事中安全能力之外,在事后通过智能化风险识别、主动防御等手段,进一步加固整个安全防护体系。
在访问安全、数据可信、审计风控等方便,目前各云代码托管服务或多或少的都具备了一些这样的能力,但我认为,存储安全才是最核心的竞争力。在这其中,代码数据加密技术的探索,也是最具有挑战的。
5. 数据加密技术
通过对数据内容进行加密,并将打开这把锁的钥匙,交到用户手中,是当下众多云服务用于解决用户信任问题的银弹。为此,具备云盘加密、云端加密能力的对象存储服务更容易被用户接受,众数据库服务厂商(如MySQL、Oracle、PostgreSQL等),也纷纷在自家产品上推出了TDE(Transparent Data Encryption)的能力。
那么,同样具备存储属性的代码托管服务,是否也可以引入数据加密的能力呢?
在提供用户对代码资产的备份、删除能力之外,通过数据加密,让用户的数据资产仅对用户自己可见,从而达到对代码存储的近完全可控的目的。
二、业界代码加密方案
1. 客户端加密
以开源软件 git-crypt 为代表的客户端加密方法,是针对敏感信息存储的不错选择。用户生成一个数据密钥,用于对目标文件加密,将加密后的内容,提交到git仓库当中。
在这种模式下,加密的内容,仅提交人可见,而当你需要与他人共享时,可以通过获取他人的 PGP 公钥,对用于加密的数据密钥加密后,提交到代码仓库。对方在获取到数据密钥密文后,使用自己的PGP私钥解密,得到数据密钥,就可以解密数据了。
但这种方式的弊端也很明显,数据密钥获取一次,就可以反复使用,无法解除授权;原有的文本文件加密后变成了二进制文件,也导致git无法对增量修改创建delta,大量使用及频繁变更就会导致仓库体积迅速膨胀。
2. 磁盘加密
磁盘加密技术已经非常成熟,似乎也是一个很好的选择方案。但磁盘加密仅解决物理设备层面的数据安全问题,在vm(虚拟机)层面,仍然是明文访问数据的。
3. 服务端闲时加密
对于使用不频繁的代码仓库,闲时加密也不失为一种好的解决方案。在一个Git仓库不被访问时,对其进行加密,而当其重新需要被访问时,就需要等待解密完成,再开放访问。
这种方案的通用性很高,也可以有很多种加密的方案可以选择,实现的成本也不高,但缺点也很明显:仓库访问需要一个预热的过程,仓库越大,预热时间也相应越长;高频访问的仓库,几乎总是以非加密的形态存储在磁盘上,而这些热点仓库,也往往是用户最为关注,也最不期望被泄露的。
4. 基于JGit、S3的云存储加密
AWS的代码托管产品CodeCommit,提供了代码加密的能力,它基于JGit实现的代码托管服务,复用了原有JGit的存储模型,利用S3的存储加密能力。
JGit的社区活跃度大大低于Git的社区活跃度,并且在性能对比上,Git也是远胜于JGit,这也是各大主流代码托管服务均使用Git的原因。
三、云端代码托管的透明加密
云代码托管服的透明加密,是一种服务端加密技术(Server-Side Encryption):它使用用户授权的密钥来完成对用户代码数据的加密;在用户访问时,使用用户的密钥来对数据进行解密。整个加解密的过程对用户完全透明,用户可以使用常规的Git客户端来进行代码库访问,或是浏览代码服务提供的页面服务;但用户保留对数据的完全掌控,可以在必要时,通过取消密钥授权,达到冻结代码数据的目的。
1. 云端透明加密的优势
Git TDE(Transparent Data Encryption)的优势:
- 不依赖文件系统。
- 文件系统访问的数据都是密文。
- 可选择仅加密一些敏感仓库来降低对性能的影响。
Git TDE 保护突破了文件系统访问控制的安全威胁:
- 偷取存储设备,并且直接访问代码库文件的恶意用户。
- 通过磁盘备份恢复数据的恶意用户。
- 保护静态数据(持久化的数据),对平台运维人员不可见。
2. 加密方式
采用信封加密[2] 方式进行加解密:
- 由密钥管理服务KMS产生数据密钥,并将数据密钥密文及加密后结果进行存储。
- 在需要解密时,由KMS解密数据密钥密文,从而解密加密后的内容。
KMS的加解密,通常用于处理少量的数据;而Git数据量较大,无法直接使用KMS的加解密服务,选择信封加密来加密数据密钥便是一个很好的选择。
3. 密钥粒度
每个代码库一个数据密钥:一库一密可以有效避免数据的泄露。
4. 哪些文件需要被加密
Git仓库中的数据,包括引用数据(HEAD、分支branch、标签tag等),索引数据(.idx, .bitmap),松散对象,打包数据(.pack)。
通常情况下,我们通过 git push
提交的少量代码修改,都会以松散对象的方式存储,一个松散对象文件对应一个用户侧文件实体。在进行垃圾回收 git gc
之后,会对松散对象进行清理,同时将他们打包整一个单独的打包数据(即 packfile)。
那么,在这种情况下,哪些文件需要被加密呢?
我们认为,分支等引用信息中,不包含敏感的用户信息,所以无需加密。同时,索引文件仅用于打包数据的查找,也不是用户信息,无需加密。通常情况下,我们的敏感信息都存储在较小的文本文件中(如代码文本),结合性能考量,我们决定:
- 仅加密<10MB的松散对象(相当于500万字中文小说)。
大小 |
压缩 |
加密 |
松散对象 |
Packfile |
< 10MB |
√ |
√ |
√ |
|
10MB ~ 512MB |
√ |
|
√ |
|
> 512MB |
√ |
|
|
√ |
- 对于提交的单文件packfile,不进行加密。(默认情况下,当我们向git服务提交单个大于500MB的文件时,服务端会将其存储为单文件packfile,而不是松散对象,而单个大于500MB的文件,我们可以认为其为二进制资源或者程序,没有加密的必要)
- 除上述单文件packfile外,其他pack文件均进行加密。
5. 何时加密
当用户进行代码提交时,用户提交数据会先通过SSL/TLS加密,传输到代码托管云服务,同时获取数据密钥,对提交的数据进行加密,而后持久化到磁盘。
6. 如何加密
使用AES(Advanced Encryption Standard)作为我们的首选算法,预计在后续也会增加SM4的支持。
加密模式
使用CTR模式对数据内容进行加密。
密钥长度
使用256位数据密钥,由KMS生成,平台只保存数据密钥的密文。
7. 加密后效果
打包文件packfile效果:
松散对象效果:
8. 加密对性能影响
加密会对仓库性能产生小幅度影响:
以Git工程的源代码下载为例,加密后打包阶段性能下降约10~20%;但由于下载过程中,网络传输占据绝大多数的时间(通常占比90%以上),由加密引起的性能下降在整体使用过程中可忽略不计。
四、我们的代码托管产品
Codeup代码加密
云端加密代码库是云效团队的自研产品,是目前国内首个支持代码加密的托管服务,也是目前世界范围内首个使用实时加密方案的代码托管服务。
通过在云端对托管在云效Codeup 的代码库进行落盘加密,可以有效避免数据拥有者之外的人接触到用户的明文数据,避免数据在云端发送泄露。同时,代码加密过程对用户完全透明,用户可以使用任意官方Git端(包括但不限于Git、JGit、libgit2等)来访问Codeup上的代码仓库。
开启仓库加密
具有管理员权限的用户,进入期望加密的具体仓库的设置页面可以看到「仓库加密」开关,点击打开:
新建仓库时开启加密
新建仓库时支持勾选启用仓库加密:
开启/关闭仓库加密
具有管理员权限的用户,进入期望加密的具体仓库的设置页面可以看到「仓库加密」开关,点击打开/关闭:
关闭加密时,会触发仓库的解密操作。
KMS密钥管理服务
前往阿里云KMS服务,可以查看到Codeup自动创建的服务密钥,该密钥不可删除和禁用,但可以通过修改KMS服务密钥的标签,临时禁用Codeup对KMS的调用:
点击④——密钥详情,可以看到「标签」部分有一个Codeup创建的标签键 acs:rdc:git-encryption
:
通过临时修改或者删除该标签值,即可限制Codeup对密钥的访问,达到临时冻结仓库的目的。
仓库已加密,获取密钥失败,请联系企业管理员确认密钥可用状态
返回上一页
返回首页