Skip to content

Commit aaefebf

Browse files
committed
debug(ch2-lease): 加回 step2 + step3
1 parent 2b29274 commit aaefebf

2 files changed

Lines changed: 135 additions & 0 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# 第二步:max_lease_ttl 是续约的硬天花板
2+
3+
文档 §3.2 的核心论断:
4+
5+
> 任何一份机密,从签发那一刻起,最多只能活 `max_ttl`
6+
> **无论续约多少次**
7+
8+
我们的 `readonly` 角色配置:`default_ttl=1m``max_ttl=5m`
9+
这一步要把这条天花板撞出来。
10+
11+
继续用第 1 步留下的 `$FULL_LEASE_ID`(如果新开的终端,重新算一遍):
12+
13+
```bash
14+
LEASE_ID=$(vault list -format=json sys/leases/lookup/database/creds/readonly | jq -r ".[0]")
15+
FULL_LEASE_ID="database/creds/readonly/$LEASE_ID"
16+
echo "$FULL_LEASE_ID"
17+
```
18+
19+
申请一个**远超 max_ttl 的 increment**——比如 1 小时:
20+
21+
```bash
22+
vault lease renew -increment=3600 "$FULL_LEASE_ID"
23+
```
24+
25+
注意输出里的 `lease_duration` 字段:**它绝对不会是 3600,最多是 300(5 分钟)**
26+
而且实际上会更小——具体值 = `issue_time + max_ttl - now`,也就是
27+
"距离这条租约的死刑日还剩多久"。
28+
29+
这正是文档 §4.2 强调的:
30+
31+
> The requested increment is completely advisory.
32+
33+
再连续续两次:
34+
35+
```bash
36+
sleep 5 && vault lease renew -increment=3600 "$FULL_LEASE_ID"
37+
sleep 5 && vault lease renew -increment=3600 "$FULL_LEASE_ID"
38+
```
39+
40+
每次都申请 1 小时,每次返回的 `lease_duration` 都在**单调递减**。这就是
41+
天花板效应——再怎么续,也越不过最初签发时锁定的 5 分钟死刑日。
42+
43+
为了直观看到死刑日,看一下完整的 lookup:
44+
45+
```bash
46+
vault lease lookup "$FULL_LEASE_ID"
47+
```
48+
49+
注意:
50+
51+
- `issue_time` 是固定的(第 1 步签出来时刻)
52+
- `expire_time` 永远 ≤ `issue_time + 5m`
53+
- `last_renewal` 这次开始有值了
54+
55+
等到这条租约过了 5 分钟自然死亡(或者直接进入第 3 步,反正它会自己消失),
56+
你就会看到对应的 Postgres 用户被 Vault 删掉。
57+
58+
> **生产含义**:如果你的应用号称"我会一直续约所以可以拿一份永久凭据"——
59+
> 不可能。`max_lease_ttl` 是底线安全保障,强迫每一份机密都有一个**确定的
60+
> 失效时刻**。这样泄露后的爆炸半径就能被精确量化为「最多 max_ttl」。
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# 第三步:increment 是「从现在开始算」——可以主动缩短租约
2+
3+
这一步演示文档 §4.1 那条最反直觉的论断:
4+
5+
> The requested increment is **not** an increment at the end of the current
6+
> TTL; it is an increment from the current time.
7+
8+
也就是说,**应用可以通过续约让自己手里的凭据提前过期**
9+
10+
签一份新凭据(前一份大概率已经被天花板撞死了):
11+
12+
```bash
13+
vault read database/creds/readonly
14+
LEASE_ID=$(vault list -format=json sys/leases/lookup/database/creds/readonly | jq -r ".[-1]")
15+
FULL_LEASE_ID="database/creds/readonly/$LEASE_ID"
16+
```
17+
18+
看一眼当前 TTL(默认 60 秒):
19+
20+
```bash
21+
vault lease lookup "$FULL_LEASE_ID" | grep -E "ttl|expire"
22+
```
23+
24+
现在做一件"看起来在续约、实际在缩短"的事——申请 increment=10:
25+
26+
```bash
27+
vault lease renew -increment=10 "$FULL_LEASE_ID"
28+
```
29+
30+
返回的 `lease_duration`**10**,不是 60。再确认一下:
31+
32+
```bash
33+
vault lease lookup "$FULL_LEASE_ID" | grep -E "ttl|expire"
34+
```
35+
36+
`expire_time` 已经被往****挪到了"现在 + 10s"。再过 10 秒:
37+
38+
```bash
39+
sleep 12 && vault lease lookup "$FULL_LEASE_ID" 2>&1 || echo "(已过期)"
40+
```
41+
42+
应该看到 `invalid lease`——这条凭据已经被 Vault 自动 revoke 了,对应的
43+
Postgres 用户也消失了:
44+
45+
```bash
46+
docker exec -i learn-postgres \
47+
psql -U root -c "SELECT usename, valuntil FROM pg_user WHERE usename LIKE 'v-%';"
48+
```
49+
50+
## 这个设计为什么有用?
51+
52+
回想一下应用的真实场景:
53+
54+
> 我的请求 handler 拿一份数据库凭据,**只会用 5 秒**——
55+
> 不需要默认的 1 分钟 TTL,更不需要 5 分钟的 max_ttl。
56+
57+
按这个模型,应用应该:
58+
59+
1. `vault read database/creds/readonly` 拿凭据;
60+
2. **立刻** `vault lease renew -increment=10`,把租约缩到 10 秒;
61+
3. 用完就完,不需要主动 revoke——10 秒后 Vault 自己回收。
62+
63+
这样 Postgres 里同时存活的临时用户数量就被压到了**实际并发数 × 10 秒**
64+
而不是 **实际并发数 × default_ttl**。一个大流量服务靠这种"自缩短"
65+
模式,能让目标系统侧的资源占用降一个数量级。
66+
67+
> 文档 §4.1 把这种用法描述为:
68+
>
69+
> > makes it easy for users to reduce the length of leases if they don't
70+
> > actually need credentials for the full possible lease period, allowing
71+
> > those credentials to expire sooner and resources to be cleaned up earlier.
72+
73+
`vault-basics` 第 4 步的 `vault lease renew "$FULL_LEASE_ID"` 命令没有
74+
`-increment`,那种用法是"按服务端默认顶满"。带上 `-increment=N`
75+
是真正用足这个 API 的能力。

0 commit comments

Comments
 (0)