Hashicorp vault使用
介绍 Intro
安装 Install
使用vault
vault的组件
从vault的功能入手,我们所有的目标都是从vault里面获取需要的token或者key 等机密数据,那么需要经历如下步骤:
- 认证identify
在vault里面叫Auth Methods。比如我们用ldap登陆我们自己的系统,我们也可 以通过ldap登陆vault的dashboard或者获取token,这个时候ldap就是一种auth methods,同时支持的还有很多,比如user pass, aliyun, token, app role等。
- 权限校验validate
vault如何根据用户进行权限管理,类似我们的rbac。主要是通过维护若干个 policy进行管理的。比如创建一个策略,允许访问database/*这个kv库。 然后把用户或者app这个实体绑定或者更新包含这个策略。
- 实际的分配Secrets Engines
用户认证成功并且有权限以后,用户就需要获取对应的实际资源,这个资源是由 对应的secrets engine实现的。
常见的有很多,比如单独存储(KV), 云服务(Aliyun, Tencent, AWS, Azure), 数据库(MongoDB, MySQL/MariaDB, ElasticSearch),证书相关PKI。
当你和对应的secrets engine申请一个credential的时候,他们会调用api最终 生成你想要的东西,并且带上一个期限,vault通过lease进行管理。
vault的命令
具体的使用请参考vault cli reference。
这里我简单介绍下我平常用的比较多的命令。
执行命令前的准备
需要注意的是vault默认认为是从127.0.0.1:8200去获取状态导致你第一次命令
可能就报错,正确办法是维护两个环境变量
VAULT_ADDR
具体的vault地址
VAULT_TOKEN
你的vault token,如果你只有用户名密码或者app role id和
secret,你需要做一下通过登陆来获取。
具体方法有如下几个:
- 登陆vault的dashboard,就是ip:9200或者你设置的负载均衡地址,选择用户 名密码或者ldap或者app,登陆进去以后,点击右上角的下拉菜单和copy token
- 调用对应的api,如果是app role可以参考
|
|
- 使用vault命令
使用vault login命令,比如用户密码可以参考
|
|
集群或者vault本身管理相关
|
|
policy创建
|
|
vault的一些思想
以阿里云的动态用户为例,简单介绍下vault的工作流程。
- 确认secret engine支持
首先目标是阿里云,首先找是否有对应的secret engine支持。发现有,alicloud vault。
- 配置secret engine
配置alicloud并且确认好max_ttl等参数,这里需要注意vault默认是30天的最大 ttl,如果需要修改,可以在vault服务器的配置文件里面进行增加max_lease_ttl = "43800h"类似的参数,默认是720h。
|
|
对于一个secrets我们也可以通过vault tune进行后续的设置和修改参数。
- 创建一个secrets相关的角色,并且确认好ttl等参数。
|
|
- 把角色授权给我们实际的用户或者用户创建的时候关联下
|
|
- 用户认证通过以后调用creds
|
|
vault集成
ldap接入
设置ldap
ldap related https://developer.hashicorp.com/vault/docs/auth/ldap
注意具体和你们自己的ldap配置有关。
|
|
ldap policy权限设置
|
|
阿里云接入
假设用户需要一个特定policy-lqx的角色权限,我们发现有则使用,无则创建一 个,创建在上面有说明,支持自定义和系统权限混合
具体文档可以参考 alicloud api https://developer.hashicorp.com/vault/api-docs/secret/alicloud
alicloud文档 https://developer.hashicorp.com/vault/docs/secrets/alicloud
创建一个阿里云ram帐号vault_test,只允许api操作,不允许控制台登录,并且给权限
|
|
创建secret engine alicloud-publiccloud
这里我使用aliccloud的publiccloud基础架构的做下演示
进入vault web页面https://vault.xxx.com/ui/vault/secrets
选择aliccloud
如果希望默认ttl可以设置,后续也可以改,这里我保持默认,点击最下面的 enable engine创建好engine
修改使用如下命令
|
|
web打开终端,输入第一步创建的阿里云ram账户的access key,请确保此步执行 成功
|
|
创建完role我们进行policy增加权限
|
|
把这个policy和用户进行绑定或者和token进行绑定,这里使用我的个人ldap进行测 试
|
|
调用http api
|
|
申请好了对应的access key了,对应时间是10min,10min后这个用户会被删除
也可以用vault read alicloud-publiccloud/creds/policy-lqx进行申请
sts支持
关于sts,可以参考这里https://help.aliyun.com/document_detail/39744.html?spm=api-workbench.API%20Explorer.0.0.c2261e0fs8q0Xc
关于role arn,可以看下这里 https://next.api.aliyun.com/api/Sts/2015-04-01/AssumeRole?params={}&tab=DOC
publiccloud 里面我创建了一个ram角色 https://ram.console.aliyun.com/roles/vault-test-lqx
复制ARN acs🐏:xxx:role/vault-test-lqx 中间是主账号
|
|
可以发现默认获取的是1个小时的sts token
腾讯云接入
安装插件
有问题参考文档 https://github.com/tencentcloudstack/vault-plugin-secrets-tencentcloud
|
|
注册插件
|
|
测试
建议参考 https://github.com/tencentcloudstack/vault-plugin-secrets-tencentcloud/blob/master/docs/Tencent%20Cloud%20Secrets%20Engine.md 和阿里云的基本一样
http api https://github.com/tencentcloudstack/vault-plugin-secrets-tencentcloud/blob/master/docs/Tencent%20%20Cloud%20Secrets%20Engine%20(API).md
创建路径
|
|
配置access key和id
新建一个账户vault_test,并且给cam的所有权限
|
|
创建一个role
|
|
尝试把权限给lqx
|
|
尝试获取credentials
|
|
此时有新用户产生,具体不截图了,这个时间长,可以调整默认ttl时间的
尝试revoke
|
|
发现新建的用户被删掉了,也可以进行renew,加上时间就是续约的时间
ssh支持
one-time password临时密码
具体可以参考链接
- 用户访问vault服务获得临时密码
- 用户ssh要登陆的服务器,输入临时密码
- ssh服务器的vault ssh agent进行验证
- 用户成功登陆
具体步骤如下
|
|
|
|
这里可以参考文档 https://developer.hashicorp.com/vault/api-docs/secret/ssh 对于cidr支持列表,支持反向,注意这个cidr指的是管理的ip段,就是你ssh的 目标ip段。
allowed_users="appops,admin"可以指定多个用户 ttl可以指定时间
|
|
|
|
|
|
首先无论任何用户都需要有对应的policy,我们之前创建了一个user, pass认证, 这里可以认证一下
|
|
可能有如下问题:
uuid
相关问题
|
|
检查远程用户是否创建了
- 没有对应的
vault helper
日志产生
把对应的命令在控制台跑一下看看
pam_unix(sshd:auth): authentication failure
出现这个问题是因为调用pam_unix的时候报错了,这个时候我们应当是不需要再 使用user password认证的,所以我逐个尝试禁止password-auth最终发现是这个 问题, 只需要注释auth这行就好了,在pam系统里面auth用于认证密码,这个引 用会导致失败。
|
|
error: PAM: User account has expired for xxx
原因是你禁止的东西太多了,把后面的password-auth都禁用了导致系统不知道 应不应该保持session了。
error: PAM: pam_setcred(): Permission denied
这个错误是少加了一行
|
|
最终贴下我的完整的配置
|
|
另外需要注意上述的操作只会影响vault设置的username,不设置的仍然可以通 过公私钥的方式登陆。
这里一定要注意如果要跳过公私钥认证,可以
|
|
否则默认还是会通过公私钥登陆的。
signed ssh certificates证书方式登陆
具体参见vault with signed certificates
|
|
|
|
注意给你测试的client增加对应的hcl权限
|
|
|
|
把领到的私钥放到服务器上面
|
|
这个时候测试下登陆,我这边没有配置成功,后来发现和ssh客户端有关系,在 另一台centos7.9上面成功了。我自己的debian 12没有成功。
|
|
目前没找到解决的办法,总之依赖于ca证书就需要解决多个客户端的各种ssh问 题,对于运维成本来说确实比堡垒机要高很多。
也可以参考这篇文章进行查看 https://gist.github.com/kawsark/587f40541881cea58fbaaf07bb82b1be#client-01a---create-key-pair-and-sign-with-vault
数据库支持
关于数据库相关 可以参考vault secrets engine database
支持大部分数据库,包括但不限于
MySQL/MariaDB
mysql平常用的比较多,为了测试兼容性,我用了aliyun的rds进行测试。
|
|
|
|
添加policy
|
|
给对应实体添加对应的policy,这里可以去dashboard简单点,如果你是维护在 gitlab等仓库里面或者用terraform管理则更方便啦。
首先确认当前登陆用户是你的要测试的用户,尽量避免在主admin账户进行测试
命令如下: vault token lookup
|
|
这个时候报错了。后来才发现是db_name这个参数有迷惑性,db_name这里需要配 置成mysql_vault_test才行
再次执行就好了,
|
|
mysql也可以连上了
|
|
一分钟后用户不见了。
这个好处是密码只需要用户自己去申请或者自动化程序去申请就好了,并且能关 联到人。回收也是自动回收的。
坏处就是不是很方便。但是可以通过开发一个平台或者工单来解决。对于一些平 台,也是可以集成的。
对于代码来说即使泄漏了密码也不会导致问题。在线上服务器上可以通过 vault-agent自动渲染mysql密码,从而加强安全性。
应用接入
创建policy和role
你可以创建一个policy,然后再关联对应的创建的app
|
|
创建app role
|
|
获取app role的token和secret
|
|
场景1 静态密码
那么我们想象一个场景是我的业务有个配置,某个外部api的用户名密码保存在 vault里面,我们这个业务去机器的/secrets/app-x/identity.json里面读取对 应的用户名和密码。
首先我们帮用户创建好对应的kv名称,让他们写入一组测试的密码到 secrets/vault-role-test/里面,可以通过vault域名进去自己添加,也可以通 过vault命令写入
下面的操作都可以通过登陆vault网页操作,我用命令只是为了方便,不习惯的 可以用页面进行管理。
创建kv vault-role-test
|
|
首先需要从app role id和secret id获取token
|
|
继续模拟用户插入一条数据
|
|
这个时候我们成功插入了一条数据,并且vault-role-test这个app role可以进 行读取和写入。
这个时候我们使用vault-agent是比较合适的。
我们编写好agent.hcl,并且下载vault的二进制文件。具体可以参考vault-agent install。
请确保你的/etc/vault/roleid和/etc/vault/secretid是我们的role对应信息。
|
|
当我们启动以后发现/tmp/vault-role-test有了对应的token,这个也就是相当 于帮我们执行了login的操作。这个是auto-auth的功能。
我们可以继续延展下我们的使用,我们需要它能映射x-username和x-password到 我们的/secrets/app-x/identity.json文件。这里原则上可以template解决。
使用vault template。这里大家一定要注意自己的vault版本,我的是v1.12暂时 不支持generate-config等高级操作。template编写的时候注意"需要转义一下。
|
|
这样操作完以后,在我的identity就有新的json了。
|
|
场景2 动态ak
另一个场景是包含lease的动态token情况下,比如用户每次去调用阿里云服务, 通过此方式实现动态ak的效果。
目前动态ak的思路,可以参考auto auth的思路,但是这个需要用户有一个ak, 这个和我们的初衷有点不一样,我们希望只给用户一个app role id和role secret, 剩下的就让vault-agent生成(我提了个issue,估计他们不一定做~, 后来发现这个是支持的), 目前看如果是vault-agent的方法,目前我这边有三个办法:
- 利用auto auth这个腾讯云和阿里云都有对应的method
aliyun https://developer.hashicorp.com/vault/docs/agent-and-proxy/autoauth/methods/alicloud
利用template file,我们也可以自动生成aliyun的ak
这里注意template file的配置
|
|
如果有自定义ttl需求,这个时候注意你创建aliyun role的ttl设置
|
|
这样就能控制模板的生成时间了,默认我没法找到传ttl参数的地方
- 开发全部用api调用aliccloud/creds获取对应的临时token,并且判断过期等
这个办法就是比较麻烦需要开发接入,并且需要有个定时刷新或者每次判断是否 过期,实际接入会比较难受
毫无疑问,第一个方案更好
场景3 golang代码里面直接访问
场景4 python代码直接访问
场景5 awx或者ansible里面访问
场景6 k8s里面访问
vault本身配置管理
增加audit审计
file类型
|
|
生产部署
如果用k8s里面的部署方式,一般helm会帮你配置好,我这里没有测试过。
如果是服务器部署,我这边使用的是如下的部署方式consul+vault集群方式配合 auto unseal,你也可以配置通过mysql集群方式部署。
这里解释下seal,seal的本意是密封,当服务器被重启或者vault服务重启以后, vault会进入密封状态,需要提供对应的vault unseal token才可以。但是我们 又不方便在服务器上面暴露unseal token,所以另搞一个unseal的vault用于 unseal这个集群。
若干vault服务器配置73等
|
|
autoseal服务器75
|
|
prometheus监控
建议把服务器的vault seal的状态进行监控,避免服务异常。
|
|
这里要注意配置完成以后可能会报错,expected a valid start token, 啥的, 原因是因为vault还需要加个配置,不加这个?format=prometheus就无法访问。
|
|
如果提示认证失败,则可能token过期或者你的集群访问错了机器,建议用对外 的暴露的域名。
告警策略目前我发现vault_core_unsealed == 0无法告警,我用了up{job=xxx}的 方式来告警。
|
|
其他类似的可以从awesome rules vault里面查看
参考文档
- vault官方文档
- vault官方安装说明
- awesome rules vault
- https://lonegunmanb.github.io/essential-vault/6.%E6%9C%BA%E5%AF%86%E5%BC%95%E6%93%8E/1.AliCloud.html
其他
admin policy example
|
|
vault重装
属于风险操作,执行前请确认vault不在集群中
|
|
vault auto unseal
unseal服务器或者集群安装好vault 参考 https://developer.hashicorp.com/vault/tutorials/auto-unseal/autounseal-transit
https://developer.hashicorp.com/vault/docs/concepts/seal
|
|
上面这个时间比较少,所以最好还是设置成几年,对于vault unseal来说,
具体可以在unseal的vault上面配置这个并且重启
|
|
前面都是没问题的 后面记得要auto unseal的集群添加如下配置
|
|
这个时候重启vault集群的这台vault
发现集群进去seal状态了,看日志需要migrate,因为我们设置了自动解封,所 以vault认为需要把原来的unseal key转成recovery key
|
|
这个时候执行任何命令都不行了
|
|
需要执行unseal -migrate
|
|
执行完以后,发现vault进入unseal状态了,这个时候重启它,也不会seal了。
测试 stop掉集群的一台
|
|
我们发现vault变成sealed了,再开
|
|
发现自动被unseal的了