2FAuth 8.0.3 安全加固指南

2FAuth 8.0.3 安全加固指南:围绕注册管控、WebAuthn 登录、落库加密、反向代理与 TLS、限流与安全开关、密钥管理、日志审计、备份灾备八大面给出可直接执行的加固清单,并坦诚讨论服务端验证码的威胁模型。

2FAuth安全加固双因素认证2FAuth2026/10/24

2FAuth 8.0.3 安全加固指南

本文是 2FAuth 专栏的加固篇。2FAuth 存的不是普通数据,而是能通过你所有二次验证的 TOTP/HOTP 密钥——它一旦泄露,攻击者等于拿到了你所有账户的第二把钥匙。因此这篇加固指南的优先级高于一般自托管组件。文中机制均基于 8.0.3 官方文档与 .env 模板实查(2026-10-24),默认配置基线在实测环境中核查过。部署与参数背景分别见部署篇与配置篇。

一、威胁模型先讲清楚

自托管验证器与手机验证器(Aegis、Ente Auth 这类本地 App)的根本差异:密钥在服务器上,且验证码经浏览器传输。对应四条攻击面:

  1. 服务端拖库——数据库被拖走,未加密的 OTP 密钥直接可用;
  2. 会话劫持——登录态被偷,验证码任意取;
  3. 传输截获——明文 HTTP 下验证码与密钥裸奔;
  4. 应用层注入——XSS/SSRF 类漏洞被利用。

第 1、2、3 条可以在配置层面压到很低,第 4 条依赖版本跟进(锁 8.0.3 补丁线)+ 出厂默认的两个安全开关。下面按「先堵大洞、再收细流」的顺序展开。

二、注册管控:第一优先级

2FAuth 自 v4.0 起是多用户应用,注册入口有四档:完全开放、按邮箱域名限制、完全关闭、仅 SSO。部署完成、注册完首个管理员后立即关闭自助注册是所有加固动作里性价比最高的一步——公网实例开放注册等于把验证码保险库的房门挂在了网上。

实操路径:管理员登录 → 设置中关闭公开注册(或限定组织邮箱域)。多用户团队的稳妥组合是「关闭注册 + 管理员手工建号」,或「仅 SSO + 反代统一认证」(见第五节)。这些开关对应的用户侧配置可被 USERPREF_LOCKED__* 环境变量锁死,防止个别用户自行放宽,命名规则见《2FAuth 8.0.3 配置参数详解》第九节。

三、登录加固:上 WebAuthn,降密码权重

  • WebAuthn 安全密钥:8.0.3 支持 YubiKey、Titan Key 等硬件密钥登录,且可关闭传统密码登录表单——认证因子从「可撞库的密码」升级为「物理持有的密钥」,这是登录面能做的最强加固。注意 WebAuthn 强依赖站点真实性:APP_URL 必须与浏览器实际访问地址(含端口、协议)完全一致,且生产环境应走 HTTPS 域名,否则注册/认证会失败;
  • 登录限流:LOGIN_THROTTLE=5(默认)对密码与 WebAuthn 两类尝试同时生效,每 IP 每分钟 5 次失败即锁至窗口结束;公网部署保持默认,不要放大;
  • 自动登出:应用内置闲置自动登出,防长效会话;更狠的用法是把策略设为「复制验证码后立即登出」——取完码即失效,会话窗口压到最短。

四、落库加密:把拖库的收益打掉

敏感数据落库加密是可选项,默认关闭。开启后数据库被拖走时 OTP 密钥是密文,没有 APP_KEY 解不开。三条纪律:

  1. 先开加密再录入:对已存在的存量数据,先备份再切换,避免半明文半密文的中间态;
  2. APP_KEY 是命门:官方原话是强烈建议开启加密后备份 .env(至少 APP_KEY)——丢钥等于全部密文作废,且丢钥不可恢复;
  3. 轮换走 APP_PREVIOUS_KEYS:换钥时旧钥必须移入该变量,否则存量密文与 Passport 访问令牌全部解不开(轮换验证步骤见配置篇第十一节)。

配套动作:.env 文件权限收紧到运行账户可读(如 600),密钥类参数在支持 secrets 注入的环境里改走 _FILE 变量(v6.0+ 约定,变量清单与互斥规则见配置篇第十节),避免密钥出现在环境变量明文与进程可见面上。

