Vault PostgreSQL Dynamic Credentials

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。
本文缩写(英文全称与中文含义)
缩写 英文全称/名称 中文含义
CA Certificate Authority 证书颁发机构
DBA Database Administrator 数据库管理员
EKS Elastic Kubernetes Service AWS 托管 Kubernetes 服务
HTTP Hypertext Transfer Protocol 超文本传输协议
RDS Relational Database Service AWS 关系型数据库服务
SQL Structured Query Language 结构化查询语言
TLS Transport Layer Security 传输层安全协议
TTL Time To Live 存活时间;具体指缓存有效期或记录过期时间

1. 场景与前提#

订单查询服务按实例取得短期 PostgreSQL 只读账号,默认 15 分钟、最长 1 小时。Vault lease 负责生命周期,应用负责及时换连接;不向应用暴露管理账号。

前提:已完成 Vault 集群部署,具备 vault、jq、psql;准备独立测试数据库 orders,Vault 所有节点能通过 TLS 访问数据库。Aurora PostgreSQL 使用 writer endpoint,并验证当前引擎版本的角色管理权限。

下面先在测试库验证,不能直接对共享生产 schema 执行初始化 SQL。

2. 数据库权限#

DBA 连接 orders 数据库,执行一次:

CREATE ROLE orders_owner NOLOGIN;
CREATE SCHEMA orders AUTHORIZATION orders_owner;

SET ROLE orders_owner;
CREATE TABLE orders.order_summary (
  id bigint PRIMARY KEY,
  status text NOT NULL
);
INSERT INTO orders.order_summary VALUES (1, 'created');
RESET ROLE;

CREATE ROLE orders_reader NOLOGIN;
GRANT CONNECT ON DATABASE orders TO orders_reader;
GRANT USAGE ON SCHEMA orders TO orders_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA orders TO orders_reader;
ALTER DEFAULT PRIVILEGES FOR ROLE orders_owner IN SCHEMA orders
  GRANT SELECT ON TABLES TO orders_reader;

CREATE ROLE vault_admin LOGIN CREATEROLE;
GRANT CONNECT ON DATABASE orders TO vault_admin;
GRANT orders_reader TO vault_admin WITH ADMIN OPTION;

在交互式 psql 中用 \password vault_admin 设置随机初始密码,避免写进 SQL 历史。将同一密码通过受控临时文件交给 Vault 管理员,权限 0600,不带末尾换行。

vault_admin 需要创建、授权、修改和删除自己创建的动态角色;它不应是业务表 owner。PostgreSQL 版本、RDS/Aurora 托管限制会影响角色管理,需实测 CREATE/GRANT/ALTER/DROP,不能用授予应用超级用户权限来解决问题。

默认权限只影响指定 owner 以后创建的对象;生产存在其他 migration owner 时需分别配置。Vault policy 控制“能否领取账号”,SQL GRANT 控制“账号能读哪些表”。

3. 配置连接#

在每个 Vault 节点安装数据库信任 CA:/etc/vault.d/tls/database-ca.pem。替换示例数据库主机名,保持 sslmode=verify-full:

vault secrets enable database

vault write database/config/orders-postgres plugin_name=postgresql-database-plugin allowed_roles=orders-read connection_url='postgresql://{{username}}:{{password}}@orders-db.internal:5432/orders?sslmode=verify-full&sslrootcert=/etc/vault.d/tls/database-ca.pem' username=vault_admin password=@/secure/bootstrap/vault-db-password.txt

vault write -f database/rotate-root/orders-postgres

rotate-root 轮换的是此连接配置的管理凭据,不表示必须使用 PostgreSQL superuser。成功后旧初始密码应失效,由 Vault 管理新密码;该管理账号不能再被其他工具共用。PostgreSQL plugin

4. 定义动态账号#

保存 orders-create.sql:

CREATE ROLE "{{name}}" WITH LOGIN INHERIT
  PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
GRANT orders_reader TO "{{name}}";

保存 orders-revoke.sql:

REVOKE orders_reader FROM "{{name}}";
DROP ROLE IF EXISTS "{{name}}";

创建 Vault role:

vault write database/roles/orders-read db_name=orders-postgres creation_statements=@orders-create.sql revocation_statements=@orders-revoke.sql default_ttl=15m max_ttl=1h

该撤销 SQL 针对只读、无对象所有权的角色。若业务账号创建了对象或获得其他依赖授权,DROP 可能失败;不要用未经审查的 DROP OWNED 直接删除业务对象。

5. 应用授权与领取#

保存 orders-app.hcl,交给 EKS / AppRole 等身份绑定:

path "kv/data/prod/orders/config" {
  capabilities = ["read"]
}
path "database/creds/orders-read" {
  capabilities = ["read"]
}
vault policy write orders-app orders-app.hcl

使用已绑定 orders-app 的短期应用身份验证,结果写入受限临时文件:

umask 077
VAULT_DB_TEST_DIR=$(mktemp -d)
vault read -format=json database/creds/orders-read > "$VAULT_DB_TEST_DIR/creds.json"

PGPASSWORD="$(jq -r '.data.password' "$VAULT_DB_TEST_DIR/creds.json")" psql "host=orders-db.internal dbname=orders user=$(jq -r '.data.username' "$VAULT_DB_TEST_DIR/creds.json") sslmode=verify-full sslrootcert=/secure/platform/database-ca.pem" -v ON_ERROR_STOP=1 -c 'SELECT id, status FROM orders.order_summary;'

临时 PGPASSWORD 只用于管理终端验证,不写 shell 日志,不作为生产注入方式;生产通过 Agent 文件与连接池接口消费。客户端 CA 路径与 Vault 服务端的 CA 路径分别准备。

验收:SELECT 成功;用同一身份尝试 INSERT 应因权限不足失败,读取其他 Vault 业务路径也应失败。

6. 续期与撤销#

用具备目标 lease 管理权限的运维身份,针对本次测试 lease 操作;不要把整个 sys/leases/* 管理权授予应用:

VAULT_DB_LEASE_ID=$(jq -r '.lease_id' "$VAULT_DB_TEST_DIR/creds.json")
vault lease renew -increment=15m "$VAULT_DB_LEASE_ID"
vault lease revoke "$VAULT_DB_LEASE_ID"

重新执行上一节的新连接测试应失败。已有数据库会话不一定立即断开;密码 VALID UNTIL 也不是现有连接的强制终止计时器。紧急隔离还需数据库侧终止会话与网络控制。

续期受 role/mount 的最大 TTL 限制;到期、撤销或不可续期后必须领取新账号。Vault 无法访问数据库时撤销可能延迟,需监控失败并核查数据库残留角色。

动态凭据也受签发它的 Vault token 生命周期影响:父 token 被撤销或过期时,其关联 lease 可能一并撤销。设计和演练时同时考虑 token 与数据库 lease,不能只按 role 的 max_ttl 估算可用时间。

7. 应用上线要求#

项目 必须实现
获取频率 每实例/连接池复用一个有效 lease,不按每次 HTTP 请求领取账号
更新 Agent 文件变化后建立新连接池,健康后排空旧池
时间 连接最大寿命小于凭据可用窗口,并预留续期/重试时间
Vault 中断 有效凭据可短暂继续使用;到期后不无限重试或回退硬编码密码
数据库故障切换 连接重建后继续校验证书;验证 plugin 能连接新的 writer
数据库对象 migration 使用独立身份,业务动态账号不创建 schema/table

确认撤销成功、删除临时凭据文件后结束实验。下一步:EKS + Agent 自动领取与更新。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