Files
SimpleRemoter/docs/Compliance_TechnicalMeasures.md

20 KiB
Raw Permalink Blame History

反滥用技术措施清单(技术证据链)

文档版本1.0 维护范围:本仓库 common/ client/ server/ 三个目录中所有与"反滥用 / 合规执法" 相关的代码模块。 文档定位:本文档是 Compliance_AntiAbuse.md 第 6 节 "发行方内置的反滥用技术措施"的工程实现附表。政策口径以 Compliance_AntiAbuse.md 为准; 本文档仅就"具体代码在哪、为什么这样设计、目前的已知局限"做工程化登记。 受众:本仓库的维护者、合规审查方、独立验证人员。


关于本文档

本仓库自起步即声明"试用版仅供 LAN 内自用,不得跨网",并明确反对任何未授权访问、 隐蔽监控、商业秘密窃取等违法用途(见 README_EN.md / ReadMe.md / Compliance_AntiAbuse.md)。 此声明若仅停留在文字层面,其证明力有限。为此发行方在源代码层面陆续构筑多道 可被独立验证的技术屏障,并将其引入证据链以备:

  1. 监管核查时举证"已尽合理技术措施";
  2. 第三方合规审计时提供可直接 review 的代码位置;
  3. 后续维护者修改这些文件时识别"哪些行为不能被弱化"。

本文档的每一项措施都给出:

  • 源代码位置(精确到文件 + 函数 / 类,不带行号 —— 行号随代码漂移);
  • 机制摘要(一段话讲清楚做什么);
  • 设计动机(为什么需要这一层、防的是哪类滥用形态);
  • 已知局限(不夸大宣传,明示哪些场景挡不住)。

1. 当前生效的技术措施

1.1 入站连接源 IP 段校验

