Files
pangolin/doc/04-infra.html
T
wangjia 3ae96ef229 docs: 新增整体架构设计文档(doc/,HTML 七章)
覆盖前端五端/后端/MySQL/弹性节点拓扑/Web安全/安全总纲,遵循 design/ 设计系统视觉呈现。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:57:49 +08:00

188 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>04 机器与网络拓扑 · 穿山甲架构设计</title>
<link rel="stylesheet" href="assets/style.css">
</head>
<body>
<header class="site-header"><div class="inner">
<a class="brand" href="index.html"><img src="assets/logo-mark.svg" alt="Pangolin"><span><span class="zh">穿山甲 · 架构设计</span><br><span class="en">Pangolin Architecture</span></span></a>
<nav class="site-nav">
<a href="index.html">总览</a>
<a href="01-frontend.html">01 前端</a>
<a href="02-backend.html">02 后端</a>
<a href="03-database.html">03 数据库</a>
<a href="04-infra.html" class="active">04 网络拓扑</a>
<a href="05-web-security.html">05 Web 安全</a>
<a href="06-security.html">06 安全总纲</a>
</nav>
<button class="theme-btn" id="themeBtn" title="切换深浅主题"><i data-lucide="moon"></i></button>
</div></header>
<main class="doc">
<div class="doc-hero">
<div class="overline">Chapter 04 · Infrastructure & Topology</div>
<h1>机器与网络拓扑</h1>
<p class="lede">目标:<strong>弹性可变的网络拓扑</strong>——所有节点可一键更换或自动更换,IP 可随时轮换;任何单点被识别、被阻断都不影响整体服务。设计核心是「节点是牲口不是宠物」:节点无状态、可丢弃、分钟级重建。</p>
</div>
<section id="layers">
<h2><span class="num">§1</span>三层弹性拓扑</h2>
<div class="diagram">
<div class="flow">
<div class="fbox accent"><b>用户</b><span>REALITY / Hysteria2</span></div>
<div class="farr"></div>
<div class="fbox"><b>入口层 Entry</b><span>消耗品 IP 池 · 多厂商 · 高频轮换</span></div>
<div class="farr"></div>
<div class="fbox ghost"><b>中转层 Relay(可选)</b><span>内部隧道转发</span></div>
<div class="farr"></div>
<div class="fbox ok"><b>落地层 Exit</b><span>精品 IP · 稳定出口 · 用户不可见</span></div>
</div>
<div class="flow">
<div class="fnote">免费用户:直连消耗品池入口(单跳直出)。付费用户:入口 → 落地两跳为主,中转层在入口与落地间链路质量差时按需启用。</div>
</div>
<div class="cap">被识别阻断的永远是入口 IP(暴露面);落地 IP 只对内部隧道可见,几乎不会被烧</div>
</div>
<div class="tbl-wrap"><table>
<thead><tr><th>角色</th><th>暴露面</th><th>IP 等级</th><th>更换频率</th><th>跑什么</th></tr></thead>
<tbody>
<tr><td><strong>entry 入口</strong></td><td>直面用户与审查(唯一公网暴露)</td><td>消耗品池:冷门小厂、便宜、可隐私购买</td><td>被封即换;常态每 24 周主动轮换</td><td>sing-boxREALITY + Hy2 端口跳跃)+ agent</td></tr>
<tr><td><strong>relay 中转</strong></td><td>仅入口可见</td><td>低价大带宽</td><td>低频</td><td>内部隧道转发 + agent</td></tr>
<tr><td><strong>exit 落地</strong></td><td>仅中转/入口可见</td><td>精品池:稳定厂商、原生 IP、解锁好</td><td>极低频</td><td>出口 + agent</td></tr>
<tr><td><strong>probe 探针</strong></td><td></td><td>境内多 ISP 拨测点 + 境外对照点</td><td></td><td>探测脚本,结果回报控制面</td></tr>
</tbody>
</table></div>
<ul>
<li><strong>分级对应套餐</strong>(plan/ 既定策略):免费用户消耗免费池入口(tier=free),被封损失最小;付费用户走 tier=pro 入口 + 落地分层,体验稳定。</li>
<li>起步规模可以「入口=落地」单跳跑通,拓扑字段(role)从第一天就建模,后续平滑演进为分层,客户端无感。</li>
</ul>
</section>
<section id="cattle">
<h2><span class="num">§2</span>节点无状态化(可丢弃的前提)</h2>
<ul>
<li>节点上只有:sing-box + agent 二进制 + 由控制面下发的运行时配置(用户 UUID 表、伪装 SNI、密钥)。<strong>零用户库、零日志、零持久数据。</strong></li>
<li>全部由 <code>cloud-init</code> 一段脚本拉起:装 agent → agent 持引导 token 向控制面 mTLS 注册 → 控制面下发完整配置。重建一台 = 开机 + 等注册,约 3–5 分钟。</li>
<li>节点间不互信:中转/落地链路用独立隧道密钥,按节点对发放,回收节点即吊销。</li>
</ul>
</section>
<section id="lifecycle">
<h2><span class="num">§3</span>节点生命周期状态机</h2>
<div class="diagram">
<div class="flow">
<div class="fbox"><b>provisioning</b><span>厂商 API 开机中</span></div>
<div class="farr"></div>
<div class="fbox warn"><b>probing</b><span>探活:境内外可达性验证</span></div>
<div class="farr"></div>
<div class="fbox ok"><b>up</b><span>在目录 · 接受连接</span></div>
<div class="farr"></div>
<div class="fbox warn"><b>draining</b><span>不接新连接 · 排空存量</span></div>
<div class="farr"></div>
<div class="fbox bad"><b>down</b><span>已出目录</span></div>
<div class="farr"></div>
<div class="fbox ghost"><b>destroyed</b><span>销毁 · IP 释放</span></div>
</div>
<div class="flow"><div class="fnote">up → down(跳过 draining):判封确认时立即下架。probing 失败 → 直接 destroyed(坏 IP 不入池)。每次迁移写 node_events 并 bump 目录 version。</div></div>
</div>
<ul>
<li><strong>目录灰度</strong><code>nodes</code> 任何变更 bump 全局 version;客户端带 <code>if_version</code> 轮询(在线连接中收到目录推送可平滑迁移);客户端缓存最后一份可用目录兜底。</li>
<li><strong>draining 排空</strong>:默认 30 分钟或存量连接归零,先到为准;免费节点可直接硬切(用户重连成本低)。</li>
</ul>
</section>
<section id="replace">
<h2><span class="num">§4</span>一键更换与自动更换</h2>
<h3>4.1 一键更换(管理端按钮 / CLI 一条命令)</h3>
<div class="diagram">
<div class="flow">
<div class="fbox accent"><b>replace(node)</b><span>管理端触发</span></div>
<div class="farr"></div>
<div class="fbox"><b>开新机</b><span>厂商 API(同区域 · 厂商池内可换家)</span></div>
<div class="farr"></div>
<div class="fbox"><b>cloud-init</b><span>装 agent · 自注册</span></div>
<div class="farr"></div>
<div class="fbox warn"><b>probing</b><span>境内外探活通过</span></div>
<div class="farr"></div>
<div class="fbox ok"><b>新机入池</b><span>version bump</span></div>
<div class="farr"></div>
<div class="fbox"><b>旧机 draining</b><span>→ destroy · IP 释放</span></div>
</div>
<div class="cap">先建后拆(make-before-break):任何更换动作期间容量不下降</div>
</div>
<ul>
<li><strong>换 IP 不换机</strong>(更轻量):厂商支持弹性 IP 时直接 API 换绑 → 探活 → 更新 endpoint → version bump,全程分钟级。</li>
<li><strong>全量轮换</strong>:同一命令对整个池滚动执行(并发度 1–2),用于例行轮换或大面积事件后重建。</li>
<li>所有动作幂等、写 <code>audit_log</code><code>node_events</code>;基础设施定义用 Terraform + 厂商 API 适配层(providers 表登记,凭证独立 secrets 管理)。</li>
</ul>
<h3>4.2 自动更换:判封 → 下架 → 补新</h3>
<h4>判封信号(三路互证,避免误判)</h4>
<div class="tbl-wrap"><table>
<thead><tr><th>信号源</th><th>采集</th><th>说明</th></tr></thead>
<tbody>
<tr><td><strong>境内探针</strong></td><td>电信 / 联通 / 移动 ≥3 个拨测点,每 5 分钟:TCP 连通 + TLS 握手 + 真实协议握手</td><td>核心信号;探针点用境内云函数/拨测服务,与运营身份隔离</td></tr>
<tr><td><strong>境外对照</strong></td><td>境外探针同款探测</td><td>区分「被墙」与「机器挂了」:境内挂 + 境外通 = 疑似被封;两边都挂 = 故障</td></tr>
<tr><td><strong>流量侧</strong></td><td>agent 上报在线数/带宽,环比骤降(如 15 分钟内 −80%)</td><td>辅助信号,提早怀疑</td></tr>
</tbody>
</table></div>
<h4>判定与处置规则(scheduler 驱动,阈值可配)</h4>
<ul>
<li><strong>疑似</strong>:境内 ≥2/3 拨测点连续 2 个周期失败,且境外正常 → <code>blocked_suspect</code>,节点降权(weight→10),加密探测频率。</li>
<li><strong>确认</strong>:连续 6 个周期(30 分钟)维持上述状态 → <code>blocked_confirmed</code> → 立即 <code>down</code> 出目录 + 自动触发 §4.1 补新流程。</li>
<li><strong>故障</strong>(境内外同挂):走告警人工介入,不消耗 IP 配额重建。</li>
<li><strong>容量保护</strong>:自动补新失败(厂商 API 错误、新机探活不过)连续 3 次 → 升级为告警;池内 up 节点低于水位线(如 tier 内 <70% 无条件告警</li>
<li><strong>熔断</strong>:1 小时内同池自动更换 >N 台(疑似大面积事件)→ 暂停自动重建、保留现场、人工决策(可能需要换厂商/换区域/换伪装 SNI 而非头铁补机)。</li>
</ul>
<div class="callout warn"><b>主动降低被封概率(比换得快更重要)</b>
<ul>
<li>REALITY 伪装 SNI 定期评估更换(目标站不可被墙、延迟特征合理);密钥/short_id 随节点轮换。</li>
<li>Hysteria2 端口跳跃(区间随机),抗 UDP QoS 与端口特征。</li>
<li>新 IP 上线前先「养」:探活通过后小流量灰度 24h 再放满 weight,避免新 IP 行为突变被标记。</li>
<li>免费池与付费池物理隔离(不同厂商账号),免费池被批量烧不殃及付费池。</li>
</ul></div>
</section>
<section id="scheduling">
<h2><span class="num">§5</span>调度、容量与厂商池</h2>
<h3>5.1 节点目录排序(服务端)与智能选择(客户端)</h3>
<ul>
<li>服务端目录按 <code>score = f(实时负载, 探针延迟, weight, tier)</code> 排序下发,给客户端一个好的默认顺序与「信号条」数据。</li>
<li>客户端「智能选择」(UI 默认选中):sing-box URLTest 在候选前 N 个节点本地实测自动择优——最终路径决策在端上,服务端只缩小候选集。</li>
</ul>
<h3>5.2 厂商池策略</h3>
<div class="tbl-wrap"><table>
<thead><tr><th></th><th>厂商画像</th><th>要求</th></tr></thead>
<tbody>
<tr><td><strong>消耗品池</strong>entry/free</td><td>冷门小厂 ≥3 家,按量/小时计费,IP 便宜量大</td><td>有 API 可自动开退机;支持加密货币付款、隐私注册;避开被重点封锁的大厂 IP 段</td></tr>
<tr><td><strong>精品池</strong>exit/pro entry</td><td>稳定厂商 1–2 家,原生 IP、带宽质量好</td><td>同样隐私注册;区域:HK / JP / SG / US 起步</td></tr>
</tbody>
</table></div>
<ul>
<li>每家厂商独立账号、独立邮箱、加密货币付款——厂商之间、厂商与域名/收款之间不产生身份关联(红线,见 06 章)。</li>
<li>控制面(API + MySQL + Redis)部署在与节点完全无关的稳定云上,不放任何代理流量;节点全灭不影响控制面,反之亦然。</li>
</ul>
<h3>5.3 监控告警</h3>
<ul>
<li>节点心跳缺失(>90s)、池水位、自动更换熔断、探针自身失联、兑换失败率、注册转化漏斗。</li>
<li>告警出口:TG bot(运营专用匿名号)。所有告警附 runbook 链接(05 章)。</li>
</ul>
</section>
</main>
<nav class="pager">
<a href="03-database.html"><span>上一章</span><b>← 03 数据库</b></a>
<a class="next" href="05-web-security.html"><span>下一章</span><b>05 Web 安全与灾备 →</b></a>
</nav>
<footer class="colophon">穿山甲 · Pangolin — 内部架构设计文档 · 遵循 design/ 设计系统 · 2026-06</footer>
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
<script src="assets/doc.js"></script>
</body>
</html>