Decentralization? We're still early!

2FAuth: 可替代谷歌验证器的自托管双因素身份验证(2FA)管理工具

  • 2FAuth: 可替代谷歌验证器的自托管双因素身份验证(2FA)管理工具

    發布人 Brave 2024-08-04 13:21

    2FAuth 是一种基于 Web 的自托管双因素身份验证(2FA)管理工具,旨在替代 Google Authenticator 等一次性密码(OTP)生成器。它专为移动设备和桌面设备设计,提供了简洁友好的界面,方便用户在任何设备上高效地执行 2FA 步骤。

    作为一个完全开源的项目(GitHub 仓库:Bubka/2FAuth),2FAuth 赋予用户对个人安全数据的完全控制权——你的认证密钥存储在你自己的服务器上,不会被发送到任何第三方云端,没有数据挖掘、没有第三方分析、也没有服务停运的风险。

    与传统移动端 2FA 应用(如 Google Authenticator、Authy)不同,2FAuth 运行在浏览器中,具备响应式 Web 界面。这意味着你可以在桌面上直接生成验证码,而无需每次都拿起手机。此外,2FAuth 还可作为 PWA(渐进式 Web 应用)安装,或通过浏览器固定标签页、快捷方式随时访问,确保 2FA 验证始终触手可及。

    截至 2026 年 2 月,2FAuth 的最新版本为 v6.0.0,自项目诞生以来持续迭代,功能日趋完善,已成为自托管 2FA 领域最受欢迎的开源解决方案之一。


    一、主要功能

    1. 账户管理 📋

    2FAuth 允许用户管理他们的 2FA 账户,并使用分组功能进行组织。用户可以对账户执行完整的 CRUD 操作(创建、查看、编辑、删除),并通过"分组"(Groups)功能将账户按照服务类型、用途或其他自定义维度进行分类管理。例如,你可以创建"社交媒体""金融服务""开发工具"等分组,将对应的 2FA 账户归入其中,从而在账户数量增多时依然保持井然有序。

    此外,2FAuth 还支持从高级表单直接将新账户分配到指定分组,省去了后续手动整理的步骤。在主界面的"管理"模式下,用户可以通过拖拽操作自定义账户排列顺序,实现直观的可视化管理。

    2. 二维码扫描 📷

    用户可以扫描和解码任何二维码,以快速添加账户。2FAuth 内置的二维码解码器不仅支持标准的 2FA 二维码(otpauth:// 协议),还能解析任意类型的二维码内容。扫描功能依赖设备摄像头,因此需要通过 HTTPS 协议访问 2FAuth 才能启用摄像头权限(这是浏览器安全策略的要求)。

    ⚠️ 注意:如果你通过反向代理部署 2FAuth,务必确保启用了 HTTPS,否则二维码扫描功能将无法正常工作。尤其在 Tailscale 等虚拟网络环境中,需要额外配置证书以确保摄像头权限的正常获取。

    3. 自定义账户添加 ✏️

    通过高级表单,用户可以添加没有二维码的自定义账户。高级表单允许用户手动输入以下关键参数:

    • 服务名称与账户标识(如 GitHub - user@example.com
    • OTP 类型(TOTP 或 HOTP)
    • 密钥(Secret):Base32 编码的共享密钥
    • 算法:SHA-1(默认)、SHA-256 或 SHA-512
    • 位数(Digits):生成的验证码位数,通常为 6 位或 8 位
    • 时间步长(Period):TOTP 验证码的刷新间隔,默认 30 秒
    • 计数器(Counter):仅 HOTP 模式下使用的初始计数值

    这一功能对于那些只提供文本密钥而不提供二维码的服务尤为重要,也方便高级用户对 OTP 参数进行精细化控制。

    4. 安全代码生成 🔐

    支持生成 TOTP 和 HOTP 安全代码,以及 Steam Guard 代码。这是 2FAuth 的核心功能——为用户实时生成一次性密码。为了更深入理解这一机制,有必要了解 TOTP 和 HOTP 的技术原理:


    💡 TOTP 与 HOTP 技术原理

    HOTP(基于 HMAC 的一次性密码,RFC 4226)TOTP(基于时间的一次性密码,RFC 6238) 是两种主流的 OTP 生成算法,构成了现代 2FA 体系的技术基石。

    🔹 HOTP(RFC 4226)— 基于事件计数器

    HOTP 的核心是 HMAC(基于哈希的消息认证码)算法,它使用两个关键输入来生成验证码:

    • 📌 一个仅服务器和客户端设备知晓的共享密钥(Secret Key)
    • 📌 一个每次生成 OTP 时递增的事件计数器(Counter)

    生成过程:对共享密钥和计数器执行 HMAC-SHA1 运算 → 对 160 位哈希结果进行动态截断(取 31 位)→ 对截断值执行模运算(mod 10^n),最终得到人类可读的 6-10 位数字验证码。

    HOTP 的主要缺陷在于计数器同步问题——如果用户意外多按了几次生成按钮,客户端的计数器就会与服务器端不一致,导致验证失败。为缓解此问题,服务器通常会接受一定窗口范围内的计数器值。

    🔹 TOTP(RFC 6238)— 基于时间窗口

    TOTP 本质上是 HOTP 的时间扩展版本,其公式为:TOTP = HOTP(K, T),其中 K 为共享密钥,T 为当前 Unix 时间戳除以时间步长(默认 30 秒)所得的整数值。

    TOTP 用当前时间替代了事件计数器,从而消除了计数器同步的难题——因为计算机通过 NTP 协议已经在进行时间同步。验证码每 30 秒自动刷新,过期即失效,进一步提升了安全性。

    对比维度HOTP(RFC 4226)TOTP(RFC 6238)
    驱动因子事件计数器时间值
    有效期使用前一直有效每 30 秒自动过期
    同步机制需要手动同步计数器依赖设备时钟自动同步
    安全性暴力破解是主要威胁时间窗口机制额外增强安全性
    应用场景硬件令牌(如银行 U 盾)主流 2FA 应用的首选方案

    当今绝大多数在线服务(GitHub、Google、AWS 等)采用的都是 TOTP 方案。


    🔹 Steam Guard 代码

    2FAuth 还特别支持 Steam Guard 验证码的生成。Steam Guard 使用的是 Valve 自定义的 OTP 算法变体,其生成的验证码由 5 位字母数字组成(而非标准的 6 位纯数字),刷新间隔同样为 30 秒。这对于 Steam 游戏平台的重度用户来说是一个非常实用的功能。

    🔹 OTP 模糊化与下一码预显示

    2FAuth 提供 OTP 模糊化功能,默认隐藏生成的验证码,需要用户主动点击才能显示,防止旁人窥视。v6.0.0 还新增了"预计算并显示下一个 OTP 验证码"的偏好设置——下一个验证码会以淡入动画缓慢显示,同时保持当前验证码的可读性,让用户在时间窗口切换时无缝衔接。

    5. 数据导入与导出 🔄

    支持多种格式的数据导入和导出,方便备份和恢复。2FAuth 的迁移系统设计精良,能够有效降低用户从其他 2FA 应用迁移的门槛:

    📥 支持导入的来源格式:

    来源应用导入格式备注
    2FAuthJSON 文件原生备份恢复
    Google AuthenticatorQR 码扫描通过 Google Authenticator 的"导出账户"功能生成迁移二维码
    Aegis AuthenticatorJSON 文件(明文/加密)需在 Aegis 中导出时取消加密选项(或使用支持加密的导入)
    2FAS AuthenticatorJSON 文件从 2FAS 的"备份"→"导出"功能生成 .2fas 迁移文件

    📤 导出功能:

    在 2FAuth 主界面点击"管理"按钮进入编辑模式,选择要导出的账户(可使用"全选"按钮),然后点击"导出"按钮即可下载 JSON 格式的迁移文件。2FAuth 使用自定义的 JSON Schema 来结构化导出数据。

    📌 导入流程细节:

    导入过程分为两个阶段:① 预加载与验证——2FAuth 检查数据格式合规性,并通过比对现有数据库中的账户来标记可能的重复项(重复项仅被标记,仍可选择导入);② 录入——用户可选择导入全部或部分有效数据。不符合 OTP 规范的账户会被自动跳过。

    6. 浏览器扩展 🌐

    2FAuth 提供官方浏览器扩展(2FAuth-WebExtension),允许用户直接从浏览器工具栏查看和复制 OTP 验证码,无需切换标签页。扩展支持 Firefox 和 Chrome/Edge 浏览器,功能包括:

    • 📌 点击生成或常显生成两种 OTP 展示模式
    • 📌 主题适配,自动匹配浏览器主题
    • 📌 自动锁定,一段时间不活动后自动加锁
    • 📌 密码格式化与 OTP 模糊化

    此外,社区开发者 josh-gaby 还提供了一个基于 Angular 构建的第三方浏览器扩展,可在 Mozilla Add-On 商店和 Chrome 扩展商店直接安装。

    扩展通过 Personal Access Token(PAT)连接到你的 2FAuth 实例,利用 2FAuth 的 RESTful API 远程获取验证码。

    7. RESTful API 🔌

    2FAuth 提供了完整的 REST API,允许外部应用执行大部分 2FAuth 功能——包括账户管理、验证码生成、分组操作等。API 使用基于 OAuth 的 Bearer Token 认证方案(遵循 RFC 6750),用户在 2FAuth 设置中生成 Personal Access Token(PAT)即可使用。

    API 文档提供了轻量级和全屏两种浏览格式,全屏格式还支持历史版本查看、高级搜索、模拟请求(Mocking)等现代功能。这为开发者打造自定义 2FA 工作流提供了强大的基础设施。


    二、安全特性

    1. 用户模式与多用户支持 👥

    2FAuth 设计为单用户应用 (已过时)自 v4.0 起,2FAuth 已支持多用户模式,你可以与家人、朋友共享同一个 2FAuth 实例,每个人拥有独立的账户和数据空间。v5.1 进一步增强了用户管理能力:

    • 📌 管理员角色可授予给任何注册用户
    • 📌 所有注册账户可搜索,便于管理
    • 📌 管理员可以撤销用户访问权限(密码、个人令牌、安全密钥/通行密钥)
    • 📌 支持删除现有用户创建新用户
    • 📌 注册控制:可设置邮箱限制、自定义注册规则

    管理员面板(Admin Panel)提供了集中管理入口,涵盖加密设置、版本检查、注册控制等此前分散在用户选项中的管理功能。

    2. 现代身份验证:WebAuthn / 通行密钥 🔑

    支持使用安全密钥(如 Yubikey 或 Titan key)进行登录,并可以禁用传统的登录表单。2FAuth 支持 W3C Web Authentication API(WebAuthn)标准,这意味着你可以注册以下类型的安全设备来替代传统密码登录:

    • 📌 硬件安全密钥:YubiKey、Google Titan Security Key 等
    • 📌 生物识别:Apple FaceID、指纹识别等
    • 📌 平台通行密钥(Passkeys):操作系统内置的认证机制

    WebAuthn 的安全优势在于:它基于公钥密码学,登录时需要物理持有安全设备,从根本上杜绝了密码泄露和网络钓鱼攻击的风险。服务器仅存储公钥,即使数据库被入侵,攻击者也无法用公钥冒充用户登录。

    WebAuthn 在 2FAuth 中可以作为传统密码登录的补充或完全替代方案。如果仅启用 WebAuthn 认证,将为你的 2FAuth 实例提供最高等级的访问保护。

    ⚙️ 设备管理与账户恢复:

    • 📌 在 设置 > WebAuthn 中可以撤销任何已注册的安全设备(撤销操作不可逆)
    • 📌 如果丢失了安全设备,可通过 2FAuth 登录页面的"恢复账户"链接,系统会向注册邮箱发送恢复链接,允许你注册新设备并撤销所有现有设备

    3. SSO 单点登录 🌍

    v5.0 引入了 SSO(单点登录)功能,目前支持两种身份提供商:

    • 📌 OpenID Connect——可对接 Keycloak、Authentik、Authelia 等自托管身份提供商
    • 📌 GitHub——直接使用 GitHub 账户登录

    当用户首次通过 SSO 登录时,2FAuth 会自动创建对应的用户账户(透明注册)。SSO 账户与身份提供商绑定后,用户不会获得独立密码,账户信息的变更需要在身份提供商侧完成,每次 SSO 登录时自动同步到 2FAuth。

    管理员还可以将 SSO 设置为唯一的认证方式(Admin > Auth > SSO),此设置不影响管理员账户,管理员仍然可以使用传统方式登录。v5.6 还新增了 Allow PAT usage 设置,确保在 SSO-Only 模式下浏览器扩展仍能通过个人访问令牌正常工作。

    OpenID Connect 的配置通过 .env 文件中的环境变量完成,主要包括:

    OPENID_AUTHORIZE_URL=https://your-provider/authorize
    OPENID_TOKEN_URL=https://your-provider/token
    OPENID_USERINFO_URL=https://your-provider/userinfo
    OPENID_CLIENT_ID=your-client-id
    OPENID_CLIENT_SECRET=your-client-secret

    v5.6 还新增了 OPENID_HTTP_VERIFY_SSL_PEER 变量,用于在 OpenID 认证过程中启用或禁用 SSL 对端验证。

    4. 数据加密 🛡️

    提供多种安全机制来保护用户的 2FA 数据。2FAuth 的加密机制具体包括:

    • 📌 数据库加密:存储在数据库中的敏感数据(即 2FA 密钥/Secret)可通过加密功能进行保护,防止数据库被入侵时密钥泄露。加密默认关闭,需要手动启用。
    • 📌 APP_KEY 保护:加密依赖于 .env 文件中的 APP_KEY 值(必须恰好 32 个字符)。强烈建议在启用加密时备份 APP_KEY 的值或整个 .env 文件——如果丢失 APP_KEY,加密的数据将永久无法恢复。

    ⚠️ 重要提示:加密是一项不可逆操作的保护机制。一旦启用并加密了数据,如果 APP_KEY 丢失,所有加密的 2FA 密钥都将无法解密,你将失去对所有已加密账户的访问权限。因此,务必在启用加密前做好密钥备份。

    5. 自动锁定 ⏱️

    2FAuth 内置自动锁定机制,在一段不活动时间后自动注销用户会话,防止长时间挂起的会话被他人利用。自动注销的触发条件可以自定义配置:

    • 📌 基于不活动时间的自动注销
    • 📌 复制验证码后触发自动注销
    • 📌 完全禁用自动注销功能

    6. 认证事件通知 📬

    v5.2 引入了认证事件通知系统。每个用户可以独立设置是否在以下事件发生时接收邮件通知:

    • 📌 从新设备成功登录时
    • 📌 发生登录失败

    两种通知默认关闭,用户可根据自身安全需求自行开启。这为安全审计提供了重要的日志参考。

    7. 内容安全策略(CSP) 🔒

    从 v5.x 起,2FAuth 默认启用了内容安全策略(Content Security Policy),帮助防止或降低跨站脚本(XSS)等安全威胁的风险,为 Web 应用层增加了一道额外的防护屏障。


    三、安装与部署

    2FAuth 可以在 Linux 上直接安装,也可以通过 Docker 进行安装,适用于群晖等 NAS 设备。用户可以通过官方文档获取详细的安装步骤和配置指南。

    1. Docker 部署(推荐方式)🐳

    Docker 是部署 2FAuth 最简便的方式,官方提供了完善的 Docker 镜像(2fauth/2fauth),兼容 amd64、386、arm64、arm/v6 和 arm/v7 架构。

    Docker Compose 方式(推荐)

    创建 docker-compose.yml 文件:

    version: "3"
    services:
      2fauth:
        image: 2fauth/2fauth
        container_name: 2fauth
        volumes:
          - ./2fauth:/2fauth
        ports:
          - 8000:8000/tcp
        environment:
          - APP_NAME=2FAuth
          - APP_ENV=local
          - APP_DEBUG=false
          - APP_KEY=SomeRandomStringOf32CharsExactly
          - APP_URL=http://your-domain-or-ip:8000
          - DB_DATABASE="/srv/database/database.sqlite"
          - AUTHENTICATION_GUARD=web-guard

    执行部署命令:

    docker compose up -d

    Docker CLI 方式

    docker run -d -p 8000:8000/tcp \
      -v /your/path/2fauth:/2fauth \
      2fauth/2fauth

    ⚠️ 权限注意:在 Linux 系统上,容器以 1000:1000 用户运行(非 root),需要确保宿主机上挂载目录的所有权和权限与之匹配:

    mkdir -p /your/path/2fauth
    chown 1000:1000 /your/path/2fauth

    关键配置说明 ⚙️

    • 📌 APP_KEY:必须恰好 32 个字符,用于加密敏感数据。可使用 openssl rand -base64 32 生成
    • 📌 APP_URL:必须设置为你访问 2FAuth 的实际 URL,否则可能导致 CSRF 等问题
    • 📌 持久化数据:确保 ./2fauth 目录事先创建,避免被 Docker 以 root 权限自动创建导致权限问题
    • 📌 Docker Secrets(v6.0+)2FAuth v6.0 起支持 Docker Secrets,敏感环境变量(如密码)可以通过 _FILE 后缀约定从挂载的 Secret 文件中读取,进一步增强生产环境的安全性
    • 📌 环境变量完整列表参见官方文档的环境变量页面标有红色星号的为必填项

    更新与备份 🔁

    Docker 镜像在每次代码推送到 master 分支时自动构建。更新流程:

    docker pull 2fauth/2fauth
    docker compose down && docker compose up -d

    ⚠️ 务必在更新前备份 database.sqlite 文件! 这是你所有 2FA 数据的存储位置,损坏或丢失将导致不可逆的数据丢失。

    2. 原生 Linux 安装 🐧

    2FAuth 基于 Laravel(PHP 框架)构建,原生安装需要以下环境:

    • 📌 PHP 8.1+(含 BCMath、Ctype、Fileinfo、JSON、Mbstring、OpenSSL、PDO、Tokenizer、XML 扩展)
    • 📌 Composer(PHP 依赖管理器)
    • 📌 Nginx 或 Apache Web 服务器
    • 📌 SQLite 或 MySQL/MariaDB/PostgreSQL 数据库

    具体安装步骤请参阅官方安装文档

    3. 一键部署平台 ☁️

    除了手动部署,2FAuth 还支持通过以下平台一键安装:

    平台说明
    TrueNAS通过 TrueNAS Apps Market 直接安装
    YunoHostYunoHost 应用商店提供 2FAuth 应用
    CloudronCloudron 平台原生支持
    Easypanel通过 Easypanel 模板一键部署

    4. HTTPS 与反向代理 🔒

    强烈建议通过反向代理(如 Nginx、Traefik、Caddy)为 2FAuth 配置 HTTPS:

    • 📌 二维码扫描功能依赖摄像头,而浏览器要求 HTTPS 才能授予摄像头权限
    • 📌 WebAuthn 认证同样要求安全上下文(HTTPS)
    • 📌 保护传输中的认证数据不被中间人窃取

    四、版本演进与新特性

    了解 2FAuth 的版本演进有助于理解其功能发展脉络和项目活跃度:

    v5.0 — 架构升级与 SSO 支持 🏗️

    • 📌 前端框架从 Vue 2 迁移至 Vue 3,全部组件采用 Composition API 重写,整体架构重新设计(Vue 2 已于 2023 年底终止维护)
    • 📌 引入 SSO 单点登录功能,支持 OpenID Connect 和 GitHub 两种身份提供商

    v5.1 — 多用户管理 👥

    • 📌 完整的用户管理系统:搜索、创建、删除用户,授予/撤销管理员角色
    • 📌 注册控制:邮箱限制、自定义 SSO 注册规则
    • 📌 新增邮件配置测试和缓存清理功能

    v5.2 — 通知系统 📬

    • 📌 认证事件通知:新设备登录、登录失败时的邮件通知
    • 📌 认证日志:记录用户的认证事件,支持安全审计

    v5.5–v5.6 — 前端重构与图标增强 🎨

    • 📌 Web App 与浏览器扩展共享组件,统一代码库以优化未来开发
    • 📌 图标获取增强:新增 selfh.st 和 dashboardicons.com 两个图标提供商,支持在高级表单中切换提供商和变体
    • 📌 新增 SSO-Only 模式下的 PAT 使用控制

    v6.0.0 — 最新版本(2026 年 2 月) 🆕

    • 📌 2FA 注册流程集成:可在服务网站的 2FA 注册过程中直接将账户注册到 2FAuth
    • 📌 管理员自定义用户偏好默认值:可定义偏好的默认设置,并锁定特定偏好禁止用户修改
    • 📌 下一码预计算显示:新增用户偏好选项,预计算并展示下一个 OTP 验证码
    • 📌 新增语言:丹麦语、荷兰语、意大利语、韩语、巴西葡萄牙语
    • 📌 界面刷新:所有图标统一使用 lucide.dev 图标库
    • 📌 Docker Secrets 支持:敏感数据可通过 _FILE 约定从 Secret 文件读取
    • 📌 未认证用户不再显示版本号(安全增强)

    五、适用场景与竞品对比

    适用场景 🎯

    2FAuth 适用于需要在多个设备上管理 2FA 账户的用户,特别是那些希望自托管 2FA 数据并确保数据安全的用户。它简化了 2FA 的使用流程,使用户能够在没有智能手机的情况下也能方便地进行身份验证。具体而言,2FAuth 特别适合以下场景:

    • 📌 隐私至上的用户:不信任 Google、Microsoft 等云端服务托管自己的 2FA 密钥
    • 📌 桌面办公为主的用户:频繁需要输入 2FA 验证码,但不方便每次拿起手机
    • 📌 NAS / 家庭服务器用户:已有自托管基础设施,希望将 2FA 管理也纳入自托管体系
    • 📌 家庭/小团队共享:多个家庭成员或团队成员需要各自管理 2FA,共用一个实例
    • 📌 安全分离策略:将密码管理(Bitwarden/Vaultwarden)和 2FA 管理分开存放,避免"一篮子装所有鸡蛋"的风险
    • 📌 开发者与运维人员:需要通过 API 将 2FA 集成到自动化工作流中

    竞品对比 📊

    为了帮助你更好地理解 2FAuth 的定位,以下是它与常见竞品/相关工具的对比:

    对比维度2FAuthVaultwardenAuthelia
    核心定位专用 OTP 验证码生成与管理密码管理器 + TOTP 存储SSO 认证网关(反向代理)
    2FA 角色生成 TOTP/HOTP 验证码在密码库中存储 TOTP 密钥在应用前端强制实施 2FA
    使用场景替代 Google Authenticator一站式密码 + 2FA 管理保护自托管应用的访问入口
    多用户✅ 支持(v4.0+)✅ 支持(组织功能)通过 YAML/LDAP 管理
    客户端Web + 浏览器扩展 + PWA全平台客户端(手机/桌面/浏览器)无独立客户端(集成在代理中)
    资源占用极低50–100 MB RAM~30 MB RAM
    API✅ RESTful API✅ Bitwarden API❌ 无面向终端用户的 API

    💡 安全分离原则:自托管社区中广泛讨论的一个安全理念是——不应将密码和 2FA 密钥存放在同一个保险箱中。这正是许多用户选择 Vaultwarden(管密码)+ 2FAuth(管 2FA) 组合方案的核心原因。如果攻击者攻破了你的密码管理器,而 2FA 密钥存储在另一个独立系统中,你的账户仍然受到保护。


    六、最佳实践与注意事项

    在实际部署和使用 2FAuth 时,以下最佳实践值得参考:

    备份策略 💾

    • 📌 定期备份 database.sqlite 文件——这是所有 2FA 数据的核心存储
    • 📌 妥善保存 .env 文件(尤其是 APP_KEY)——丢失将导致加密数据不可恢复
    • 📌 利用 2FAuth 的导出功能定期导出 JSON 备份文件,存储在安全的离线位置
    • 📌 考虑使用 3-2-1 备份策略:3 份副本、2 种介质、1 份异地存储

    安全加固 🔐

    • 📌 启用 HTTPS——这不仅是安全建议,更是二维码扫描和 WebAuthn 的前提条件
    • 📌 使用 WebAuthn 替代密码登录——如果条件允许,禁用传统密码登录表单
    • 📌 启用数据库加密——尤其是在共享环境或公网可访问的部署场景中
    • 📌 启用自动锁定——防止离开电脑时会话被他人利用
    • 📌 开启认证通知——及时发现异常登录行为
    • 📌 如果使用 SSO,建议将其配置为唯一认证方式,减少攻击面

    迁移建议 🚚

    • 📌 从 Google Authenticator 迁移时,使用其"导出账户"功能生成二维码,2FAuth 直接扫描导入
    • 📌 从 Aegis/2FAS 迁移时,确保导出时不加密或使用 2FAuth 支持的加密格式
    • 📌 导入后仔细核对每个账户的验证码是否与原应用一致,再删除原应用中的数据

    参考资源

    Brave 回复 11 months, 2 weeks ago 1 成員 · 0 回复
  • 0 回复

歡迎留言回复交流。

Log in to reply.

讨论開始
00 回复 2018 年 6 月
現在