POSTS2017

Vault Database Secret Backend

vault

在当前版本(v0.7.2)这个 backend 还处于 beta 状态;这个 backend 应该是用来统一之前版本中各种数据库的 secret backend 的;使用前需要挂载 vault mount database,这里用 MySQL 来演示它的主要工作流程:

  • 写入数据库配置,路径在 database/config/$db_name ,主要参数有:
    • db_name 这个配置的名字
    • plugin_name 指定用何种数据库 driver plugin(mysql/postgres 等)
    • connection_url 指定连接参数(注:这个连接参数是用来连数据库以创建用户的,需要有对应的权限)
    • allowed_roles 指定的是允许哪些角色使用此配置(角色是啥下一步就会说明)
    • 安全考虑:这个路径即使读权限也需要严格限制,因为它包含了相当高权限的数据库用户信息
    • 例子:
$ export db_name="test"
$ export role_name="test_reader"
$ export plugin_name="mysql-legacy-database-plugin"             # mysql 有多个 plugin,它们的区别这是创建的数据库用户名最大长度不一样,因为不同版本用户名长度有变化
$ export connection_url="root:password@tcp(127.0.0.1:3306)/"    # 不要忘了最后的 /

$ vault write database/config/$db_name \
>   plugin_name=$plugin_name \
>   connection_url=$connection_url \
>   allowed_roles="$role_name" ...

The following warnings were returned from the Vault server:
* Read access to this endpoint should be controlled via ACLs as it will return the connection details as is, including passwords, if any.
  • 创建角色,角色代表的是数据库用户的类型,路径在 database/roles/$role_name,主要参数有:
    • db_name 就是上一步创建的数据库配置名
    • creation_statements/revocation_statements/... 等是在创建具体用户/注销用户等时执行的语句,这些语句中可以添加如 {{name}}/{{password}} 等这些占位符,待生成真正用户时,这里会特换成动态生成的值,这些也就是这个 backend 要自动管理的秘密了,具体支持哪些占位符需要参阅各个 driver 的文档
    • 例子:
$ vault write database/roles/$role_name \
>   db_name=$db_name \
>   creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON test.* TO '{{name}}'" \
>   default_ttl=15m

Success! Data written to: database/roles/test_reader
    

这里创建了一个角色,用这个角色创建的用户对 test 数据库有读权限,且用户名/密码的默认有效时间是 15 分钟,超时且没有续租的话,Vault 就会删除掉这个用户。(注意由于 MySQL plugin 默认有 revocation_statements 可以不用提供,这些细节要看相关 plugin 的说明)

  • 创建用户,路径在 database/creds/$role_name
$ vault read database/creds/$role_name

Key             Value
---             -----
lease_id        database/creds/test_reader/8e735c82-2eb7-53cf-9cc6-d9c9dc16dd96
lease_duration  15m0s
lease_renewable true
password        96d17f10-9c67-8d44-26d1-c77dcd3e6ec1
username        v-root-01fc63a1-

每次读取这个路径时,Vault 就会调用 creation_statements 创建一个新用户,返回动态生成的用户名密码,并对这个秘密关联租约(由 lease_id 标识),这个租约默认 15 分钟内有效,可以续租

由此,我们就可以把一个 MySQL root 权限的用户保存在 Vault 中,并由它来动态产生受限的数据库用户,这些受限的数据库用户可以存在时间很短,使用它的服务可以定时续租,一旦服务停止,这个用户很快就会被删除掉

一些细节

  • database/config/$db_name: 数据库配置
  • database/roles/$role_name: 角色
  • database/creds/test_reader/8e735c82-2eb7-53cf-9cc6-d9c9dc16dd96: 具体用户秘密租约

这三部分信息是独立,删除修改其中一个貌似并不会影响其它,例如删除数据库配置,角色还是在的,只是创建具体用户的时候会失败,说无法找到相应的数据库配置;又如删除了角色,则具体用户在被吊销的时候也会报错,导致数据库里面还残留没有被删除的用户。