lawless/docs/技术文档/TDD-07-反作弊与安全设计.md
徐勤民 521603a899
一些检测仍在等待运行
Docs Build / build-and-deploy (push) Waiting to run
refactor(client): 删除游戏核心管理器和场景脚本
- 移除 ConfigManager 配置管理器类
- 移除 GameManager 全局单例管理器类
- 移除 NetworkManager 网络连接管理器类
- 移除 CharacterData 和 ItemData 数据模型类
- 移除 BagScene、BattleScene、LobbyScene 等场景脚本
- 移除 EncounterBubble 和 EventFeedPanel UI组件脚本
- 更新代理邀请文档中的服务器连接方式
- 更新同步状态表格中的代理任务分配信息
- 添加 MiMo 任务完成总结和审查修复记录
2026-07-03 21:34:51 +08:00

41 KiB

TDD-07 反作弊与安全设计

文档类型技术设计文档Technical Design Document 版本1.0 日期2026-07-02 关联文档TDD-04《数据库表结构设计》、TDD-05《API接口设计》、GDD-02《底层核心机制》、GDD-03《战斗系统设计》、GDD-06《经济系统设计》、GDD-13《佣兵大厅与悬赏系统》、GDD-14《稀有宝物流转与拍卖系统》


1. 文档信息

项目 说明
目标 为《洪荒大陆》挂机手游定义反作弊与安全设计规范,覆盖服务端权威模型、异常行为检测、经济安全、举报惩罚、接口安全与数据安全六大领域。
读者 服务端开发、客户端开发、安全工程师、运维、QA
技术栈 Nakama 3.x + Go 插件 + PostgreSQL 16 + Valkey + Nacos 2.x + Cocos Creator 3.x
核心约束 无任务系统、无赛季重置、概率/机遇驱动、文字战报、ATB 行动条、功法加持、能量体系(非体力)

2. 服务端权威模型

2.1 设计原则

本项目采用 服务端权威Server-Authoritative 架构:客户端仅负责展示与发起请求,所有涉及游戏状态变更的逻辑在服务端计算并持久化。客户端提交的数据仅作为"意图声明",不作为事实来源。

客户端                    服务端                    数据库/缓存
  │                        │                        │
  │── 请求(意图) ────────►│                        │
  │                        │── 读取状态 ──────────►│
  │                        │◄─ 返回当前状态 ───────│
  │                        │                        │
  │                        │── 校验 + 计算 ────────►│
  │                        │── 写入结果 ──────────►│
  │                        │                        │
  │◄─ 返回结算结果 ───────│                        │
  │                        │                        │
  │── 仅做 UI 展示 ────────│                        │

2.2 服务端必须校验的操作清单

以下操作必须由服务端完整计算,客户端不可参与任何判定逻辑:

操作类别 具体操作 校验要点 关联接口
战斗结算 PVE 战斗(游历/副本/遗迹、PVP 战斗、悬赏追杀 服务端加载双方属性快照 → ATB 引擎计算 → 生成战报 → 写入 battles + battle_logs POST /api/v1/combatsPOST /api/v1/combats/pvp
突破渡劫 小境界突破、大境界渡劫、天启晋级 服务端校验修为/材料/护法条件 → 概率判定 → 更新 characters.realm_tier / minor_realm / world_tier POST /api/v1/characters/{id}/realm/breakthroughPOST .../tribulationPOST .../world-break
经济交易 货币增减、交易行挂单/购买、拍卖出价、悬赏赏金、天机阁情报 服务端校验余额 → 原子扣款/加款 → 写入 economy_audit_logs → 同步 Valkey 钱包缓存 POST /api/v1/market/orders/{id}/buyPOST /api/v1/auctions/{id}/bids
地图移动 跨区域移动、进入副本/遗迹、天启传送 服务端校验 world_tier / realm_tier 解锁状态 → 更新 characters.world_tier POST /api/v1/instances/{id}/enter
技能学习 功法升层、技能学习、玉简拓印、加持切换 服务端校验种族/境界/属性/SAN/材料条件 → 概率判定 → 写入 character_skills / character_manuals POST /api/v1/characters/{id}/manuals/{mid}/upgradePOST .../skills/learn
弟子派遣 弟子代派任务、领地产出 服务端计算成功率/死亡率 → 异步结算 → 写入 disciple_missions POST /api/v1/disciples/{id}/dispatch
组织操作 创建/加入/退出组织、领地竞标、帮派资金 服务端校验权限/条件 → 原子更新 guilds / guild_members / guild_territories POST /api/v1/guildsPOST .../territories/bids
社交关系 道侣/结义/师徒请求、关系解除 服务端校验互斥关系/冷却时间 → 写入 social_relations / lovers / sworn_brothers POST /api/v1/relations/{type}/requests

2.3 客户端仅做展示与请求的原则

原则 说明
不信任客户端数值 客户端发送的属性值、伤害值、概率值全部忽略,服务端自行从数据库/缓存加载
不信任客户端时间 所有时间判定以服务端 timestamptz 为准,客户端时间仅用于 UI 倒计时展示
不信任客户端随机 概率判定(突破/渡劫/技能顿悟/掉落)全部使用服务端 CSPRNGcrypto/rand
不信任客户端状态 客户端报告的"战斗胜利""突破成功"等状态无效,必须由服务端判定并返回
客户端仅提交意图 客户端发送"我要对目标 X 使用技能 Y",服务端校验技能存在性/能量/CD/目标合法性后执行

2.4 客户端校验(可选,提升体验)

客户端可进行以下前置校验以减少无效请求,但服务端仍需独立校验:

  • 当前能量是否足够(避免发送必定失败的请求)
  • 目标是否在交互范围内
  • 材料是否在背包中
  • 冷却是否结束

关键:客户端校验失败仅阻止本地 UI 操作,不作为任何服务端逻辑的依据。


3. 异常行为检测

3.1 加速检测

3.1.1 时间回拨检测

检测项 实现方式 阈值 响应
客户端时钟偏移 登录时客户端上报本地时间戳,服务端计算偏差 abs(client_ts - server_ts) > 300 秒 记录日志,连续 3 次超阈值标记可疑
请求时间序列单调性 同一 character_id 的请求 X-Trace-Id 中嵌入服务端接收时间戳,检查是否递增 出现回退 标记异常,回退的请求拒绝处理
游戏内时间跳跃 对比两次请求的 game_timestamp 差值与现实间隔 游戏时间增量 > 现实间隔 × 3.5 触发告警,暂停游历/挂机产出

3.1.2 速度异常检测

检测项 实现方式 阈值 响应
地图移动速度 计算两次位置变更的 distance / time_elapsed > 角色最大移动速度 × 1.2 重置位置,标记异常
请求频率 基于 Valkey 滑动窗口计数器 rate:{character_id}:{path} 超过 TDD-05 §2.5 定义的限流值 返回 429,累计触发次数
战斗间隔 检查两次战斗请求的时间间隔 < 战斗最短耗时ATB 最少回合数) 拒绝请求,记录日志
挂机产出速率 对比实际产出与理论产出 expected = base_rate × duration × modifiers 实际 > 理论 × 1.3 截断超出部分,标记异常

