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-postgresrotate-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 自动领取与更新。