安全模型
AuthNexus 以 fail-closed 为核心安全哲学:在任何安全组件不可用或验证失败时,系统默认拒绝而非放行。
Fail-Closed 设计
PKI 未初始化
四类 CA 未全部完成初始化时,Control Plane 仅开放部署向导端点 (/admin/v1/setup/*):
/cp/*南向接口不开放- 业务节点无法注册
- 系统处于安全的最小功能状态
CP Agent 未就绪
Server App 的 CP Agent 必须成功连接到 Control Plane 并应用关键配置后,才开放业务 TLS 端口:
- 配置应用失败 → 不开放端口
- CP 连接失败 → 不开放端口
- 关键证书缺失 → 不开放端口
CA 替换失败
CP Node Client CA 的 reconcile 是 fail-closed 的:reconcile 失败时节点无法连接 CP,直到问题解决。App Client CA 热替换期间,旧 TLS context 上的在途握手被拒绝。
证书吊销
节点证书被吊销时,Server 继续 staple revoked 的 OCSP 响应,SDK must-staple 验证拒绝握手。业务面立即中断,但管控通道保持存活以便恢复。
密码哈希
算法选择
AuthNexus 使用高速版本化 HMAC-SHA256 作为密码哈希算法,而非传统的 Argon2、bcrypt 或 scrypt。
设计取舍:优先在线高吞吐与低延迟,而非离线抗暴力破解。这一选择基于以下考量:
- 认证请求走 mTLS TCP 二进制协议,攻击面远小于开放 HTTP
- 四道 mTLS 约束已在网络层大幅收窄攻击者可达的认证端点
- 业务场景要求每秒处理大量认证请求,传统慢哈希成为瓶颈
- 通过 HMAC 密钥(服务端持有)提供额外安全层——即使数据库泄露,无密钥无法离线爆破
哈希格式
$authnexus-fast-hmac-sha256$v=1$<salt_hex>$<hash_hex>| 字段 | 说明 |
|---|---|
authnexus-fast-hmac-sha256 | 算法标识 |
v=1 | 版本号 |
<salt_hex> | 16 字节随机 salt(hex 编码) |
<hash_hex> | 32 字节 HMAC-SHA256 输出(hex 编码) |
域分离
HMAC 计算使用固定的域分离字符串 AuthNexusPasswordFastHashV1,确保同一密钥在不同场景下产生不同的哈希值。
旧格式拒绝
系统拒绝所有旧格式的密码哈希:
- SHA256 裸哈希
- Argon2id 格式(
$argon2id$...) - 其他非标准格式
遇到旧格式时返回认证失败,不做自动迁移。
认证 Epoch 机制
认证 epoch 是一个全局递增的版本号,用于批量失效认证状态。
工作原理
Admin 递增 epoch → CP 写入 Control DB
→ Channel ② 推送 epoch.bumped
→ Channel ③ DeltaPuller 拉取变更
→ Server 更新本地 Runtime DB + 内存缓存
→ 所有旧 epoch 的 token 立即失效使用场景
- 紧急安全事件:发现系统被入侵时,递增 epoch 立即踢出所有在线用户
- 全局密钥轮换:更换 token 签名密钥后递增 epoch
- 策略批量生效:某些策略变更需要所有用户重新认证
数据同步
epoch 变更通过 auth_epoch_changes 表增量同步。Server 端 RuntimeSecurityDeltaPuller 负责拉取并落入本地 Runtime DB。当 Channel ② SSE 健康时通过事件触发即时拉取;降级时以 800ms 间隔轮询。
服务端黑名单
架构
Server 的运行时黑名单以本地 Runtime DB 为单一真相来源:
- 黑名单数据从 CP 通过
server_blacklist_changes表增量同步 - 写入本地 Runtime DB 后加载到内存缓存
- 认证检查直接查内存,不走远程调用
- 无 CP 下发快照模式(已移除历史选项
AUTHNEXUS_SERVER_BLACKLIST_USE_DB)
黑名单检查
认证流程中的黑名单检查发生在密码验证之后、token 签发之前:
收到认证请求
→ 解析协议
→ 验证 mTLS(四道约束)
→ 查找用户
→ 验证密码 / 卡密
→ 检查黑名单 ← 此处
→ 检查 epoch
→ 签发 token
→ 返回成功变更同步
黑名单变更通过 Channel ③ DB Delta 同步,与 epoch 共用 RuntimeSecurityDeltaPuller。自适应拉取间隔同样根据 Channel ② 健康状态动态调整。
限速与防护
认证限速
Server 对认证请求实施限速(rate limiting),防止暴力破解:
- 按源 IP 限速
- 按用户名限速
- 超过阈值返回限速响应,不执行密码验证
会话安全
- Token 有有效期,过期后必须重新认证
- Session 状态 mutation 在任意线程都安全(Session 内部 mutex)
- 单 session 串行由 connection read_loop 的
await dispatch自然保证
访问控制
平台管理员 vs 应用代理
AuthNexus 通过 agents.kind 字段区分两类管理角色:
| Kind | 说明 | app_id |
|---|---|---|
platform_admin | 全平台管理员 | NULL(不绑定应用) |
app_agent | 应用级代理 | 引用真实 application |
三道数据库约束保证不变量:
- Schema CHECK:
kind只能是'platform_admin'或'app_agent' - FK ON DELETE RESTRICT:
app_agent的app_id外键约束 - Partial UNIQUE:按 kind 分区的唯一性约束
业务实体约束
所有业务实体(cloud_function、user、cardkey、variable 等)强制 app_id > 0:
- Schema 层
CHECK (app_id > 0)约束 - 代码层
validate_business_app_id函数校验 - 源码审计测试
AgentKindIsExplicit同时固定这两类约束
历史上的 app_id = 0 sentinel 用法已完全移除。
代理层级
代理(Agent)支持多级树形结构:
- 平台管理员位于树的根部
- 应用代理通过
agent_app_grants表关联多个应用 - 子代理继承上级的权限范围
- 佣金结算按代理层级向上汇总
云函数沙箱
云函数使用 Lua 5.4 运行时,严格沙箱化:
禁用模块
以下标准库模块在沙箱中不可用:
io— 文件 IOos— 操作系统接口debug— 调试库package— 包管理require— 模块加载dofile/loadfile— 文件执行
执行限制
| 限制项 | 默认值 |
|---|---|
| 执行超时 | 1000ms |
| 每函数唯一性 | app_id + name 唯一 |
| 执行隔离 | 独立 cloud_function_threads 线程池 |
| 背压控制 | cloud_function_max_in_flight 并发限制 |
云函数执行在专用线程池中运行,不复用 IO/DB/Crypto 线程,避免恶意或低效脚本影响核心业务。
审计与可观测
审计日志
关键操作记录审计日志,存储在 Control DB 中:
- 管理员登录/登出
- 配置变更
- 证书操作
- 用户管理操作
- 代理权限变更
节点指标
节点通过 Channel ① 的 checkin 端点上报运行指标,包括连接数、请求速率、错误率等。
用户在线状态
在线用户数据通过节点 checkin 上报到 CP,由 NodeUserPresence 聚合,管理后台可实时查看。