3.1.3 请求频率异常检测

// Go 伪代码:滑动窗口限流器(基于 Valkey
func CheckRateLimit(characterID, path string, limit int, window time.Duration) bool {
    key := fmt.Sprintf("rate:%s:%s", characterID, path)
    now := time.Now().UnixMilli()
    windowStart := now - window.Milliseconds()

    pipe := valkey.Pipeline()
    pipe.ZRemRangeByScore(ctx, key, "0", fmt.Sprintf("%d", windowStart))
    pipe.ZAdd(ctx, key, &valkey.Z{Score: float64(now), Member: uuid.New().String()})
    pipe.ZCard(ctx, key)
    pipe.Expire(ctx, key, window)
    results := pipe.Exec(ctx)

    count := results[2].(*valkey.IntCmd).Val()
    return count <= int64(limit)
}

3.2 数据篡改检测

3.2.1 属性/货币/背包哈希校验

对客户端展示的关键数据附加校验哈希,服务端在关键节点验证一致性:

数据域 校验方式 触发时机
角色属性快照 HMAC-SHA256(character_id + base_stats_json + battle_stats_json + secret_salt) 登录同步、战斗前加载
货币余额 HMAC-SHA256(character_id + currency_code + amount + secret_salt) 每次货币变更后生成,客户端下次请求携带
背包物品 HMAC-SHA256(character_id + item_count_hash + secret_salt) 物品变更后生成

注意:哈希校验仅用于客户端篡改检测,服务端始终以数据库数据为准。校验失败不直接封号,而是标记可疑并触发人工审核。

3.2.2 服务端内部一致性校验

校验项 实现方式 频率
货币守恒 currency_balances.amount = total_earned - total_spent(从 economy_audit_logs 聚合) 每日凌晨批处理
背包守恒 inventories 中的物品数量变化应与 economy_audit_logs 中的物品流转记录一致 每日凌晨批处理
境界一致性 characters.realm_tier 应与 character_realms.is_current=true 的记录一致 实时校验(突破/渡劫时)
装备合法性 equipments 引用的 inventory_id 应属于同一 character_id,且 bind_type 与穿戴状态一致 装备变更时

3.3 机器人挂机检测

3.3.1 行为模式分析

特征 正常玩家 疑似机器人 检测方式
操作间隔分布 随机波动,有高峰低谷 高度规律,近似固定间隔 统计操作间隔的标准差(σ < 阈值则可疑)
活跃时长 有休息,单次 1~3 小时 24 小时不间断 检查连续在线时长
决策模式 有犹豫、有选择 固定路线、固定操作序列 序列熵分析(操作序列熵低于阈值则可疑)
响应速度 对事件有合理反应时间 对随机事件瞬间响应 事件推送 → 响应延迟统计
设备指纹 正常设备特征 模拟器/多开特征 设备指纹库比对(见 §3.4.4

3.3.2 验证码策略

触发条件 验证码类型 说明
连续在线 > 8 小时 图形验证码 / 滑块 强制验证,失败则暂停游历产出
操作间隔标准差低于阈值 行为验证码(点选/拖拽) 3 次失败标记为可疑
被举报 2 次以上24 小时内) 图形验证码 每次登录强制验证,持续 3 天
异常 IP 段批量注册 注册时强制验证码 结合设备指纹去重