项目 内容
源代码 common/LANChecker.h class LANChecker::CheckAndWarn()
触发位置 client/KernelManager.cpp AuthKernelManager::OnHeatbeatResponse 的 trial 分支
阈值 任一入站连接对端 IP 落在公网段(非 RFC 1918 / RFC 3927 / 回环段)即触发
触发动作 终端用户可见 MessageBox 告警(一次性 latch
设计动机 封堵"试用版被直接挂到公网"这一最常见、技术门槛最低的越权部署
已知局限 攻击者在 LAN 内放置反向代理 / 隧道时,对端 IP 仍呈私网段 → 漏检 → 由 1.3 RTT 反代理 兜底

1.2 监听端口数量上限

项目 内容
源代码 common/LANChecker.h LANChecker::CheckPortLimit(int maxPorts)
触发位置 同 1.1trial 分支调用 CheckPortLimit(2)
阈值 试用:≤ 2 个监听端口;无口令:≤ 2 个
触发动作 终端用户可见告警
设计动机 防止单台试用部署被改造为多租户中转节点 / 公网代理出口
已知局限 仅扫描本进程 PID 的监听端口;攻击者另起辅助进程在同机做端口转发可绕过,但攻击成本已上升,且会被其他机制(如 1.3)侧面捕获

1.3 应用层 RTT 反代理

项目 内容
源代码 common/LANChecker.h class LANRttChecker
触发位置 client/KernelManager.cpp CKernelManager::OnHeatbeatResponse(自 commit 4279e79 起从 AuthKernelManager 迁至此处,使采样源从"客户端到授权服务器"变为"客户端到主控服务器",更精确反映滥用链路)
启停 由主控通过 MasterSettings.IsTrail 字段下发;试用主控 → 开,已授权主控 → 关
阈值参数 25 ms 中位数 / 滑窗 10 / 收敛跳过 5 / 持续超阈 3 次(最快触发 ≥ 150 秒)
触发动作 终端用户可见告警(一次性 latch进程生命周期内不再重弹
设计动机 1.1 的物理盲区补丁:光速决定的真实 RTT 不可被代理转发降低,能识别"源 IP 看似私网、实际经公网中转"的反向隧道部署
已知局限 攻击者自有公网 IP 且与"客户"同城同 ISP 时,物理 RTT 可低于阈值 → 漏检。该残留盲区已在 common/LANChecker.h class LANRttChecker 的头部注释中明示,并标注"需叠加同源 IP 多 ClientID 行为信号做双因素判定"

1.4 授权服务器周期心跳与超时熔断

项目 内容
源代码 common/LANChecker.h class AuthTimeoutChecker
触发位置 client/KernelManager.cpp AuthKernelManager 心跳循环;ResetTimer() 在每次 ACK 到达时被调
阈值 DEBUG 30s 警告RELEASE 300s 警告;后续超时阈值由 AuthTimeoutChecker::Check 控制
触发动作 警告期:可见 MessageBox;终态:进程退出
设计动机 防止"仅在初次激活时联网、之后离线长期使用"以规避吊销;同时为发行方在授权服务器侧吊销违规授权提供下发通道
已知局限 攻击者搭建假冒授权服务器并做 DNS / hosts 劫持可绕过;但属本政策 Compliance_AntiAbuse.md § 5.3 明示禁止之"伪造授权服务器响应"行为,已转入法律风险

1.5 服务端硬性并发连接上限

项目 内容
源代码 server/2015Remote/2015RemoteDlg.cpp CMy2015RemoteDlg 构造、OnInitDialogOnPasswordCheck 三处
机制 m_nMaxConnection = 2 是初始默认;IsPwdHashValid()CheckValid(-1) 失败时强制重置为 2 并 UpdateMaxConnection(2)
设计动机 未授权主控的"硬天花板"。客户端校验代码可能被重打包绕过,但 TCP / UDP 服务器在并发数超限时直接拒绝新连接,是难以从客户端侧绕开的服务端策略
已知局限 未授权主控的运营者若直接修改服务端二进制以解除上限,已构成对政策 Compliance_AntiAbuse.md § 5.3 的根本违反

1.6 系统时钟篡改检测

项目 内容
源代码 common/DateVerify.h class DateVerify
触发位置 client/KernelManager.cpp AuthKernelManager::OnHeatbeatResponse 中授权分支
机制 客户端通过多个公共 NTP 源(阿里云 / 腾讯 / 清华 TUNA / 港澳台 / 全球池等共 11 个,按地理优先级)核对系统时间;时间被回拨用以延长试用 → TerminateProcess(0xDEAD0001)
设计动机 防止用户修改系统时间利用早期试用授权码或绕过时间相关的授权约束
已知局限 出网完全被阻断时无法核对 NTP该情形下与 1.4 共同作用——长时间无 NTP / 无授权心跳同时存在时进程会被自然终止

1.7 子连接身份校验

项目 内容
源代码 server/2015Remote/Server.h CONTEXT_OBJECT::m_bAuthenticated;触发于 TOKEN_CONN_AUTH 处理路径
机制 主连接走 TOKEN_LOGIN;屏幕 / 文件 / 键盘等子连接走 TOKEN_CONN_AUTH,连入后必须在握手阶段提交可校验凭证;当前阶段为"宽容验证"模式,仅打标记,为后续收紧策略保留入口
设计动机 防止攻击者绕过主连接直接连入子连接通道复用既有 ClientID 的会话
已知局限 当前为宽容模式(未通过仍接受),仅作为标记。收紧时机待定,将在新增 commit 中说明

1.8 主控授权状态下发

项目 内容
源代码 common/commands.h struct MasterSettingsAuthorized / IsTrail 字段;服务端 server/2015Remote/2015RemoteDlg.cpp CMy2015RemoteDlg::OnInitDialog 中填充
机制 服务端在客户端注册后将自己的"授权 / 试用"状态写入 MasterSettings 下发;客户端在 client/KernelManager.cpp CMD_MASTERSETTING 分支接收,据此决定是否启用 1.3 RTT 反代理
设计动机 让试用 / 已授权两种主控的客户端行为差异化:试用主控的所有连入客户端自动启用反代理检测;正式授权主控的客户端则关闭,避免误伤合法的跨网远控场景
兼容性 字段位于 MasterSettings.Reserved 的前 2 字节,保持 sizeof(MasterSettings) == 500 不变;旧客户端连新服务端时按 MasterSettingsOldSize 截读,不影响协议兼容

1.9 服务端入站 IP 段即时检测

项目 内容
源代码 server/2015Remote/IOCPServer.cpp OnAccept 末段;common/LANChecker.h LANChecker::IsPrivateIPv4Str
触发位置 server/2015Remote/2015RemoteDlg.cpp CMy2015RemoteDlg::OnTrialWanIpAbuse(由 OnAccept PostMessage(WM_TRIAL_WAN_IP_ABUSE) 触发)
检测时机 每个新连接 accept 后立即检测,比 RTT 路径快(无需累计 30 秒的中位数样本)
信号源 Proxy Protocol v2 透出的真实客户端 IP若存在→ 否则回退到 getpeername 的 raw TCP 对端 IP
阈值 任一入站 IP 不在 RFC 1918 / RFC 3927 / 回环段 → 即触发
触发动作 每个 abusive 连接独立记 Mprintf 日志(含真实 IP + 解析来源);与 1.10 服务端内核级 RTT 监测 共用 IOCPServer::s_TrialAbuseWarned 进程级 latch → 主窗口 MessageBox 弹一次
启停 仅在 m_bTrialMode 为真时执行(StartServerIsTrail(passcode) 缓存);正式授权主控该分支彻底跳过
设计动机 1.10 的 TCP 终结代理盲点 —— 合作型代理FRP / HAProxy若发送 PP2 头,本检测就能拿到真实 IP 并直接命中。即时触发,无需等待 RTT 累积
与客户端 1.1 的关系 两层不重复:[1.1] 在 master 进程内周期性GetExtendedTcpTable,看到的是内核态 raw IP不透 PP2本节在 OnAccept 即时触发,能透 PP2 真实 IP。两层互补
已知局限 不发 PP2 头的代理socat、自制 TCP 转发、不配 PP2 的 FRP→ 看到的仍是代理的 LAN IP本节漏检,由 1.3 客户端 RTT 反代理 端到端 RTT 兜底
性能 每新连接增加一次 inet_pton + 几个位运算(< 1µs。非试用模式下 m_bTrialMode == false,整段分支彻底跳过

1.10 服务端内核级 RTT 监测(SIO_TCP_INFO

项目 内容
源代码 server/2015Remote/IOCPServer.cpp RttPollThreadProc + QuerySocketTcpRttUsserver/2015Remote/Server.h CONTEXT_OBJECT::SetRttUs/GetRttUscommon/LANChecker.h class TcpRttBreachDetector
触发位置 server/2015Remote/2015RemoteDlg.cpp CMy2015RemoteDlg::OnTrialRttAbuse(由 RTT 轮询线程 PostMessage(WM_TRIAL_RTT_ABUSE) 触发)
信号源 Win10 1703+ / Server 2016+ 提供的 WSAIoctl(SIO_TCP_INFO),返回 TCP_INFO_v0.RttUs(内核测得的纯网络 RTT微秒精度不含任何应用层处理
阈值参数 20 ms 中位数 / 滑窗 10 / 收敛跳过 5 / 持续超阈 3 次 @1Hz最快触发 ≥ 30 秒,是 1.3 客户端 RTT 反代理 的 5 倍)
触发动作 每个 abusive 连接独立记 Mprintf 日志(含 ClientID + 真实 IP + median RTT全 server 进程一次性 latchs_TrialRttWarned CAS→ 主窗口 MessageBox 弹一次
启停 仅在主控自身为试用模式时(StartServerIsTrail(passcode))启动专用轮询线程;正式授权主控不启动,零运行时开销
OS 不支持 首次 WSAIoctl 拿到 WSAEOPNOTSUPP 时打一行 Mprintf 日志后线程自杀;1.3 客户端 RTT 反代理 仍作为兜底
设计动机 服务端检测周期 30 svs 客户端 150 s更快识别直接挂公网的 abusive 部署;且代码运行于发行方 / 运营商可控的服务端二进制,比客户端校验更难绕过
已知局限(重要) SIO_TCP_INFO 测得的是服务端 ↔ 直接 TCP 对端的 RTT。任何在 TCP 层终结的代理FRP / ngrok / nginx / HAProxy / socat 等)会让服务端只看到"我 ↔ 代理"那段 LAN RTT完全漏检 WAN 段。本机制只能识别直挂公网 / NAT / VPN 等"不终结 TCP"的部署形态TCP 终结型代理由 1.3 的端到端应用层 RTT 兜底(客户端心跳总耗时无法被任何中间层降低)
范围 IOCPServerTCPUDP / KCP 通道由 1.3 客户端 RTT 反代理 继续兜底

2. 分档授权与对应限制

详见 Compliance_AntiAbuse.md § 7MultiLayerLicense.md。本表仅列对应的强制限制点:

授权档 强制限制 由哪一节技术措施实施
无口令 监听端口 ≤ 2服务端并发 ≤ 2 1.2 + 1.5
试用口令 入站 IP 必须私网段;端口 ≤ 20客户端 RTT ≤ 25 ms服务端内核 RTT ≤ 20 ms周期回连授权服务器系统时钟可信 1.1 + 1.2 + 1.3 + 1.4 + 1.6 + 1.9 + 1.10
正式授权 由签发协议另行约定,技术上解除 1.1 / 1.3 / 1.9 / 1.10 限制 1.8 由服务端下发 IsTrail=0 触发客户端关闭;服务端 IsTrail 为假时 1.9 / 1.10 均跳过

3. 演进时间线(合规相关提交)

按发布时间倒序排列。SHA 列为 git log --oneline 可直接核对的短哈希;任何 独立第三方均可在公开仓库通过 git show <SHA> 自行验证。

日期 SHA 主题 关联节
2026-05-16 7f95f00 Compliance: Server-side anti-proxy — accept-time WAN-IP check + SIO_TCP_INFO kernel-RTT 1.9 + 1.10
2026-05-15 4279e79 Compliance fix: Move LAN RTT check to KernelManager heartbeat 1.3 / 1.8
2026-05-14 14387d6 Compliance: Anti-proxy RTT check + tiered usage policy and disclaimer 1.3 / Compliance_AntiAbuse.md v1.0 发布
—(既往) LANChecker IP 段 / 端口数检测、AuthTimeoutChecker 授权心跳、DateVerify 时钟校验等机制 1.1 / 1.2 / 1.4 / 1.6

后续提交按 commit message 前缀 Compliance:Compliance fix: 识别,加入本表。


4. 规划中的技术措施

以下条目为已确定方向但尚未合入主分支的工作项,列出便于审查方了解未来演进。

4.1 行为信号融合(占位)

LANRttChecker 源码注释中明示的"同源 IP 多 ClientID"行为信号待并入。 计划在授权服务器侧实现,与本仓库客户端 / 主控代码解耦。

针对 1.10 的 TCP 终结代理盲点 —— 合作型代理FRP / HAProxy发送 Proxy Protocol v2 头的情况已由 1.9 兜住; 不发 PP2 的代理socat、自制 TCP 转发)的残留盲区由 1.3 客户端 RTT 反代理 端到端 RTT 兜底,本仓库内无进一步可加的服务端措施。后续考虑授权服务器侧"同源 IP 多 ClientID" 行为信号作为外部交叉验证。


5. 维护者注意事项

对未来修改本仓库的任何贡献者:以下文件 / 模块的削弱、移除、绕过型修改 应被视为对发行方反滥用立场的直接违反PR 一律拒收。即使您是为了"优化体验" 或"修复误报",也请优先选择调阈值 / 加白名单而非禁用机制

不可被静默削弱的内容 文件
LANChecker::CheckAndWarn 中私网段判定逻辑 common/LANChecker.h
LANChecker::CheckPortLimit 的端口数比对 同上
LANRttChecker::SetEnabled 的启停语义 同上
LANRttChecker::RecordSample 的滑窗 / 收敛 / 持续超阈逻辑 同上
AuthTimeoutChecker 的超时熔断分支 同上
DateVerify::isTimeTampered 的多 NTP 比对 common/DateVerify.h
服务端 m_nMaxConnection 在未授权 / 失效校验时回落到 2 的分支 server/2015Remote/2015RemoteDlg.cpp
服务端 MasterSettings.Authorized / IsTrail 字段的真实填充逻辑 同上
客户端 OnHeatbeatResponseLANRttChecker 的调用、AuthTimeoutChecker 的复位 client/KernelManager.cpp
TcpRttBreachDetector 滑窗 / 收敛 / 持续超阈逻辑 common/LANChecker.h
IOCPServer::OnAccept 末段试用模式下的入站 IP 段判定PP2 真实 IP 优先) server/2015Remote/IOCPServer.cpp
IOCPServer::RttPollThreadProc 试用模式判定、SIO_TCP_INFO 探测、per-context 检测器喂样 同上
主对话框 OnTrialRttAbuse / OnTrialWanIpAbuse 弹框 + 日志归档;WM_TRIAL_RTT_ABUSE / WM_TRIAL_WAN_IP_ABUSE 消息映射 server/2015Remote/2015RemoteDlg.cpp
LANChecker::IsPrivateIPv4Str 字符串版私网段判定(被 §1.9 直接依赖) common/LANChecker.h

允许的修改方向:

  • 调整阈值参数(需在 PR 中给出新的统计依据);
  • 新增告警通道(如增加日志落盘 / 加 webhook 通知),但不得替换原有告警通道;
  • 提高检测精度(如本文档 §4 所列规划项);
  • 修复 OS 兼容性 bug但不得以"OS 不支持"为由整体跳过试用档的检测。

6. 与政策文档的对照表

便于审查方在本仓库技术实现 ↔ Compliance_AntiAbuse.md 政策条款之间双向追溯。

政策条款 本文档节
§ 6.1 入站连接源 IP 段校验 1.1
§ 6.2 监听端口数量上限 1.2
§ 6.3 应用层 RTT 反代理 1.3 + 1.9(服务端即时 IP 段判定)+ 1.10(服务端内核级 RTT 补强)
§ 6.4 授权服务器周期心跳 1.4
§ 6.5 措施的可被感知性 见各节"触发动作"列
§ 6.6 措施的合理性声明 见各节"已知局限"列
§ 7 授权分级与对应限制 2

文档结束 / END OF DOCUMENT