KPanel 两步验证安全契约
August 1, 2026 · View on GitHub
KPanel 的两步验证使用 RFC 6238 TOTP,默认关闭,由管理员在“设置 → 两步验证”中主动启用。 它用于降低密码泄露、撞库和钓鱼后的账户接管风险,但不能替代 Session、CSRF、路径约束、 Agent 隔离和接口鉴权,也不能防止已经取得服务器代码执行权限的攻击者。
用户流程
- 管理员输入当前密码后,KPanel 生成一次性注册会话、二维码和手动密钥。
- 管理员使用身份验证器扫描二维码,再输入 6 位动态验证码确认启用。
- KPanel 只在确认成功后保存加密密钥,并一次性显示 10 个恢复码。
- 启用后登录必须同时通过密码和动态验证码或一枚未使用的恢复码。
- 重新生成恢复码或关闭两步验证必须再次输入当前密码和当前第二因素。
- 启用、关闭或重置恢复码后撤销该管理员的全部现有 Session,并要求重新登录。
密钥和状态
- TOTP 使用 SHA-1、6 位数字、30 秒周期,并兼容当前周期前后各一个周期的时钟漂移。
- 已使用的 TOTP 周期计数器与启用状态原子持久化;同一验证码不能被并发或重复使用。
- TOTP 密钥使用 Panel 本地
0600AES-256-GCM 密钥加密;密钥缺失或损坏时禁止静默重建。 - 恢复码只保存 SHA-256 摘要,比较使用固定时间操作,成功使用后立即原子删除。
- 二维码、明文密钥、动态验证码和恢复码不得写入审计、日志、任务或浏览器持久化存储。
- 未确认的注册会话只保存在内存,10 分钟失效,单实例最多保留 8 个。
默认加密密钥路径为:
/var/lib/kejilion-panel/totp-encryption.key
可通过 KEJILION_PANEL_TOTP_KEY_FILE 修改,但必须是绝对路径,且不能与 Web 根、Panel Store、
Bootstrap Token 或 Agent Token 重叠。
防绕过边界
- 密码验证通过但缺少第二因素时不创建 Session。
- 登录第二因素失败与密码失败共享 IP 和账户限速;两步验证管理操作另有管理员级重认证限速。
- 状态读取要求有效 Session;启用、关闭和恢复码重置还要求严格 Origin 与 CSRF。
- 后端不提供跳过第二因素的兼容登录入口,也不根据前端字段决定是否校验。
- 受保护 API 仍统一使用服务端 Session 鉴权;TOTP 不会替代各业务接口本身的授权和输入校验。
两步验证不能防御未认证 RCE、路径穿越读取 Session/密钥、会话劫持、供应链植入或遗漏鉴权的 独立 RPC。发布验收必须同时覆盖这些基础边界,不能用“已启用 2FA”作为安全结论。
恢复和运维
- 管理员应将恢复码保存在密码管理器或离线位置;KPanel 不提供恢复码二次查看。
- 丢失身份验证器后,可在登录页切换为恢复码登录,再在设置中重新生成恢复码或关闭后重新启用。
- 同时丢失身份验证器和全部恢复码时,不提供 Web 绕过入口;当前版本只能恢复一份同时包含 Panel Store 与 TOTP 加密密钥的完整备份,或在本机执行经人工审计的离线恢复,不能从网页自动解除第二因素。
- 备份 Panel 数据时必须同时备份 TOTP 加密密钥;只恢复 Store 而缺少密钥时,TOTP 验证会失败。
- 关闭 2FA 后加密密钥文件可以保留,以便未来重新启用;用户记录中的密文和恢复码摘要会清除。
发布验收
- 后端:RFC 向量、时间窗口、TOTP 重放、恢复码重放、密钥损坏、原子写入、Session 吊销和限速。
- HTTP:未认证访问、错误 Origin、缺少 CSRF、密码直登、错误第二因素和敏感字段审计泄露。
- 前端:注册、二维码、恢复码一次性展示、重新登录、恢复码登录和错误提示。
- 兼容:关闭状态保持原密码登录;升级不会自动启用,也不要求更新
kejilion.sh或 Agent 协议。 - 实机:在隔离数据目录完整执行启用、退出、TOTP 登录、恢复码登录、重置和关闭,再验证正常登录。