3.3.3 机器学习辅助检测(长期规划)

阶段 内容
数据采集 采集正常玩家行为序列:操作间隔、路径选择、战斗决策、市场行为
特征工程 提取操作熵、时间分布特征、社交图谱密度、经济行为模式
模型训练 使用 Isolation Forest 或 LSTM-AutoEncoder 训练异常检测模型
线上部署 对可疑行为打分,超过阈值触发人工审核,不自动封号

3.4 协议攻击检测

3.4.1 重放攻击防护

机制 实现
Nonce 校验 每个请求携带 X-Nonce: <uuid>,服务端在 Valkey 中存储已用 NonceTTL 5 分钟),重复 Nonce 拒绝处理
Timestamp 校验 请求携带 X-Timestamp: <unix_ms>,服务端校验 abs(now - timestamp) < 60s,超出窗口拒绝
Sequence Number 高敏感操作(交易/拍卖/悬赏)使用递增 X-Sequence,服务端校验单调递增,跳跃过大拒绝
Idempotency-Key 所有扣费/扣材料操作要求 Idempotency-Key,服务端以 character_id + key 去重 24 小时TDD-05 §5
// 请求头扩展protobuf 定义)
message SecureRequestHeader {
  string session_token = 1;
  string nonce = 2;           // UUID v4
  int64 timestamp = 3;        // Unix 毫秒
  int64 sequence = 4;         // 单调递增序号
  string idempotency_key = 5; // 幂等键(写操作必填)
  bytes signature = 6;        // HMAC-SHA256 签名(高敏感操作)
}

3.4.2 中间人攻击防护

措施 说明
全链路 TLS 1.3 HTTPS / WSS / gRPC 全部启用 TLS 1.3,禁止降级到 TLS 1.2 以下
证书固定Certificate Pinning 客户端内置服务端证书指纹,防止中间人伪造证书
请求签名 高敏感操作(交易/出价/悬赏)要求客户端对请求体做 HMAC-SHA256 签名,密钥由 Nakama session 派生TDD-05 §5
响应签名 服务端对关键响应(战斗结算/突破结果/交易确认)附加签名,客户端验证完整性

3.4.3 伪造 Token 防护

机制 说明
Nakama Session 签名 Token 由 Nakama 使用 HMAC-SHA256 签名,服务端校验签名完整性
Token 绑定 Token 与 device_id + ip_geo 绑定,异地登录触发二次验证
Token 吊销 异常行为检测到后,通过 Nakama Admin API 强制吊销 Token
Token 刷新 长期 Token60 天)可被服务端主动过期,强制重新登录

3.4.4 设备指纹与多开检测

特征 采集方式 用途
device_id 客户端生成并上报 账号绑定,防止刷号
设备型号 / OS 版本 客户端上报 模拟器检测
屏幕分辨率 / DPI 客户端上报 多开检测(同一分辨率批量注册)
IP 地址 / 地理位置 服务端获取 异地登录检测、IP 黑名单
安装应用列表哈希 客户端采集(需用户授权) 外挂工具检测

隐私合规:设备指纹采集需符合《个人信息保护法》,在隐私政策中明确告知,并提供关闭选项(关闭后功能受限)。


4. 经济安全

4.1 RMTReal Money Trading检测

4.1.1 异常交易模式检测

检测规则 触发条件 响应
单向大额转账 24 小时内 A → B 的交易行购买总额 > 5000 灵石,且 B → A 无反向交易 标记可疑,冻结双方交易功能 24 小时,触发人工审核
新号转金 创建 < 7 天的角色在交易行购买总额 > 2000 灵石 标记可疑,限制交易行购买额度
关联账号网络 多个账号之间形成闭环交易链A→B→C→A 标记整组账号,触发人工审核
固定价格交易 同一卖家对同一买家以相同价格反复交易 标记可疑,检查是否为 RMT 通道
离线交易 卖家长时间不在线但持续有高价成交 标记可疑,检查是否为傀儡账号

4.1.2 RMT 检测评分模型

RMT_RISK_SCORE = (
    单向交易金额占比 × 0.3 +
    交易频率异常度 × 0.2 +
    账号年龄因子 × 0.15 +
    社交图谱稀疏度 × 0.15 +
    价格偏离度 × 0.2
) × 100

阈值:
  score < 40  → 正常
  40 ≤ score < 70 → 标记观察
  70 ≤ score < 90 → 标记可疑,限制交易
  score ≥ 90 → 标记高危,冻结账号,触发人工审核

4.1.3 RMT 数据库表

