Skip to content

[数据库] Hub Redis 键面审计(TTL/有界性/失效路径) #2119

Description

@DeliciousBuding

背景

hub-server 用 Redis 承载鉴权令牌黑名单、限流窗口、在线状态路由、离线消息队列、OIDC state、relay 命令等,但「谁写了什么键、TTL 多少、有没有永不外溢的无界键」从未系统盘点。本 issue 是纯审计产出,不含代码变更。

审计范围:hub-server/internal/ 全部 Redis 写入(cache client 封装 + GetRDB() 旁路 + middleware)。方法:静态代码审计(grep rdb./pipe./GetRDB().*Set|HSet|SAdd|ZAdd|LPush|RPush|Incr|Expire),未执行开发库写操作。

键面矩阵

# 键模板 写入方 file:line TTL 有界性 清理/失效路径
1 session:members:<sessionID> cache.GetOrLoad @ app/events.go:27 (client.go:70 Set) SessionMemberCacheTTL=5min + ±10% jitter string Invalidate @ service/session/service_members.go:71,116,153,186,252,332
2 session:meta:<sessionID> 写入点未定位(仅见 Invalidate) 推测 5min+jitter string Invalidate @ service/session/service_members.go:186,252,284
3 user:profile:<userID> 写入点未定位(仅见 Invalidate @ service/auth/service.go:221) 未知 string Invalidate only
4 user:friends:<userID> 写入点未定位(仅见 Invalidate @ service/contact/service.go:196,271,291,344,366,378) 未知 string Invalidate only
5 session:seq:<sessionID> Incr @ cache/client_auth.go:15 + Expire line 23;SetNX line 29;Set line 36 30d string (int64) 自然过期;SetSeq 覆盖
6 rt_blacklist:<tokenHash> Set @ cache/client_auth.go:52 调用方传入 ttl(refresh token 剩余有效期) string 自然过期
7 at_blacklist:<jti> Set @ cache/client_auth.go:81 调用方传入 ttl(access token 剩余有效期) string 自然过期
8 ratelimit:<key> Incr @ cache/client_auth.go:117 + Expire line 122 60s(滑动窗口) string (counter) 自然过期
9 device_route:<userID> HSet @ cache/client_routes.go:25 + Expire line 28 7d hash(字段数=在线设备数) HDel @ client_routes.go:34;HDel 后不检查 HLen=0
10 kicked:<connID> Set @ cache/client_routes.go:83 60s string 自然过期
11 rate_limit:<keyFn> ZAdd @ middleware/rate_limit.go:49 + Expire line 56 window + 10s buffer zset(ZRemRangeByScore 清过期成员) 自然过期 + 滑动清理
12 pending_tasks:<userID> LPush+LTrim @ cache/client_pending.go:77,81 + Expire line 82 PendingTaskTTL=24h list,LTRIM cap=256 PopPendingTasks Del line 117
13 pending_tasks:<userID>:device:<deviceID>:targets SAdd @ cache/client_pending.go:145 + Expire line 146 24h set SRem line 229,277;Del line 286,303
14 pending_tasks:<userID>:device:<deviceID>:target:<targetID> RPush @ cache/client_pending.go:147 + Expire line 148 24h list,无 LTrim cap Del line 228,300
15 pending_tasks:<userID>:device:<deviceID>:target_order RPush @ cache/client_pending.go:149 + Expire line 150 24h list,无 LTrim cap Del line 240,302
16 pending_controls:<userID>:device:<deviceID> RPush+LTrim @ cache/client_pending.go:314,315 + Expire line 316 24h list,LTRIM cap=256 AckPendingAgentControl LRem+Del-if-empty line 351,365
17 oidc:state:<state> Set @ service/oidc/oidc.go:149 10min string GetDel @ oidc.go:254(一次性消费)
18 relay:cmd:<id> Set @ service/relay/relay.go:54,97 24h string 无主动 Del
19 migration:legacy-seq-sync:v1 SetNX @ app/background.go:235 0(永不过期) string Del @ background.go:288(仅中断时清理;成功后永久保留)

风险清单(按严重度)

P1 — 需修复

  1. 无 TTL 持久键migration:legacy-seq-sync:v1 (chore(repo): 收口仓库卫生和轻量检查 #19)

    • 迁移完成后永久驻留 Redis;违反「所有键应有 TTL」原则
    • 建议:迁移成功后显式 Set TTL(如 30d)或改为 Del;若刻意保留作幂等标记,补注释+监控
  2. 集合类无上限pending_tasks:...:target:<targetID> (M1: 前端 #14) 与 ...:target_order (M1: 后端 #15)

P2 — 建议优化

  1. HDel 后空 hash 残留device_route:<userID> (docs: 完成中文化治理和 Hub Server 需求归档 #9)

    • DeleteRoute 移除最后字段后空 hash 驻留至 7d TTL;IsOnline 用 HLen>0 判断不受影响,但浪费内存
    • 建议:DeleteRoute 后 HLen==0 则 Del key
  2. 写入点未定位的 Invalidateuser:profile:* (M0: 锁定 authority、EventStore 和数据通道契约 #3), user:friends:* (M0: 定义审批策略循环和 workspace 隔离契约 #4), session:meta:* (M0: 对齐 Go 服务布局、module 策略和包归属 #2)

    • Invalidate 存在但找不到 Set/GetOrLoad;可能是历史残留或遗漏写入路径
    • 建议:全仓搜索确认;残留则删无效 Invalidate;遗漏则补写入
  3. relay:cmd 无主动清理relay:cmd:<id> (docs: 统一三部分命名和隐私规则 #18)

    • AckCommand 后状态变 acked 仍占满 24h;高频 relay 场景堆积
    • 建议:AckCommand 后缩短 TTL(如 1h)或 Del

P3 — 已知可接受

修复切片建议(≤3 条)

  1. 切片 A(P1):给 pending_tasks:...:target:<targetID>...:target_order 加 LTrim cap=256;改 migration:legacy-seq-sync:v1 为成功后 Set TTL=30d 或 Del。预计改动 ≤2 文件。
  2. 切片 B(P2)DeleteRoute 后检查 HLen==0 则 Del;AckCommand 后缩短 relay:cmd TTL 至 1h。预计改动 ≤2 文件。
  3. 切片 C(P2 调查):全仓搜索 user:profile: / user:friends: / session:meta: 写入点;确认为残留则删除无效 Invalidate;确认为遗漏则补 GetOrLoad 写入。预计改动视调查结果而定。

基线

抽查级证据

  1. device_route:<userID> → HSet @ hub-server/internal/cache/client_routes.go:25 → TTL=7d(line 28)→ HDel @ line 34(不检查 HLen=0)
  2. pending_tasks:<userID> → LPush+LTrim @ hub-server/internal/cache/client_pending.go:77,81 → TTL=24h(config.PendingTaskTTL)→ cap=256(pendingTaskQueueMaxLen)→ PopPendingTasks Del @ line 117
  3. migration:legacy-seq-sync:v1 → SetNX TTL=0 @ hub-server/internal/app/background.go:235 → 永不过期 → Del @ line 288(仅中断时清理)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium prioritysize-MMedium effort后端Hub Server、Edge-Hub 通信和后端服务

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions