写在前边
这一篇文章是基于 Gitea+Drone CI+Vault 打造属于自己的CI/CD工作流系列文章第二篇,让我们一起来完成 drone
与 vault
的搭配使用,这篇主要讲 vault
的部署和使用,以及怎么通过 drone
来使用 vault
上一篇文章(一) Drone CI For Github —— 打造自己的CI/CD工作流我们一起了解了,Drone
的部署和使用,一起感受了 Drone
的简单强大的功能带来的方便和快捷。在实际的应用中,我们会有很多的敏感数据,Drone
自身的 Secret
是以仓库为单位进行管理,而且也没有严格独立的权限控制,其实是不太方便的。
带着这样的疑惑,我再次向@Dee luo老哥寻求帮助,老哥掏了掏肚子上的口袋,取出一本武林秘籍,曰:“小伙子,我这里有一个色情网站记录在上面,你看看”。我打开只看到 www.vaultproject.io 一行小字赫然记录在内,我迫不及待的打开,美滋滋的看了起来。
此处省略一万个字…
另外强烈推荐YUHAO的博客 私密信息管理利器 HashiCorp Vault系列文章
好了,现在我已经知道该做什么了。
说干就干,开始搞事。
了解Vault
Vault是一个管理Secrets并保护敏感数据的工具,来自HashiCorp,如果你对这个名字有点陌生,那么你一定知道Vagrant
Vault是一种安全访问
Secret
的工具。Secret
就是您要严格控制访问的任何内容,例如API密钥,密码或证书。Vault为任何机密提供统一的界面,同时提供严格的访问控制并记录详细的审计日志。现代系统需要访问大量
Secret
:数据库凭证,外部服务的API密钥,面向服务的体系结构通信的凭证等。了解谁正在访问哪些秘密已经非常困难且特定于平台。如果没有自定义解决方案,几乎不可能添加密钥滚动,安全存储和详细的审计日志。这是Vault介入的地方。Vault的主要功能包括:
- 安全秘密存储:任意密钥/值秘密可以存储在Vault中。Vault会在将这些机密写入持久存储之前加密这些机密,因此获取对原始存储的访问权限不足以访问您的机密。Vault可以写入磁盘,Consul等。
- 动态秘密:Vault可以按需为某些系统生成机密,例如AWS或SQL数据库。例如,当应用程序需要访问S3存储桶时,它会要求Vault提供凭据,Vault将根据需要生成具有有效权限的AWS密钥对。创建这些动态机密后,Vault也会在租约到期后自动撤消它们。
- 数据加密:Vault可以加密和解密数据而无需存储数据。这允许安全团队定义加密参数,并允许开发人员将加密数据存储在SQL等位置,而无需设计自己的加密方法。
- 租赁和续订:Vault中的所有机密都有与之相关的租约。在租约结束时,Vault将自动撤销该秘密。客户可以通过内置续订API续订租约。
- 撤销:Vault内置了对秘密撤销的支持。保险柜不仅可以撤销单个秘密,还可以撤销秘密树,例如特定用户读取的所有秘密,或特定类型的所有秘密。撤销有助于关键滚动以及在入侵情况下锁定系统。
上边都是废话,这里说一下我自己的体验。
首先我没有体验的很深,我现在只是体验了 key/value
结构和 database
,然后看了一下 ACL Policies
管理权限。
- 权限控制很严格,机制也很灵活和安全
- UI美观,操作简单,不过UI功能也简单
- CLI 操作容易理解,文档齐全。
- 安全确实很放心,token定时刷新,可以通过token来获取数据库的配置,UI的激活需要输入key,容器重启也需要重新输入key来激活。
部署 vault
这里并不是单独部署vault,而是参考上一篇文章来结合vault使用,在上一篇文章的
docker-compose.yml
基础上,加入vault
的容器,并为vault
提供web
服务.为了区分,以下代码块中,用
$
开头表示宿主机命令,用/ #
开头表示容器中的命令
编写模板文件
1 | ... |
配置 vault
事先准备好一个数据库和对该数据库具有访问权限的数据库账号
参考
database
: vaultname
: vaultpassword
: vault123456样例中的配置请事先阅读文档知晓含义
参考Vault Configuration
Vault
的配置文件是HCL或者json
,这里我使用json
HCL to json
请参考HCL
- 初始化
vault
1 | $ mkdir -p vault/config |
初始化动作为我们生成了 5 个 Unseal key,此外还有默认的 Root Token。所以应该马上把这些信息记录到安全的地方,因为以后你是没有办法再看到它们的。
- 编辑nginx,为vault提供web服务
编辑完记得重启nginx服务
1 | server { |
- 访问
vault.yiranzai.top
Vault 对于数据保护是非常重视的。服务器启动后,并不能够马上访问其数据,而必须经过一个解封(Unseal)的动作。
依次输入上边得到的五个
Unseal Key
中的三个来解封服务,然后使用Root Token
登录,登录后如图,右侧会有教程,先跟着做一边熟悉熟悉。
- 创建一个
Secrets Engines
这个东西,怎么说呢,不太好理解。字面意思就是
秘密引擎
,是存储,生成或加密数据的一个组件,可以理解为一个数据集,也可以理解为一种数据渠道。只有Secrets Engines
存在,数据才能被指定方式存储。
- Generic
- KV (这里只示范这种)
- PKI Certificates
- SSH
- Transit
- TOTP
- Cloud
- Active Directory
- AliCloud
- AWS
- Azure
- Google Cloud
- Google Cloud KMS
- Infra
- Consul
- Databases (支持多种驱动)
- Nomad
- RabbitMQ
- 创建一个
ACL Policy
创建一个
ACL Policy
,配置为仅对刚刚创建的Secrets Engine
——dronetest
有可读和列表权限。ACL Policy
的配置格式为HCL,HCL 是 HashiCorp 创造的、专门用于配置文件的语言格式)
1 | # Allow tokens to look up their own properties |
至此,我们的
Vault
就配置好了,接下来让我们创建secret
创建 Secret
上面我们简单配置了一下
Vault
,现在让我们创建Secret
首先我们明白的是
dronetest(Policy)
对dronetest(Secrets Engine)
只有可读和列表的权限。
- 登录
回到
vault
容器中,使用Root token
登录
1 | / # vault login s.RIeC53WBWizfl0OXVbDYuxbh |
- 创建一个用于验证的
token
这个token应当只对
dronetest(Secrets Engine)
可读,所以我们为他分配一个dronetest(Policy)
1 | / # vault token create -policy=dronetest -no-default-policy |
- 写入
Secret
如图所示,这里我们为
web
创建了两对KV
接下来尝试用命令创建
1 | / # vault kv put dronetest/test v=k |
可以看出后者覆盖了前者,注意
version
增加了1
,vault
为每个path
每次写入的数据都定义为了一个新的版本,这样就不难理解,这里为什么是后者覆盖了前者。
在 Drone
中使用 Vault
以上我们了解了
Vault
简单的部署和使用,现在我们一起了解怎么在Drone
中使用Vault
编辑Docker-compose.yml
结合上一篇文章(一) Drone CI For Github —— 打造自己的CI/CD工作流,我们将
Vault
加入进来然后我们还需要
drone-vault
这个插件来实现Drone
和Vault
之间的通信中转参考
- Drone使用Vault存储Secret (仔细看,文档是有缺失的)
- Drone-vault源码分析 (之所以要分析,是因为官方文档中没有说明怎么和vault通信,观看源码一目了然)
1 | version: "3.7" |
改写仓库中的 .drone.yml
这里的
.drone.yml
与上一篇文章中的类似,没有太大改动。参考
- 为
dronetest
中的web
创建一个新版本
私钥中的换行符需要替换成\n粘贴进来
1 | { |
- 编辑
.drone.yml
1 |
|
- 提交修改
1 | git add .;git commit -m 'init test 4'; |
查看
Drone
的ACTIVITY FEED
如果成功就会如下图所示
去服务器检查一下
看到
bash.sh
和.drone.yml
都被上传到这里(只是测试,不是真的让你这么干)
1 | $ pwd |
总结和推荐
写到这里,就算是结束了。说实话,有了上一篇文章的的经验和踩坑,我已经对于 Drone
的文档相当失望了,没想到后边有更深的坑在等着我,当我了解到真相以后,气得差点砸键盘。
本次总结
- Vault 的文档其实还算清晰,在实际操作之间,建议至少把KV相关的部分熟读,而且第一次激活之后的手册一定要照着实践一遍。(如果你的英文不错,你可以看
vault
官方提供的高级教程) drone-vault
的官方样例中没有说明怎么与vault
通信,在我第一遍的操作中,我没有细想这个问题,跳过了,结果不用多说,自然是失败。后面发现问题一脸蒙蔽,这玩意他不说我怎么找呢?还是@Dee luo老哥提醒我,我才想起来去看看源码,在源码中找到了相关参数。(强烈吐槽!!!仓库还是只读的!!!)drone-vault
是用GO语言开发的,drone-vault
使用的http
包,不支持没写协议的url
,例如vault:8200
不能被识别,要写成http(s)://vault:8200
vault
中的Secret
存储路径是{Engine Name}/data/{Secret Name}
,这一点要牢记
如果你对 vault
想有更深层次的了解,可以看下YUHAO的博客 私密信息管理利器 HashiCorp Vault系列文章
系列文章
- 基于 Gitea+Drone CI+Vault 打造属于自己的CI/CD工作流
- (一) Drone CI For Github —— 打造自己的CI/CD工作流
- (二) Drone CI使用Vault作为凭据存储 —— 打造自己的CI/CD工作流
- (三) 轻量化自建 Drone CI For Gitea —— 打造自己的CI/CD工作流
- 番外:基于Gitea打造一个属于你自己的代码托管平台
好了,祝大家撸码愉快,沉迷于BUG不能自拔。
不要砸键盘!