-- RMT 检测记录表
CREATE TABLE rmt_detection_records (
    id              uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    character_id    uuid NOT NULL REFERENCES characters(id),
    risk_score      numeric(5,2) NOT NULL,
    risk_level      varchar(16) NOT NULL,  -- normal / watch / suspicious / critical
    trigger_rules   jsonb NOT NULL,        -- 触发的规则列表
    related_ids     uuid[],                -- 关联的交易/订单 ID
    status          varchar(16) NOT NULL DEFAULT 'pending',  -- pending / reviewing / confirmed / cleared
    reviewer_id     uuid,                  -- 审核人
    review_note     text,
    created_at      timestamptz NOT NULL DEFAULT now(),
    reviewed_at     timestamptz
);

CREATE INDEX idx_rmt_character ON rmt_detection_records(character_id, created_at);
CREATE INDEX idx_rmt_status ON rmt_detection_records(status, risk_level);

4.2 刷金检测

4.2.1 产出速率异常检测

检测维度 基线计算 异常阈值 响应
游历产出 base_rate × duration × race_modifier × realm_modifier 实际 > 基线 × 1.5 截断超出部分,标记异常
副本产出 instance_reward × difficulty_coefficient × party_bonus 实际 > 预期 × 1.3 截断,标记异常
挂机产出 gathering_rate × duration × talent_modifier 实际 > 理论 × 1.5 截断,标记异常
悬赏收益 bounty_reward × completion_rate 单日悬赏收益 > 基线 × 3 标记异常,限制接取

4.2.2 多号联动检测

检测规则 触发条件 响应
同 IP 批量注册 同一 IP 24 小时内注册 > 3 个账号 注册时强制验证码,标记关联
同设备多号 同一 device_id 绑定 > 2 个账号 标记关联,共享风控评分
多号向单号集中转金 > 3 个账号在 24 小时内向同一账号交易 标记目标账号,触发人工审核
多号协同刷副本 同一 IP 段的多个账号同时进入同一副本 标记异常,检查是否为工作室

4.2.3 产出监控看板指标

指标 计算方式 告警阈值
全服货币通胀率 (total_supply_today - total_supply_yesterday) / total_supply_yesterday > 5%/天
人均产出偏差 avg(player产出) / theoretical_avg > 1.5
Top 1% 产出占比 top1%_产出 / total_产出 > 30%
新号产出集中度 accounts_7d产出 / total_产出 > 20%

4.3 洗钱检测

4.3.1 交易行价格操纵检测

检测规则 触发条件 响应
异常低价挂单 挂单价格 < 近 7 天同物品均价 × 0.3 标记可疑,限制成交,触发人工审核
异常高价购买 购买价格 > 近 7 天同物品均价 × 3.0 标记可疑,记录买家信息
自买自卖 卖家与买家为同一账号(或关联账号) 拒绝成交,标记异常
批量低买高卖 短时间内大量低价收购后高价出售 标记可疑,检查是否为价格操纵
价格异常波动 物品价格在 1 小时内波动 > 50% 触发告警,人工审核

4.3.2 拍卖自拍自买检测

检测规则 触发条件 响应
卖家 = 出价者 auctions.seller_id = auction_bids.bidder_id 数据库约束拒绝
关联账号出价 卖家与出价者为关联账号(同设备/IP/交易历史) 标记可疑,取消出价
保证金循环 拍卖失败后保证金退回 → 立即用于下一次出价 检查资金循环频率
价格虚高 拍卖成交价 > 近 7 天同物品均价 × 5.0 标记可疑,触发人工审核

4.3.3 经济异常自动响应

// 经济异常响应状态机
type EcoAnomalyResponse struct {
    Level    string // watch / restrict / freeze / ban
    Actions  []string
}

var anomalyResponses = map[string]EcoAnomalyResponse{
    "watch": {
        Level:   "watch",
        Actions: []string{"log_detail", "increase_monitoring"},
    },
    "restrict": {
        Level:   "restrict",
        Actions: []string{"limit_trade_amount", "limit_trade_frequency", "require_captcha"},
    },
    "freeze": {
        Level:   "freeze",
        Actions: []string{"freeze_trade", "freeze_withdraw", "notify_reviewer"},
    },
    "ban": {
        Level:   "ban",
        Actions: []string{"freeze_account", "notify_admin", "create_ticket"},
    },
}

5. 举报与惩罚系统

5.1 举报类型

举报类型 说明 证据要求 优先级
外挂/加速器 使用第三方工具加速/修改游戏 截图/视频 + 异常行为记录
辱骂/骚扰 聊天频道发布不当言论 聊天记录截图
诈骗 虚假交易/冒充GM/诱导转账 交易记录 + 聊天记录
RMT 现金交易游戏资源 交易异常记录
利用BUG 利用游戏漏洞获取不当利益 详细复现步骤 紧急
其他 不当角色名/组织名等 截图

5.2 举报接口

项目 内容
功能 玩家提交举报
REST POST /api/v1/reports
请求参数 target_character_iduuidreport_typestringdescriptionstringevidence_urls[]string,可选battle_iduuid,可选
限流 5 次/天/角色
错误码 9101举报类型非法、9102目标不存在、9103今日举报次数已满、9104不可举报自己

5.3 举报数据表

