已经花了43,643,874Tokens 说实话我看不懂
fnOS/TRIM NAS WebSocket 2FA 登录问题 — 排查总结
环境
• NAS: fnOS/TRIM, 192.168.5.125:5666
• 用户: shashamajie520 (管理员)
• 2FA: 已绑定 TOTP (Microsoft Authenticator) + 已绑定安全邮箱
• 当前状态: isTwofaEnforced=false, isBindTwofaSecret=true, isTrustedDevice=false
问题现象
通过 WebSocket API (ws://<host>:5666/websocket) 登录,流程如下:
Step 1: user.login → 成功返回 accessToken,但无 token(即使 isTwofaEnforced=false)
Step 2: user.2fa.loginVerify → 无论使用何种参数组合,均返回 errno=8192
已尝试的验证方式(全部失败)
方式 参数 结果
─────────────────────────── ──────────────────────────────────────────────────────────────── ──────────
TOTP 码 {code, accessToken} errno=8192
TOTP 码 + trust {code, accessToken, trust:true} errno=8192
邮箱验证码(code字段) {code:HJsqWAB3, accessToken} errno=8192
邮箱验证码(email+emailCode) {email, emailCode, accessToken} errno=8192
前端精确参数 {code, isTrustedDevice:false, stay, deviceName, deviceType, did} errno=8192
信任设备跳过 {isTrustedDevice:true, accessToken} errno=8192
appcgi.tfa...totpVerify data包装 {code, accessToken} 超时无响应
关键发现
appcgi.tfa...totpVerify data包装 {code, accessToken} 超时无响应
关键发现
1. 错误码 8192 = E_PARAM_ERROR(参数错误)
从 JS 反编译确认:
8192: "参数错误" (E_PARAM_ERROR)
135168: "无效的凭证" (E_INVALID_TOKEN)
所以 8192 并非验证码无效,而是请求格式有问题。
2. 根本原因:缺少 si(Session Integrity)参数
从 Web UI JS 反编译发现,前端登录调用 util.crypto.getRSAPub 获取 si(会话完整性标识),然后所有 user.* 请求都需携带 si 字段。我们之前的请求不带
si,所以服务端返回"参数错误"。
验证结果:
• ❌ 不带 si: user.2fa.loginVerify → errno=8192
• ✅ 带 si: user.2fa.loginVerify → errno=135168(真正的"验证码无效",说明参数正确了)
3. isBindTwofaSecret=true 的持久性问题
即使 SSH 进 NAS 清空所有 4 张数据库表(twofa_rule, twofa_setting, user_security_setting, user_security_setting_tmp — 全部为空),user.login 响应中 isBindTwofaSecret=true
仍然持续。该标志的存储位置不明(不在 PostgreSQL 中),可能存储在:
• TFA 服务的内存/加密文件
• /usr/trim/etc/trim.key.enc 或类似加密配置
• 其他数据库(trim_sac, trim_connect 等)
4. isTwofaEnforced=false 但不放行
当 isTwofaEnforced=false 且 isTrustedDevice=false 且 isBindTwofaSecret=true 时,登录不返回 token,必须走邮箱验证码流程。但邮箱验证码又持续 8192,形成死锁。
建议论坛反馈方向
1. WebSocket API user.2fa.loginVerify 文档缺失 — 缺少 si 参数的说明
2. isTwofaEnforced=false 时登录行为 — 当 2FA 不强制但密钥仍绑定时,应返回 token 直接登录还是必须验证?
3. sendEmailCode 发送的验证码用途不明 — 邮件提示"重置双重验证",但无法确认该码适用于哪个端点
4. isBindTwofaSecret 的存储位置 — 数据库清空无效,建议统一管理