五、传输与反代:TLS 是底线

  • 前置反向代理 + TLS:生产必须 HTTPS。验证码在 HTTP 明文链路上传输等同把 OTP 发给整条链路的旁观者;
  • TRUSTED_PROXIES:设为代理 IP 列表(不要图省事设 *),否则应用把代理地址当客户端地址,LOGIN_THROTTLE/THROTTLE_API 的按 IP 限流会被「全体共享一个 IP」击穿;
  • reverse-proxy-guard 的信任边界:把 AUTHENTICATION_GUARD 切到 reverse-proxy-guard 后,2FAuth 只认代理头、跳过全部内置认证检查——认证完全托付给代理。这意味着:代理侧必须配置严实(认证头不可伪造、内网不可直达应用端口),应用端口只对代理开放。用不好这个守卫比不用更危险;
  • 证书校验全开:MAIL_VERIFY_SSL_PEER=true、OPENID_HTTP_VERIFY_SSL_PEER=true 均保持默认,任何一项关闭都是官方 WARNING 点名的重大缺陷(自签场景走证书路径而非关闭校验)。

六、应用层安全开关:出厂默认即最优

以下三项 8.0.3 出厂默认即安全态(实测部署基线核查一致),加固核查时确认没有被误关:

开关默认作用关闭后果
CONTENT_SECURITY_POLICYtrue内容安全策略,压缩 XSS 注入收益注入脚本可在会话内自由取码
BLOCK_OPTAUTH_IMAGELINK_FETCHINGtrue阻断 otpauth URI 内图片链接抓取,防盲 SSRF后端可被诱导访问内网地址
APP_DEBUGfalse关闭错误页调试信息报错页泄露路径、配置等环境细节
IS_DEMO_APPfalse演示模式每小时重置并挂通用账号生产开启等于裸奔

版本卫生同样属于应用层加固:镜像/源码锁定不可变版本标签(8.0.3),跟进官方补丁版本再升级,不追 latest(跟随 master 分支,可能含未发布变更)。

七、限流与日志:让攻击留痕、变贵

  • API 限流:THROTTLE_API=60(每 IP 每分钟)与 THROTTLE_API_DURING_IMPORT=1000(导入通道)保持默认;关闭限流(null)只在纯内网可信环境可接受;
  • 审计日志:AUTHENTICATION_LOG_RETENTION=365 与 OTP_LOG_RETENTION=365(默认各 365 天)保留认证与取码记录,超龄自动清理,也可用维护命令即时清理(2fauth:purge-auth-log、2fauth:purge-otp-log);日志级 LOG_LEVEL=notice 够用,调 debug 会放大日志面;
  • API 令牌卫生:走 API 自动化的令牌按需签发、最小范围、定期轮换,不长期硬编码在脚本与 CI 里。

八、数据库与备份:最后的安全网

  • 最小权限数据库账户:专用账户只授予 2FAuth 库的读写,不复用 root;经 SSL 连库时配置 MYSQL_ATTR_SSL_CA 指向根 CA;
  • 备份三件套:数据库转储 + 应用数据目录 + .env(含 APP_KEY)——三者缺一恢复即残废;
  • 恢复演练:备份不做恢复验证等于没有备份,建议至少演练一次「全量恢复到新路径并登录取码」;
  • 备份介质加密:备份内容含全部 OTP 密钥(或密文+密钥),备份本身要进加密存储,权限对齐生产。

九、加固核查清单

上线前逐项打勾(配置项语义与取值详见《2FAuth 8.0.3 配置参数详解》):

#核查项目标状态优先级
1自助注册关闭/限域/仅 SSOP0
2传输HTTPS + TRUSTED_PROXIES 指向真实代理 IPP0
3APP_KEY唯一 32 字节键、.env 权限 600、已入备份P0
4落库加密已开启,APP_KEY 备份到位P0
5APP_URL与实际访问地址完全一致(WebAuthn 前提)P0
6WebAuthn密钥登录已启用,评估关闭密码表单P1
7登录/会话LOGIN_THROTTLE=5,自动登出(可设复制即登出)P1
8安全开关CSP/SSRF 阻断/APP_DEBUG/IS_DEMO_APP 四项安全态P1
9限流THROTTLE_API=60、IMPORT=1000 保持默认P1
10版本锁定 8.0.3 不可变标签,跟进补丁P1
11数据库最权账户 + SSL(可选 MYSQL_ATTR_SSL_CA)P2
12日志审计保留期 365 天,purge 命令纳入例行维护P2
13备份三件套齐 + 恢复演练至少一次P2

十、残余风险与坦诚建议

把上述全部做完后仍剩两块承认给读者的风险:其一,服务器本身被完整攻破(root 级失陷)时,运行中的应用密钥与内存中的验证码无从谈起——落库加密只保「拖库」不保「打穿」;其二,验证码中枢是单点,服务宕机时你取不到码。工程上的对冲是组合部署:手机端保留 Aegis/Ente Auth 等本地验证器作为日常来源,2FAuth 作为服务端灾备中枢,两侧通过 Aegis JSON/2FAS JSON 导出互通(导入支持清单见《2FAuth 8.0.3 介绍与选型指南》)。验证码这种资产,冗余一份不是浪费,是设计。