CREATE TABLE player_reports (
    id                  uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    reporter_id         uuid NOT NULL REFERENCES characters(id),
    target_id           uuid NOT NULL REFERENCES characters(id),
    report_type         varchar(32) NOT NULL,  -- cheat / insult / fraud / rmt / bug_exploit / other
    description         text,
    evidence_urls       text[],
    related_battle_id   uuid,
    related_trade_id    uuid,
    status              varchar(16) NOT NULL DEFAULT 'pending',  -- pending / reviewing / resolved / dismissed
    priority            smallint NOT NULL DEFAULT 2,  -- 1=紧急 2=高 3=中 4=低
    reviewer_id         uuid,
    review_result       varchar(16),  -- confirmed / insufficient_evidence / false_report
    review_note         text,
    created_at          timestamptz NOT NULL DEFAULT now(),
    reviewed_at         timestamptz
);

CREATE INDEX idx_reports_status ON player_reports(status, priority, created_at);
CREATE INDEX idx_reports_target ON player_reports(target_id, created_at);

5.4 人工审核流程

玩家举报
    │
    ▼
自动分类 + 优先级排序
    │
    ├── 紧急利用BUG/RMT高危──► 自动冻结可疑账号 ──► 24小时内人工审核
    │
    ├── 高(外挂/诈骗)──► 48小时内人工审核
    │
    ├── 中(辱骂)──► 72小时内人工审核
    │
    └── 低(其他)──► 7天内人工审核
    │
    ▼
人工审核
    │
    ├── 确认违规 ──► 执行惩罚 ──► 通知举报者
    │
    ├── 证据不足 ──► 标记观察 ──► 通知举报者
    │
    └── 误报 ──► 驳回 ──► 恶意举报者扣信用分

5.5 惩罚梯度

惩罚等级 适用场景 执行方式 持续时间
警告 首次轻微违规(辱骂/不当名) 站内信通知 永久记录
禁言 重复辱骂/刷屏 冻结聊天功能 1~7 天
交易限制 疑似 RMT/刷金 限制交易行/拍卖操作 3~30 天
功能封禁 使用外挂/严重 BUG 利用 封禁特定功能PVP/副本/交易) 7~90 天
临时封号 严重违规/屡教不改 冻结账号,禁止登录 7~180 天
永久封禁 极端违规(大规模 RMT/外挂开发/恶意攻击) 永久冻结账号 + 设备黑名单 永久

惩罚数据库表

CREATE TABLE punishment_records (
    id              uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    character_id    uuid NOT NULL REFERENCES characters(id),
    player_id       uuid NOT NULL REFERENCES players(id),
    punishment_type varchar(16) NOT NULL,  -- warning / mute / trade_ban / feature_ban / temp_ban / perm_ban
    reason          text NOT NULL,
    report_id       uuid REFERENCES player_reports(id),
    related_rule    varchar(64),           -- 违反的规则编号
    start_at        timestamptz NOT NULL DEFAULT now(),
    end_at          timestamptz,           -- 永久封禁为 NULL
    is_active       boolean NOT NULL DEFAULT true,
    issued_by       varchar(32) NOT NULL,  -- system / admin_id
    appeal_status   varchar(16) DEFAULT 'none',  -- none / pending / approved / rejected
    created_at      timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_punishment_character ON punishment_records(character_id, is_active);
CREATE INDEX idx_punishment_player ON punishment_records(player_id, is_active);

5.6 申诉机制

项目 说明
申诉入口 游戏内「客服中心」→「申诉」
申诉条件 被处罚后 7 天内可提交,每个处罚仅可申诉 1 次
申诉内容 申诉理由(文字)+ 补充证据(截图/视频链接)
审核时限 3 个工作日内给出结果
申诉结果 维持原判 / 减轻处罚 / 撤销处罚
恶意申诉 连续 3 次申诉被驳回,后续申诉优先级降低

申诉接口

项目 内容
REST POST /api/v1/appeals
请求参数 punishment_iduuidreasonstringevidence_urls[]string
限流 1 次/天
错误码 9201处罚不存在、9202已申诉过、9203申诉窗口已过

6. 接口安全

6.1 限流策略

限流在网关层OpenResty/Traefik基于 Token Bucket 实现,详见 TDD-05 §2.5。本节补充安全相关的限流细节。

6.1.1 限流维度

维度 说明 实现
IP 维度 防止单 IP 批量请求 Valkey SET rate:ip:{ip} {count} EX 60 NX
账号维度 防止单账号刷接口 Valkey ZSET rate:char:{id}:{path} 滑动窗口
接口维度 热点接口单独限流 按 path + method 组合配置
设备维度 防止多开刷量 device_id 维度限流
全局维度 防止 DDoS 云防火墙 + WAF 全局限流

6.1.2 安全增强限流

场景 策略
登录失败 5 次失败后锁定 15 分钟,10 次失败后锁定 1 小时
注册 同 IP 每天最多 3 次注册
交易操作 新账号(< 7 天)交易行操作限流加倍
异常 IP 被标记的 IP 段所有请求限流降至 1/10

6.2 防重放攻击

详见 §3.4.1。核心机制:

  1. Nonce + Timestamp:每个请求携带唯一 Nonce 和时间戳,服务端校验唯一性与时效性
  2. Sequence Number:高敏感操作使用递增序号
  3. Idempotency-Key:所有写操作幂等控制
// 防重放校验中间件
func AntiReplayMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        nonce := r.Header.Get("X-Nonce")
        timestamp := r.Header.Get("X-Timestamp")

        // 1. 校验 Nonce 唯一性
        if !valkey.SetNX(ctx, "nonce:"+nonce, "1", 5*time.Minute).Val() {
            writeError(w, 9004, "duplicate request")
            return
        }

        // 2. 校验时间窗口
        ts, _ := strconv.ParseInt(timestamp, 10, 64)
        if abs(time.Now().UnixMilli()-ts) > 60000 {
            writeError(w, 9005, "request expired")
            return
        }

        next.ServeHTTP(w, r)
    })
}

