Skip to content

安全模型

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

三道数据库约束保证不变量:

  1. Schema CHECKkind 只能是 'platform_admin''app_agent'
  2. FK ON DELETE RESTRICTapp_agentapp_id 外键约束
  3. 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 — 文件 IO
  • os — 操作系统接口
  • 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 聚合,管理后台可实时查看。

下一步