6.3 DDoS 防护

层级 措施 说明
网络层 云防火墙 腾讯云 DDoS 防护,SYN Flood / UDP Flood / ACK Flood 清洗
传输层 CDN 静态资源通过 CDN 分发,隐藏源站 IP
应用层 WAF OpenResty + lua-resty-waf,SQL 注入 / XSS / 路径遍历防护
业务层 限流 + 验证码 超限请求返回 429,可疑流量触发验证码
数据库层 连接池限制 PostgreSQL max_connections 限制,防止连接耗尽

6.3.1 WAF 规则

# OpenResty WAF 配置示例
lua_shared_dict waf_rules 10m;

init_by_lua_block {
    local waf = require "resty.waf"
    waf.init()
}

access_by_lua_block {
    local waf = require "resty.waf"
    local ctx = waf.new()
    ctx:set_option("mode", "ACTIVE")
    ctx:set_option("request_body_limit", 1048576)  -- 1MB
    ctx:exec()
}

6.4 SQL 注入 / XSS 防护

防护项 措施
SQL 注入 所有数据库操作使用参数化查询(pgx / gorm prepared statement,禁止字符串拼接 SQL
XSS 输出编码HTML Entity / JSON Escape,CSP 头限制脚本来源
CSRF API 使用 Token 认证(非 Cookie,天然免疫 CSRF
路径遍历 文件操作限制在白名单目录,禁止 ../ 路径
命令注入 禁止 os.Exec 拼接用户输入,使用参数化调用
SSRF 内部服务调用使用白名单 URL,禁止用户指定目标地址
// 参数化查询示例pgx
func GetCharacter(db *pgxpool.Pool, characterID uuid.UUID) (*Character, error) {
    var c Character
    err := db.QueryRow(ctx,
        `SELECT id, name, race_id, world_tier, realm_tier, minor_realm
         FROM characters WHERE id = $1`, characterID,
    ).Scan(&c.ID, &c.Name, &c.RaceID, &c.WorldTier, &c.RealmTier, &c.MinorRealm)
    return &c, err
}

6.5 CSPContent Security Policy

add_header Content-Security-Policy "
    default-src 'self';
    script-src 'self' 'unsafe-inline' 'unsafe-eval';
    style-src 'self' 'unsafe-inline';
    img-src 'self' data: https:;
    connect-src 'self' wss://*.honghuang.example.com https://api.honghuang.example.com;
    font-src 'self';
    object-src 'none';
    base-uri 'self';
    form-action 'self';
" always;

7. 数据安全

7.1 敏感数据加密

数据类型 加密方式 存储位置 说明
密码 bcryptcost=12 PostgreSQL players 仅账号系统使用,Nakama 内置处理
支付信息 AES-256-GCM 独立支付数据库 充值记录加密存储,解密密钥独立管理
Session Token HMAC-SHA256 签名 Nakama 内部 Token 本身不存储,仅存储签名
设备指纹 SHA-256 哈希 PostgreSQL players.device_id_hash 不存储原始设备 ID
API 密钥 环境变量 / 密钥管理服务 服务端配置 不硬编码,不写入日志
数据库连接 TLS + 密钥文件 服务端配置 PostgreSQL 连接使用 SSL

7.2 日志脱敏

日志类型 脱敏规则 示例
玩家 IP 保留前两段,后两段替换为 *** 192.168.***.***
设备 ID 仅保留哈希值 sha256:a1b2c3...
角色名 正常记录(非敏感) 铁爪传
货币金额 正常记录(审计需要) 1280
请求体 移除 Token / 密码字段 {"device_id": "***", "platform": "ios"}
错误堆栈 移除文件路径中的用户名 /app/internal/handler/...
// 日志脱敏中间件
func SanitizeLogMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 脱敏请求头
        sanitizedHeaders := sanitizeHeaders(r.Header)

        log.Info("incoming request",
            zap.String("method", r.Method),
            zap.String("path", r.URL.Path),
            zap.String("ip", maskIP(r.RemoteAddr)),
            zap.Any("headers", sanitizedHeaders),
        )

        next.ServeHTTP(w, r)
    })
}

func maskIP(ip string) string {
    // "192.168.1.100:8080" -> "192.168.***.***:***"
    host, port, _ := net.SplitHostPort(ip)
    parts := strings.Split(host, ".")
    if len(parts) == 4 {
        return parts[0] + "." + parts[1] + ".***.***:***"
    }
    return "***"
}

7.3 传输加密

场景 加密方式 说明
客户端 ↔ 网关 TLS 1.3 HTTPS / WSS
网关 ↔ 服务端 mTLS 内部服务间双向 TLS
服务端 ↔ 数据库 SSL PostgreSQL sslmode=verify-full
服务端 ↔ Valkey TLS Valkey 6.0+ 支持
服务端 ↔ Nacos HTTPS Nacos 2.x 配置传输

7.4 数据备份与恢复

备份类型 频率 保留策略 存储位置
PostgreSQL 全量备份 每日凌晨 03:00 保留 30 天 对象存储(腾讯云 COS
PostgreSQL WAL 增量 实时 保留 7 天 对象存储
Valkey RDB 快照 每 6 小时 保留 3 天 本地 + 对象存储
配置备份 每次变更 永久 Git 仓库

7.5 GDPR / 个人信息保护合规

7.5.1 数据分类

数据类别 包含字段 处理依据 保留期限
账号信息 player_id, device_id_hash, platform 合同履行 账号存续期间 + 3 年
游戏角色 character_id, name, race_id, 等级/属性 合同履行 账号存续期间
行为数据 登录日志, 操作日志, 战斗记录 合法利益(安全) 12 个月
交易数据 充值记录, 交易行记录 法律义务(财务) 5 年
设备信息 设备型号, OS 版本, IP 合法利益(安全) 6 个月
聊天记录 聊天内容 合法利益(举报审核) 3 个月

7.5.2 用户权利实现

权利 实现方式 响应时限
知情权 隐私政策中明确告知数据收集范围与用途 首次安装时展示
访问权 提供数据导出接口 GET /api/v1/privacy/export 30 天内
更正权 角色名修改、绑定手机修改 即时
删除权 账号注销接口 DELETE /api/v1/privacy/account 30 天内完成数据删除(法律保留除外)
撤回同意 关闭设备指纹采集(功能受限) 即时
可携带权 数据导出为 JSON/CSV 格式 30 天内

7.5.3 账号注销流程

玩家申请注销
    │
    ▼
校验条件
    │
    ├── 有未完成的交易/拍卖 ──► 拒绝,提示先处理
    │
    ├── 有未结束的组织关系 ──► 拒绝,提示先退出
    │
    └── 条件满足 ──► 进入 30 天冷静期
    │
    ▼
30 天冷静期(可随时取消)
    │
    ▼
执行删除
    │
    ├── 删除characters, inventories, currency_balances, 等游戏数据
    │
    ├── 匿名化players 表保留 player_id 用于审计,其他字段替换为匿名值
    │
    └── 保留economy_audit_logs, punishment_records法律义务

8. 安全审计与监控

8.1 审计日志

日志类型 记录内容 保留期限
登录日志 player_id, ip, device_id_hash, login_time, login_result 12 个月
操作日志 character_id, action, params_hash, result, timestamp 12 个月
经济日志 economy_audit_logsTDD-04 §5.4 12 个月
安全日志 异常行为检测结果、封禁记录、举报处理记录 24 个月
管理日志 GM 操作、配置变更、手动封禁 永久

8.2 监控告警

监控项 告警阈值 通知方式
登录失败率 > 10%5 分钟窗口) 企业微信 + 邮件
异常行为检测触发数 > 50 次/小时 企业微信
经济异常(通胀率) > 5%/天 企业微信 + 邮件
API 错误率 > 5%1 分钟窗口) 企业微信 + 电话
数据库连接数 > 80% max_connections 企业微信
内存使用率 > 85% 企业微信
磁盘使用率 > 90% 企业微信 + 电话

8.3 安全事件响应流程

安全事件发生
    │
    ▼
自动检测 + 告警
    │
    ├── P0严重数据泄露/服务中断)──► 15分钟内响应 ──► 1小时内止损 ──► 24小时内复盘
    │
    ├── P1大规模外挂/经济崩溃)──► 30分钟内响应 ──► 4小时内止损 ──► 3天内复盘
    │
    ├── P2个别外挂/RMT──► 2小时内响应 ──► 24小时内处理
    │
    └── P3轻微违规──► 24小时内响应 ──► 7天内处理

9. 已确认决策记录表

# 决策 确认时间
S01 所有战斗结算PVE/PVP/悬赏/追杀)完全服务端权威,客户端仅提交意图 2026-07-02
S02 突破/渡劫/天启的概率判定使用服务端 CSPRNGcrypto/rand),不使用客户端随机数 2026-07-02
S03 经济交易(交易行/拍卖/悬赏/天机阁)全部服务端原子操作,写入 economy_audit_logs 2026-07-02
S04 地图移动/副本进入的服务端校验包含 world_tier / realm_tier / 解锁状态 / 钥匙/次数 2026-07-02
S05 技能学习/功法升层的服务端校验包含种族/境界/属性/SAN/材料/来源标签 2026-07-02
S06 防重放采用 Nonce + Timestamp + Sequence 三重机制,高敏感操作额外使用 Idempotency-Key 2026-07-02
S07 全链路 TLS 1.3,客户端证书固定Certificate Pinning 2026-07-02
S08 RMT 检测采用评分模型,score ≥ 90 自动冻结账号并触发人工审核 2026-07-02
S09 刷金检测基于产出速率基线对比 + 多号联动分析 2026-07-02
S10 洗钱检测覆盖交易行价格操纵 + 拍卖自拍自买 + 价格异常波动 2026-07-02
S11 举报系统支持 6 种类型,紧急举报自动冻结可疑账号,24 小时内人工审核 2026-07-02
S12 惩罚梯度 6 级:警告/禁言/交易限制/功能封禁/临时封号/永久封禁 2026-07-02
S13 申诉机制:处罚后 7 天内可申诉,每个处罚仅 1 次,3 个工作日出结果 2026-07-02
S14 限流按 IP/账号/接口/设备/全局五维度,网关层 Token Bucket 实现 2026-07-02
S15 日志脱敏IP 保留前两段、设备 ID 仅存哈希、请求体移除 Token/密码 2026-07-02
S16 账号注销 30 天冷静期,删除游戏数据,匿名化账号信息,保留法律义务数据 2026-07-02
S17 敏感数据加密:密码 bcrypt、支付信息 AES-256-GCM、设备指纹 SHA-256 2026-07-02
S18 安全事件分级响应P015分钟/P130分钟/P22小时/P324小时 2026-07-02

10. 验收标准

# 验收条目 测试方法 预期结果
1 客户端伪造战斗胜利结果,服务端不接受 客户端篡改战斗结果字段发送请求 服务端独立计算,返回真实结果
2 客户端伪造突破概率,服务端不接受 客户端发送 success: true 字段 服务端独立判定,返回真实结果
3 客户端伪造货币余额,服务端不接受 客户端发送篡改后的余额哈希 服务端以数据库为准,哈希校验失败标记可疑
4 重放攻击被拒绝 重复发送同一 Nonce 的请求 第二次返回 9004
5 时间窗口外的请求被拒绝 发送 timestamp 偏差 > 60s 的请求 返回 9005
6 高频请求触发限流 短时间发送超过限流阈值的请求 返回 429,响应头包含限流信息
7 异常交易触发 RMT 检测 模拟单向大额转账行为 生成 rmt_detection_records,risk_level = suspicious
8 举报系统正常工作 提交举报并检查状态流转 举报创建成功,状态为 pending
9 惩罚系统正常执行 执行禁言惩罚 角色聊天功能被禁用,到期自动恢复
10 申诉流程正常 对处罚提交申诉 申诉创建成功,状态为 pending
11 SQL 注入防护 在请求参数中注入 SQL 语句 请求被拒绝或参数被安全处理
12 XSS 防护 在角色名/聊天内容中注入脚本 输出被编码,脚本不执行
13 TLS 证书固定生效 使用伪造证书连接 连接被拒绝
14 日志脱敏正确 检查日志中的 IP 和设备 ID IP 后两段为 ***,设备 ID 为哈希值
15 账号注销流程正确 申请注销并等待冷静期 30 天后游戏数据被删除,账号信息被匿名化
16 经济守恒校验通过 运行每日批处理校验 currency_balances.amount = total_earned - total_spent 成立
17 机器人检测生效 模拟固定间隔操作模式 操作间隔标准差低于阈值时触发验证码
18 设备指纹采集合规 检查隐私政策和采集逻辑 隐私政策明确告知,关闭选项可用

11. 与关联文档的映射

关联文档 本安全设计承接点
TDD-04 economy_audit_logs 用于经济守恒校验;rmt_detection_records / player_reports / punishment_records 新增表
TDD-05 限流策略§2.5、认证方式§2.2、幂等控制§5在本文档扩展安全细节
GDD-02 战斗结算服务端权威(1;概率/机遇驱动(37;死亡惩罚25;充值体系22
GDD-03 战斗 ATB 引擎完全服务端计算;文字战报由服务端生成
GDD-06 经济 Faucet/Sink 框架;货币分层;交易行/拍卖/天机阁交易安全
GDD-13 佣兵委托/悬赏系统防刷检测
GDD-14 拍卖双轨制安全;追杀令防滥用;黑吃黑检测
GDD-16 社交关系防刷(道侣/结义/师徒请求频率限制)

12. 版本记录

版本 日期 修订内容 作者
1.0 2026-07-02 初始版本:服务端权威模型、异常行为检测(加速/篡改/机器人/协议攻击、经济安全RMT/刷金/洗钱)、举报惩罚系统、接口安全、数据安全、审计监控、验收标准 Claude

本文档阈值/参数均引用 Nacos 动态配置,服务端实现时以运行时配置为准,不硬编码。安全规则可根据运营数据持续调整。