1648871a2a
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1119 lines
75 KiB
HTML
1119 lines
75 KiB
HTML
<!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">
|
||
<style>
|
||
/* ---- 拓扑图专用扩展 ---- */
|
||
.topo-legend {
|
||
display: flex; gap: 1.5rem; flex-wrap: wrap; align-items: center;
|
||
font-size: var(--text-caption); color: var(--fg2); margin-bottom: var(--space-4);
|
||
padding: var(--space-3) var(--space-4); background: var(--surface);
|
||
border: 1px solid var(--border); border-radius: var(--radius-md);
|
||
}
|
||
.topo-legend .item { display: flex; align-items: center; gap: var(--space-2); white-space: nowrap; }
|
||
.l-dash { width: 28px; height: 3px; border-radius: 2px; flex: none; }
|
||
.l-dash.data { background: var(--red-500); }
|
||
.l-dash.ctrl { background: var(--green-500); }
|
||
.l-dash.ops { background: var(--fg3); }
|
||
.l-dash.ops-d { background: none; border-top: 2px dashed var(--fg3); width: 28px; height: 0; }
|
||
|
||
/* fbox 颜色扩展 */
|
||
.fbox.data { border-color: var(--red-500); background: var(--danger-subtle); }
|
||
.fbox.data b { color: var(--danger); }
|
||
.fbox.ctrl-g { border-color: var(--success); background: var(--success-subtle); }
|
||
.fbox.ctrl-g b { color: var(--success); }
|
||
.fbox.muted { border-color: var(--border); background: var(--surface); opacity: .75; }
|
||
|
||
/* SNI 路由表 */
|
||
.sni-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); margin-bottom: var(--space-4); box-shadow: var(--shadow-sm); }
|
||
.sni-wrap table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
|
||
.sni-wrap th { text-align: left; background: var(--bg-subtle); color: var(--fg2); font-size: var(--text-caption); font-weight: 600; letter-spacing: var(--tracking-wide); padding: 9px 14px; border-bottom: 1px solid var(--border); white-space: nowrap; }
|
||
.sni-wrap td { padding: 10px 14px; border-bottom: 1px solid var(--border); font-family: var(--font-mono); font-size: var(--text-sm); vertical-align: middle; }
|
||
.sni-wrap tr:last-child td { border-bottom: none; }
|
||
.sni-wrap td.desc { font-family: var(--font-sans); color: var(--fg2); }
|
||
|
||
/* 小徽章 */
|
||
.badge { display: inline-block; font-size: 0.65rem; font-weight: 700; padding: 1px 6px; border-radius: 3px; letter-spacing: 0.05em; text-transform: uppercase; white-space: nowrap; }
|
||
.badge.data { background: var(--danger-subtle); color: var(--danger); }
|
||
.badge.ctrl { background: var(--success-subtle); color: var(--success); }
|
||
.badge.ops { background: var(--bg-subtle); color: var(--fg2); border: 1px solid var(--border); }
|
||
.badge.new { background: var(--warning-subtle); color: var(--warning); }
|
||
.badge.warn { background: var(--warning-subtle); color: var(--warning); border: 1px solid var(--warning); }
|
||
|
||
/* 端口胶囊 */
|
||
code.port { font-family: var(--font-mono); font-size: 0.8em; padding: 1px 6px; border-radius: 3px; }
|
||
code.port.data { background: var(--danger-subtle); color: var(--danger); border: 1px solid var(--red-500); }
|
||
code.port.ctrl { background: var(--success-subtle); color: var(--success); border: 1px solid var(--success); }
|
||
code.port.ops { background: var(--bg-subtle); color: var(--fg2); border: 1px solid var(--border); }
|
||
|
||
/* 跳转路径块 */
|
||
.path-block {
|
||
background: var(--surface); border: 1px solid var(--border);
|
||
border-radius: var(--radius-lg); overflow: hidden; margin-bottom: var(--space-3);
|
||
}
|
||
.path-block + .path-block { margin-top: var(--space-3); }
|
||
.path-title {
|
||
display: flex; align-items: center; gap: var(--space-2);
|
||
padding: var(--space-3) var(--space-4); background: var(--bg-subtle);
|
||
border-bottom: 1px solid var(--border); font-weight: 600; font-size: var(--text-sm);
|
||
}
|
||
.path-title .badge { margin-left: auto; }
|
||
.path-steps { padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
|
||
.hop {
|
||
display: flex; align-items: baseline; gap: var(--space-2);
|
||
font-size: var(--text-sm); line-height: 1.5;
|
||
}
|
||
.hop .n { font-family: var(--font-mono); color: var(--fg3); font-size: var(--text-caption); min-width: 1.6rem; flex: none; }
|
||
.hop .arrow { color: var(--fg3); font-family: var(--font-mono); flex: none; }
|
||
.hop .node { font-family: var(--font-mono); font-weight: 500; }
|
||
.hop .sub { font-size: var(--text-caption); color: var(--fg2); }
|
||
.hop .note { font-size: var(--text-caption); color: var(--fg3); margin-left: auto; white-space: nowrap; }
|
||
.hop.indent { padding-left: 2.4rem; }
|
||
.hop.indent2 { padding-left: 4.8rem; }
|
||
|
||
/* 双列分支布局 */
|
||
.branch-grid {
|
||
display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4);
|
||
margin: var(--space-4) 0;
|
||
}
|
||
@media (max-width: 700px) { .branch-grid { grid-template-columns: 1fr; } }
|
||
|
||
/* 节点角色标 */
|
||
.role-bar {
|
||
display: flex; gap: var(--space-2); flex-wrap: wrap;
|
||
padding: var(--space-2) var(--space-4); border-top: 1px solid var(--border);
|
||
font-size: var(--text-caption); color: var(--fg3);
|
||
}
|
||
</style>
|
||
</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>§0 是现网实际在跑的 EC2 单机部署</strong>(具体到端口与容器),<strong>§1–§5 是目标弹性多节点架构</strong>。两者均严格区分「数据面」(用户 VPN 流量)与「控制面」(API / 管理 / 运维流量),数据面与控制面在物理路径上彻底分离。</p>
|
||
<div class="topo-legend">
|
||
<span style="font-weight:600;color:var(--fg1)">图例:</span>
|
||
<span class="item"><span class="l-dash data"></span> 数据面 Data Plane — VPN 代理流量(用户→节点→互联网)</span>
|
||
<span class="item"><span class="l-dash ctrl"></span> 控制面 Control Plane — API / Web / 面板流量</span>
|
||
<span class="item"><span class="l-dash ops-d"></span> 运维面 Ops — 证书续签 / CI/CD / 心跳</span>
|
||
</div>
|
||
|
||
<!-- ── 网络请求流向总览 SVG ── -->
|
||
<div class="diagram" style="padding:var(--space-6);margin-top:var(--space-4)">
|
||
<p style="text-align:center;font-size:var(--text-caption);color:var(--fg3);margin:0 0 var(--space-4);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;font-weight:600">网络请求流向总览 · Network Request Flow</p>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 270" style="width:100%;height:auto;display:block;overflow:visible" font-family="'Noto Sans SC','Manrope',sans-serif">
|
||
<defs>
|
||
<marker id="tad" viewBox="0 0 10 8" refX="9" refY="4" markerWidth="6" markerHeight="6" orient="auto"><path d="M0,0 L10,4 L0,8 z" fill="#C0533B"/></marker>
|
||
<marker id="tag" viewBox="0 0 10 8" refX="9" refY="4" markerWidth="6" markerHeight="6" orient="auto"><path d="M0,0 L10,4 L0,8 z" fill="#467046"/></marker>
|
||
<marker id="tao" viewBox="0 0 10 8" refX="9" refY="4" markerWidth="6" markerHeight="6" orient="auto"><path d="M0,0 L10,4 L0,8 z" fill="#B0A491"/></marker>
|
||
<marker id="tagr" viewBox="0 0 10 8" refX="1" refY="4" markerWidth="6" markerHeight="6" orient="auto"><path d="M10,0 L0,4 L10,8 z" fill="#467046"/></marker>
|
||
</defs>
|
||
|
||
<!-- DATA PLANE label -->
|
||
<text x="6" y="15" font-family="'JetBrains Mono',monospace" font-size="9" font-weight="600" fill="#C0533B" letter-spacing="1">DATA PLANE 数据面 — VPN 代理流量</text>
|
||
|
||
<!-- 用户 x=5 y=24 w=104 h=84 -->
|
||
<rect x="5" y="24" width="104" height="84" rx="10" fill="#FAF3ED" stroke="#CC8B5C" stroke-width="1.5"/>
|
||
<text x="57" y="56" text-anchor="middle" font-size="15" font-weight="700" fill="#7E4426">用户</text>
|
||
<text x="57" y="72" text-anchor="middle" font-size="10.5" fill="#9E5630">客户端</text>
|
||
<text x="57" y="99" text-anchor="middle" font-size="8.5" fill="#B96A3D" font-family="'JetBrains Mono',monospace">Flutter · sing-box</text>
|
||
|
||
<line x1="111" y1="66" x2="119" y2="66" stroke="#C0533B" stroke-width="2" marker-end="url(#tad)"/>
|
||
|
||
<!-- GFW x=121 y=24 w=78 h=84 -->
|
||
<rect x="121" y="24" width="78" height="84" rx="10" fill="#F6E1DA" stroke="#C0533B" stroke-width="1.5" stroke-dasharray="4,3"/>
|
||
<text x="160" y="56" text-anchor="middle" font-size="13" font-weight="700" fill="#9E4230">GFW</text>
|
||
<text x="160" y="71" text-anchor="middle" font-size="10" fill="#C0533B">防火长城</text>
|
||
<text x="160" y="99" text-anchor="middle" font-size="9" fill="#D4715A">封锁 · 识别</text>
|
||
|
||
<line x1="201" y1="66" x2="209" y2="66" stroke="#C0533B" stroke-width="2.5" marker-end="url(#tad)"/>
|
||
<text x="205" y="59" text-anchor="middle" font-size="8" fill="#C0533B" font-family="'JetBrains Mono',monospace">穿透</text>
|
||
|
||
<!-- 接入点 x=211 y=16 w=124 h=100 (taller + bold border) -->
|
||
<rect x="211" y="16" width="124" height="100" rx="10" fill="#ffffff" stroke="#B96A3D" stroke-width="2.5"/>
|
||
<text x="273" y="46" text-anchor="middle" font-size="14" font-weight="700" fill="#7E4426">接入点</text>
|
||
<text x="273" y="62" text-anchor="middle" font-size="10" fill="#9E5630">Entry Node</text>
|
||
<text x="273" y="79" text-anchor="middle" font-size="8.5" fill="#B96A3D" font-family="'JetBrains Mono',monospace">tcp:443 REALITY</text>
|
||
<text x="273" y="93" text-anchor="middle" font-size="8.5" fill="#B96A3D" font-family="'JetBrains Mono',monospace">udp:443 Hysteria2</text>
|
||
<text x="273" y="108" text-anchor="middle" font-size="8.5" fill="#8C8270">消耗品 IP · 唯一公网暴露</text>
|
||
|
||
<line x1="337" y1="66" x2="348" y2="66" stroke="#B0A491" stroke-width="1.5" stroke-dasharray="4,3" marker-end="url(#tao)"/>
|
||
<text x="342" y="59" text-anchor="middle" font-size="7.5" fill="#B0A491">可选</text>
|
||
|
||
<!-- 转发点 x=350 y=24 w=92 h=84 (dashed) -->
|
||
<rect x="350" y="24" width="92" height="84" rx="10" fill="transparent" stroke="#D2C8B8" stroke-width="1.5" stroke-dasharray="5,3"/>
|
||
<text x="396" y="54" text-anchor="middle" font-size="13" font-weight="600" fill="#8C8270">转发点</text>
|
||
<text x="396" y="70" text-anchor="middle" font-size="10" fill="#B0A491">Relay</text>
|
||
<text x="396" y="84" text-anchor="middle" font-size="9" fill="#B0A491">大带宽 · 低价</text>
|
||
<text x="396" y="99" text-anchor="middle" font-size="8.5" fill="#D2C8B8">— 可选 —</text>
|
||
|
||
<line x1="444" y1="66" x2="454" y2="66" stroke="#B0A491" stroke-width="1.5" stroke-dasharray="4,3" marker-end="url(#tao)"/>
|
||
|
||
<!-- 落地节点 x=456 y=24 w=110 h=84 -->
|
||
<rect x="456" y="24" width="110" height="84" rx="10" fill="#E9F0E6" stroke="#467046" stroke-width="1.5"/>
|
||
<text x="511" y="54" text-anchor="middle" font-size="13" font-weight="600" fill="#2E4D2E">落地节点</text>
|
||
<text x="511" y="70" text-anchor="middle" font-size="10" fill="#5B8C5A">Exit Node</text>
|
||
<text x="511" y="86" text-anchor="middle" font-size="9" fill="#5B8C5A">精品 IP · 用户不可见</text>
|
||
<text x="511" y="100" text-anchor="middle" font-size="8.5" fill="#5B8C5A">稳定出境</text>
|
||
|
||
<line x1="568" y1="66" x2="578" y2="66" stroke="#467046" stroke-width="2" marker-end="url(#tag)"/>
|
||
|
||
<!-- 目标网站 x=580 y=24 w=112 h=84 -->
|
||
<rect x="580" y="24" width="112" height="84" rx="10" fill="#FAF8F4" stroke="#E6DFD3" stroke-width="1.5"/>
|
||
<text x="636" y="54" text-anchor="middle" font-size="13" font-weight="600" fill="#2E2A24">目标网站</text>
|
||
<text x="636" y="70" text-anchor="middle" font-size="10" fill="#6B6253">互联网</text>
|
||
<text x="636" y="86" text-anchor="middle" font-size="8.5" fill="#8C8270" font-family="'JetBrains Mono',monospace">Google / Netflix</text>
|
||
<text x="636" y="100" text-anchor="middle" font-size="8.5" fill="#8C8270">任意境外服务</text>
|
||
|
||
<!-- Phase notes -->
|
||
<text x="273" y="126" text-anchor="middle" font-size="8.5" fill="#B96A3D">▲ Phase 0: 接入=落地(单跳直出)</text>
|
||
<text x="511" y="118" text-anchor="middle" font-size="8.5" fill="#467046">▲ Phase 1+: 独立落地节点</text>
|
||
|
||
<!-- DIVIDER -->
|
||
<line x1="5" y1="147" x2="694" y2="147" stroke="#E6DFD3" stroke-width="1" stroke-dasharray="6,4"/>
|
||
<text x="350" y="159" text-anchor="middle" font-size="9.5" fill="#B0A491">控制面 Control Plane — 独立路径,不经过代理节点</text>
|
||
|
||
<!-- CONTROL PLANE label -->
|
||
<text x="6" y="174" font-family="'JetBrains Mono',monospace" font-size="9" font-weight="600" fill="#467046" letter-spacing="1">CONTROL PLANE 控制面 — 管理 / API / 节点配置</text>
|
||
|
||
<!-- Flutter App x=5 y=183 w=104 h=68 -->
|
||
<rect x="5" y="183" width="104" height="68" rx="10" fill="#E9F0E6" stroke="#5B8C5A" stroke-width="1.5"/>
|
||
<text x="57" y="207" text-anchor="middle" font-size="12" font-weight="600" fill="#2E4D2E">Flutter App</text>
|
||
<text x="57" y="222" text-anchor="middle" font-size="10" fill="#5B8C5A">账户 / 订阅</text>
|
||
<text x="57" y="243" text-anchor="middle" font-size="8.5" fill="#5B8C5A" font-family="'JetBrains Mono',monospace">HTTPS</text>
|
||
|
||
<line x1="111" y1="217" x2="119" y2="217" stroke="#467046" stroke-width="1.5" marker-end="url(#tag)"/>
|
||
|
||
<!-- Cloudflare CDN x=121 y=183 w=96 h=68 -->
|
||
<rect x="121" y="183" width="96" height="68" rx="10" fill="#E9F0E6" stroke="#5B8C5A" stroke-width="1.5"/>
|
||
<text x="169" y="207" text-anchor="middle" font-size="12" font-weight="600" fill="#2E4D2E">Cloudflare</text>
|
||
<text x="169" y="222" text-anchor="middle" font-size="10" fill="#5B8C5A">CDN / 域名池</text>
|
||
<text x="169" y="243" text-anchor="middle" font-size="8.5" fill="#5B8C5A">源站 IP 隐藏</text>
|
||
|
||
<line x1="219" y1="217" x2="227" y2="217" stroke="#467046" stroke-width="1.5" marker-end="url(#tag)"/>
|
||
|
||
<!-- API Server x=229 y=178 w=124 h=78 -->
|
||
<rect x="229" y="178" width="124" height="78" rx="10" fill="#E9F0E6" stroke="#467046" stroke-width="2"/>
|
||
<text x="291" y="202" text-anchor="middle" font-size="13" font-weight="600" fill="#2E4D2E">API Server</text>
|
||
<text x="291" y="218" text-anchor="middle" font-size="10" fill="#5B8C5A">Go · 独立机器</text>
|
||
<text x="291" y="233" text-anchor="middle" font-size="8.5" fill="#5B8C5A" font-family="'JetBrains Mono',monospace">MySQL + Redis</text>
|
||
<text x="291" y="248" text-anchor="middle" font-size="8.5" fill="#5B8C5A">用户 / 节点 / 订阅</text>
|
||
|
||
<!-- mTLS gRPC bidirectional: API top ↔ Entry bottom -->
|
||
<line x1="284" y1="177" x2="266" y2="118" stroke="#467046" stroke-width="1.5" stroke-dasharray="4,3" marker-start="url(#tagr)" marker-end="url(#tag)"/>
|
||
<rect x="300" y="136" width="88" height="32" rx="4" fill="#FAF8F4" opacity="0.95"/>
|
||
<text x="344" y="150" text-anchor="middle" font-size="8.5" fill="#467046" font-family="'JetBrains Mono',monospace">mTLS gRPC</text>
|
||
<text x="344" y="163" text-anchor="middle" font-size="8" fill="#5B8C5A">配置下发 · 心跳</text>
|
||
|
||
<!-- 探针 x=372 y=183 w=108 h=68 (dashed) -->
|
||
<rect x="372" y="183" width="108" height="68" rx="10" fill="#FAF8F4" stroke="#D2C8B8" stroke-width="1.5" stroke-dasharray="4,3"/>
|
||
<text x="426" y="207" text-anchor="middle" font-size="12" font-weight="600" fill="#6B6253">探针系统</text>
|
||
<text x="426" y="222" text-anchor="middle" font-size="10" fill="#8C8270">境内多 ISP 拨测</text>
|
||
<text x="426" y="243" text-anchor="middle" font-size="8.5" fill="#8C8270">判封 · 5min 周期</text>
|
||
|
||
<!-- 探针 → API (report, pointing left) -->
|
||
<line x1="370" y1="217" x2="355" y2="217" stroke="#8C8270" stroke-width="1.5" stroke-dasharray="3,3" marker-end="url(#tao)"/>
|
||
<text x="362" y="210" text-anchor="middle" font-size="7.5" fill="#8C8270">上报</text>
|
||
|
||
<!-- 探针 → 接入点 (probe tests node) curved dashed -->
|
||
<path d="M 420,181 C 420,154 360,132 330,118" stroke="#B0A491" stroke-width="1" stroke-dasharray="3,3" fill="none" marker-end="url(#tao)"/>
|
||
<text x="408" y="155" text-anchor="middle" font-size="7.5" fill="#B0A491">拨测节点</text>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════
|
||
§0 当前 EC2 单机生产部署(Phase 0 现状)
|
||
══════════════════════════════════════════════════════════════ -->
|
||
<section id="current">
|
||
<h2><span class="num">§0</span>当前 EC2 单机部署(仅供测试,非生产 VPN 网络)</h2>
|
||
<div class="callout danger"><b>重要说明:EC2 是个人测试机,与 VPN 网络架构彻底分离</b>
|
||
当前 EC2(18.136.60.128)是运维者个人的测试机,上面跑着与 Pangolin VPN 业务无关的个人服务(marzban/jiu/blog)。<strong>后续 Pangolin VPN 生产网络将使用独立专用机器,与这台 EC2 完全无关</strong>。EC2 只是当前验证 edge/singbox 容器可行性的临时环境。VPN 正式上线后,EC2 上不会再部署 Pangolin 的任何组件,以保护个人服务不受 VPN 业务影响(封锁、扫描、流量特征关联等)。</div>
|
||
<p>当前所有服务共用 <strong>一台 EC2(ap-southeast-1,18.136.60.128,ec2-user)</strong>。Pangolin 数据面容器(edge / singbox)与现网已有服务(marzban / jiu / blog / billing)并存;<strong>Marzban REALITY 提供线上代理,绝不能中断</strong>。</p>
|
||
|
||
<h3>0.1 在跑服务与端口一览</h3>
|
||
<div class="tbl-wrap"><table>
|
||
<thead><tr><th>服务</th><th>容器/进程</th><th>监听地址:端口</th><th>网络模式</th><th>流量类型</th><th>所属</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>pangolin-edge</strong></td>
|
||
<td>Docker · <code>pangolin-edge:local</code></td>
|
||
<td><code class="port data">:80/tcp</code> <code class="port data">:443/tcp</code></td>
|
||
<td>host</td>
|
||
<td><span class="badge data">数据面</span> <span class="badge ctrl">控制面</span></td>
|
||
<td>Pangolin</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>pangolin-singbox</strong></td>
|
||
<td>Docker · <code>sing-box:v1.13.12</code></td>
|
||
<td><code class="port data">:443/udp</code></td>
|
||
<td>host</td>
|
||
<td><span class="badge data">数据面</span> Hysteria2</td>
|
||
<td>Pangolin</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Marzban REALITY</strong></td>
|
||
<td>marzban 服务(宿主)</td>
|
||
<td><code class="port ops">127.0.0.1:10443</code></td>
|
||
<td>loopback</td>
|
||
<td><span class="badge data">数据面</span> VLESS+REALITY</td>
|
||
<td>现有(勿动)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Marzban 面板</strong></td>
|
||
<td>marzban 服务(宿主)</td>
|
||
<td><code class="port ops">127.0.0.1:8899</code></td>
|
||
<td>loopback</td>
|
||
<td><span class="badge ctrl">控制面</span> Web UI</td>
|
||
<td>现有(勿动)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>jiu.service</strong></td>
|
||
<td>systemd(Go 二进制)</td>
|
||
<td><code class="port ops">127.0.0.1:8080</code></td>
|
||
<td>loopback</td>
|
||
<td><span class="badge ctrl">控制面</span> 电商 API</td>
|
||
<td>现有(勿动)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>blog(Next.js)</strong></td>
|
||
<td>Docker / pm2</td>
|
||
<td><code class="port ops">127.0.0.1:3000</code></td>
|
||
<td>loopback</td>
|
||
<td><span class="badge ctrl">控制面</span> Blog</td>
|
||
<td>现有(勿动)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Umami 统计</strong></td>
|
||
<td>Docker</td>
|
||
<td><code class="port ops">127.0.0.1:3001</code></td>
|
||
<td>loopback</td>
|
||
<td><span class="badge ctrl">控制面</span> 统计后台</td>
|
||
<td>现有(勿动)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>billing.service</strong></td>
|
||
<td>systemd</td>
|
||
<td><code class="port ops">:18080/tcp</code></td>
|
||
<td>host(独立,不经 edge)</td>
|
||
<td><span class="badge ctrl">控制面</span> 计费</td>
|
||
<td>现有(勿动)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<h3>0.2 SNI 分流路由表(pangolin-edge · stream 层)</h3>
|
||
<p>pangolin-edge 以 <strong>host 网络</strong>绑定 <code>:443/tcp</code>,在 <strong>TCP 层</strong>(ssl_preread)读取 SNI,<em>不解密</em>,直接按域名把连接 proxy_pass 到不同后端:</p>
|
||
<div class="sni-wrap"><table>
|
||
<thead><tr><th>SNI(客户端发送的域名)</th><th>→ 后端(容器内 127.0.0.1)</th><th>再经 nginx http vhost</th><th>最终落点</th><th>类型</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>www.cloudflare.com</code></td>
|
||
<td><code>127.0.0.1:10443</code></td>
|
||
<td>——(直通)</td>
|
||
<td class="desc">Marzban REALITY 数据面 → 互联网</td>
|
||
<td><span class="badge data">数据面</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>default(其他 SNI)</code></td>
|
||
<td><code>127.0.0.1:10443</code></td>
|
||
<td>——(直通)</td>
|
||
<td class="desc">同上(兜底)</td>
|
||
<td><span class="badge data">数据面</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>vpn.51yanmei.com</code></td>
|
||
<td><code>127.0.0.1:8443</code></td>
|
||
<td>SSL 终止 → <code>:8899</code></td>
|
||
<td class="desc">Marzban 管理面板</td>
|
||
<td><span class="badge ctrl">控制面</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>blog.51yanmei.com</code></td>
|
||
<td><code>127.0.0.1:8444</code></td>
|
||
<td>SSL 终止 → <code>:3000</code> / <code>:3001</code></td>
|
||
<td class="desc">Next.js 博客 + Umami 统计</td>
|
||
<td><span class="badge ctrl">控制面</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>jiu.51yanmei.com</code></td>
|
||
<td><code>127.0.0.1:8445</code></td>
|
||
<td>SSL 终止 → <code>:8080</code></td>
|
||
<td class="desc">jiu.service API + 静态</td>
|
||
<td><span class="badge ctrl">控制面</span></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<div class="callout"><b>为什么用 tcp stream 层分流而非 http 层?</b>
|
||
SNI 分流在 TCP 层完成,TLS 连接<strong>不在 edge 里解密</strong>再到 Marzban REALITY。这让 REALITY 的 TLS 流量完整透传:Marzban 收到原始 ClientHello,保留 REALITY 协议的所有防识别特征。只有 <code>vpn/blog/jiu.51yanmei.com</code> 的 HTTPS 流量才在 edge 内部做 SSL 终止(TLS → 明文 → 反代后端)。</div>
|
||
|
||
<h3>0.3 数据面:VPN 流量跳转路径</h3>
|
||
<div class="branch-grid">
|
||
<div class="path-block">
|
||
<div class="path-title"><i data-lucide="zap" style="width:15px;height:15px;color:var(--danger)"></i> 路径 A:REALITY(TCP)<span class="badge data" style="margin-left:auto">主线</span></div>
|
||
<div class="path-steps">
|
||
<div class="hop"><span class="n">①</span><span class="arrow">→</span><span class="node">VPN 客户端</span><span class="sub">· Flutter + sing-box libbox</span></div>
|
||
<div class="hop"><span class="n">②</span><span class="arrow">→</span><span class="node">GFW(穿越)</span><span class="sub">· REALITY 流量伪装成 HTTPS 到 cloudflare.com</span></div>
|
||
<div class="hop"><span class="n">③</span><span class="arrow">→</span><span class="node">EC2 <code class="port data">:443/tcp</code></span><span class="sub">· 公网 IP 18.136.60.128</span></div>
|
||
<div class="hop"><span class="n">④</span><span class="arrow">→</span><span class="node">pangolin-edge</span><span class="sub">· ssl_preread SNI=www.cloudflare.com → proxy_pass</span></div>
|
||
<div class="hop"><span class="n">⑤</span><span class="arrow">→</span><span class="node"><code class="port ops">127.0.0.1:10443</code></span><span class="sub">· Marzban REALITY(宿主进程,loopback)</span></div>
|
||
<div class="hop"><span class="n">⑥</span><span class="arrow">→</span><span class="node">🌐 互联网</span><span class="sub">· Marzban 作为出口,EC2 的公网 IP 出境</span></div>
|
||
</div>
|
||
<div class="role-bar">TLS 握手在 Marzban(⑤)内完成 · edge(④)零解密 · 完整 REALITY 防识别</div>
|
||
</div>
|
||
<div class="path-block">
|
||
<div class="path-title"><i data-lucide="wifi" style="width:15px;height:15px;color:var(--danger)"></i> 路径 B:Hysteria2(UDP)<span class="badge data" style="margin-left:auto">备线</span></div>
|
||
<div class="path-steps">
|
||
<div class="hop"><span class="n">①</span><span class="arrow">→</span><span class="node">VPN 客户端</span><span class="sub">· Flutter + sing-box libbox</span></div>
|
||
<div class="hop"><span class="n">②</span><span class="arrow">→</span><span class="node">GFW(穿越)</span><span class="sub">· QUIC over UDP · masquerade=www.bing.com</span></div>
|
||
<div class="hop"><span class="n">③</span><span class="arrow">→</span><span class="node">EC2 <code class="port data">:443/udp</code></span><span class="sub">· TCP 与 UDP 共用 443,互不干扰</span></div>
|
||
<div class="hop"><span class="n">④</span><span class="arrow">→</span><span class="node">pangolin-singbox</span><span class="sub">· sing-box Hysteria2 inbound(host 网络)</span></div>
|
||
<div class="hop"><span class="n">⑤</span><span class="arrow">→</span><span class="node">🌐 互联网</span><span class="sub">· direct outbound · EC2 公网 IP 出境</span></div>
|
||
</div>
|
||
<div class="role-bar">TLS(ALPN=h3)在 singbox 内终止 · 自签证书(secrets/hy2/)· 端口跳跃抗 QoS</div>
|
||
</div>
|
||
</div>
|
||
<div class="callout ok"><b>关键:数据面不经过任何 API 服务</b> 用户的代理流量(路径 A/B)<strong>完全不经过控制面</strong>(API Server、MySQL、Redis)。节点(当前即 EC2 上的 Marzban/singbox)不保存任何用户身份信息——零用户库、零浏览日志。计费数据(字节数)由控制面独立上报,不在数据面节点产生。</div>
|
||
|
||
<h3>0.4 控制面:Web / 面板流量跳转路径</h3>
|
||
<p>所有 Web 流量(Marzban 面板、jiu 管理端、博客)均经 Cloudflare CDN 前置隐藏源站 IP,到 EC2 后再由 pangolin-edge 做 SNI 分流 + SSL 终止 + HTTP 反代:</p>
|
||
|
||
<div class="path-block">
|
||
<div class="path-title"><i data-lucide="layout-dashboard" style="width:15px;height:15px;color:var(--success)"></i> 控制面通用路径(以 vpn.51yanmei.com 为例)<span class="badge ctrl" style="margin-left:auto">控制面</span></div>
|
||
<div class="path-steps">
|
||
<div class="hop"><span class="n">①</span><span class="arrow">→</span><span class="node">浏览器 / 管理员</span></div>
|
||
<div class="hop"><span class="n">②</span><span class="arrow">→</span><span class="node">Cloudflare CDN</span><span class="sub">· DNS 解析 → CF 边缘节点 · 源站 IP 隐藏</span></div>
|
||
<div class="hop"><span class="n">③</span><span class="arrow">→</span><span class="node">EC2 <code class="port ctrl">:443/tcp</code></span><span class="sub">· CF→EC2 段为 HTTPS(CF Origin Certificate)</span></div>
|
||
<div class="hop"><span class="n">④</span><span class="arrow">→</span><span class="node">pangolin-edge · tcp stream</span><span class="sub">· ssl_preread 读 SNI=vpn.51yanmei.com → proxy_pass :8443</span></div>
|
||
<div class="hop"><span class="n">⑤</span><span class="arrow">→</span><span class="node"><code class="port ops">127.0.0.1:8443</code> nginx http vhost</span><span class="sub">· SSL 终止(Let's Encrypt 证书)· X-Real-IP=$http_cf_connecting_ip</span></div>
|
||
<div class="hop"><span class="n">⑥</span><span class="arrow">→</span><span class="node"><code class="port ops">127.0.0.1:8899</code> Marzban 面板</span><span class="sub">· HTTP 反代 · 宿主进程 · loopback</span></div>
|
||
</div>
|
||
<div class="role-bar">blog → :8444 → :3000(Next.js) + /stats/ → :3001(Umami) | jiu → :8445 → :8080(jiu.service) + 静态(/opt/jiu/)</div>
|
||
</div>
|
||
|
||
<div class="callout warn"><b>注意 :80 的行为</b> pangolin-edge 的 nginx http 模块监听 <code>:80</code>(default_server)。所有业务域名均配置了 <code>return 301 https://</code> 跳转;未匹配域名直接返回 404。<strong>不存在</strong>明文 HTTP 落地的业务路由。</div>
|
||
|
||
<h3>0.5 运维面:证书自续签循环</h3>
|
||
<div class="diagram">
|
||
<div class="flow">
|
||
<div class="fbox ghost"><b>pangolin-edge 容器内</b><span>后台进程(启动后 60s 开始)</span></div>
|
||
<div class="farr">每 12h</div>
|
||
<div class="fbox warn"><b>certbot renew</b><span>DNS-01 验证 · --quiet</span></div>
|
||
<div class="farr">→</div>
|
||
<div class="fbox"><b>Cloudflare DNS API</b><span>/etc/cloudflare.ini · TXT record</span></div>
|
||
<div class="farr">→</div>
|
||
<div class="fbox"><b>Let's Encrypt</b><span>证书颁发</span></div>
|
||
</div>
|
||
<div class="flow" style="margin-top:0.75rem">
|
||
<div class="farr" style="padding-left:1rem">若有续期</div>
|
||
<div class="farr">→</div>
|
||
<div class="fbox ok"><b>nginx -s reload</b><span>--deploy-hook · 容器内热重载</span></div>
|
||
<div class="farr">↑</div>
|
||
<div class="fbox ghost"><b>/etc/letsencrypt</b><span>rw 挂载卷(宿主 + edge 共享)</span></div>
|
||
</div>
|
||
<div class="cap">无宿主 cron · 无 docker socket · 无跨容器信号 · edge 自续签自己用的证书</div>
|
||
</div>
|
||
<p class="muted">证书覆盖:<code>vpn.51yanmei.com</code>、<code>blog.51yanmei.com</code>、<code>jiu.51yanmei.com</code>(Let's Encrypt · DNS-01 / Cloudflare)。Hysteria2 用自签证书(<code>secrets/hy2/</code>),与 LE 无关。</p>
|
||
</section>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════
|
||
§1 三层弹性拓扑(Phase 1+ 目标架构)
|
||
══════════════════════════════════════════════════════════════ -->
|
||
<section id="layers">
|
||
<h2><span class="num">§1</span>三层弹性拓扑(目标多节点架构)</h2>
|
||
<p>§0 是单机现状;§1 开始描述 Pangolin 自有节点架构的目标形态。核心原则:<strong>入口 IP 是唯一公网暴露面(消耗品);落地 IP 只对隧道内部可见(精品);控制面独立部署,完全不跑用户流量</strong>。</p>
|
||
|
||
<h3>1.1 数据面:用户 VPN 流量路径</h3>
|
||
<div class="diagram">
|
||
<div class="flow">
|
||
<div class="fbox accent"><b>VPN 客户端</b><span>Flutter · sing-box libbox</span></div>
|
||
<div class="farr">REALITY<br>或 Hy2</div>
|
||
<div class="fbox data"><b>入口节点 Entry</b><span>消耗品 IP · :443 · sing-box</span></div>
|
||
<div class="farr">内部隧道<br>(付费用户)</div>
|
||
<div class="fbox warn"><b>中转节点 Relay</b><span>可选 · 大带宽低价</span></div>
|
||
<div class="farr">内部隧道</div>
|
||
<div class="fbox ok"><b>落地节点 Exit</b><span>精品 IP · 稳定出口</span></div>
|
||
<div class="farr">→</div>
|
||
<div class="fbox ghost"><b>🌐 目标网站</b><span>Netflix / Google / etc.</span></div>
|
||
</div>
|
||
<div class="flow" style="margin-top:0.75rem">
|
||
<div class="fnote">免费用户:入口 = 落地(单跳直出),消耗品池;付费用户:入口 → 落地两跳,中转层按需启用;客户端 URLTest 实测择优,服务端目录只缩小候选集。</div>
|
||
</div>
|
||
<div class="cap">被识别/封锁的永远是入口 IP(唯一公网暴露);落地 IP 几乎不会被烧</div>
|
||
</div>
|
||
|
||
<h3>1.2 控制面:API 管理与节点注册路径</h3>
|
||
<div class="branch-grid">
|
||
<div class="path-block">
|
||
<div class="path-title"><i data-lucide="smartphone" style="width:15px;height:15px;color:var(--success)"></i> 客户端 ↔ API 服务器</div>
|
||
<div class="path-steps">
|
||
<div class="hop"><span class="n">①</span><span class="arrow">→</span><span class="node">Flutter App / Web 用户中心</span></div>
|
||
<div class="hop"><span class="n">②</span><span class="arrow">→</span><span class="node">Cloudflare 域名池</span><span class="sub">· 多域名轮换 · 源站 IP 隐藏</span></div>
|
||
<div class="hop"><span class="n">③</span><span class="arrow">→</span><span class="node">API Server(Go)</span><span class="sub">· 独立机器 · 不跑任何代理流量</span></div>
|
||
<div class="hop"><span class="n">④</span><span class="arrow">→</span><span class="node">MySQL 8 + Redis</span><span class="sub">· 用户/订阅/节点/激活码</span></div>
|
||
<div class="hop"><span class="n">⑤</span><span class="arrow">←</span><span class="node">节点目录(带版本)</span><span class="sub">· if_version 增量轮询 · 客户端缓存兜底</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="path-block">
|
||
<div class="path-title"><i data-lucide="server" style="width:15px;height:15px;color:var(--success)"></i> 节点 Agent ↔ API 服务器</div>
|
||
<div class="path-steps">
|
||
<div class="hop"><span class="n">①</span><span class="arrow">→</span><span class="node">新节点开机</span><span class="sub">· cloud-init 脚本拉起 agent</span></div>
|
||
<div class="hop"><span class="n">②</span><span class="arrow">→</span><span class="node">mTLS gRPC 注册</span><span class="sub">· 引导 token → API 签发节点证书</span></div>
|
||
<div class="hop"><span class="n">③</span><span class="arrow">←</span><span class="node">配置下发</span><span class="sub">· UUID 表 / 伪装 SNI / 隧道密钥</span></div>
|
||
<div class="hop"><span class="n">④</span><span class="arrow">→</span><span class="node">sing-box 启动</span><span class="sub">· agent 管理进程生命周期</span></div>
|
||
<div class="hop"><span class="n">⑤</span><span class="arrow">↔</span><span class="node">心跳 + 指标上报</span><span class="sub">· 每 30s · 在线数/带宽/延迟</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="diagram" style="margin-top:var(--space-4)">
|
||
<div class="flow">
|
||
<div class="fbox ghost"><b>探针系统</b><span>境内多 ISP 拨测</span></div>
|
||
<div class="farr">5min 周期</div>
|
||
<div class="fbox ctrl-g"><b>API · Scheduler</b><span>判封逻辑 · 状态机</span></div>
|
||
<div class="farr">blocked_confirmed</div>
|
||
<div class="fbox warn"><b>节点 Down</b><span>立即出目录</span></div>
|
||
<div class="farr">→</div>
|
||
<div class="fbox data"><b>自动补新</b><span>厂商 API 开机</span></div>
|
||
<div class="farr">→</div>
|
||
<div class="fbox ok"><b>探活通过</b><span>入池 · version bump</span></div>
|
||
</div>
|
||
<div class="flow" style="margin-top:0.5rem">
|
||
<div class="fnote">控制面负责全部节点生命周期管理;数据面节点不保存任何用户信息;两面物理隔离,互不干扰。</div>
|
||
</div>
|
||
<div class="cap">判封三路互证:境内探针 + 境外对照 + 流量侧骤降 · 避免误判</div>
|
||
</div>
|
||
|
||
<h3>1.3 三层节点角色对照</h3>
|
||
<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>直面用户与 GFW(唯一公网暴露)</td>
|
||
<td>消耗品池:冷门小厂 · 便宜 · 可隐私购买</td>
|
||
<td>被封即换;常态每 2–4 周主动轮换</td>
|
||
<td>sing-box(REALITY + 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>:入口 = 落地(当前 EC2 即此模式)。role 字段从第一天建模,后续演进为分层对客户端无感。</li>
|
||
<li><strong>分级对应套餐</strong>:免费用户消耗消耗品池(tier=free),被封损失最小;付费用户走 tier=pro 入口 + 落地分层。</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════
|
||
§2 节点无状态化
|
||
══════════════════════════════════════════════════════════════ -->
|
||
<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>
|
||
<li>节点全灭不影响控制面(API + MySQL + Redis 独立部署);反之亦然。</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════
|
||
§3 节点生命周期状态机
|
||
══════════════════════════════════════════════════════════════ -->
|
||
<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,客户端收到新 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>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════
|
||
§4 一键更换与自动更换
|
||
══════════════════════════════════════════════════════════════ -->
|
||
<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>:自动补新失败连续 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>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════
|
||
§5 调度、容量与厂商池
|
||
══════════════════════════════════════════════════════════════ -->
|
||
<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>
|
||
|
||
<h4>5.2.1 消耗品池候选厂商(接入节点 · 被封即换)</h4>
|
||
<p class="muted" style="font-size:var(--text-sm);margin-bottom:var(--space-3)">数据来源:各厂商官网 + LowEndTalk / VPSBenchmarks 社区实测,调研日期 2026-06。价格以美元计,¥ 人民币标注为国内商家。</p>
|
||
<div class="tbl-wrap"><table>
|
||
<thead><tr><th>厂商</th><th>最低月价</th><th>亚洲节点</th><th>Crypto / 匿名</th><th>API 自动开退机</th><th>中国网络</th><th>KYC</th><th>推荐场景</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>HostHatch</strong></td>
|
||
<td>~$2.4/月</td>
|
||
<td>HK · SG · TYO</td>
|
||
<td>BTC;接近匿名</td>
|
||
<td><span class="badge ctrl">✓ REST API</span><br><small>支持创建/删除实例</small></td>
|
||
<td>普通 BGP,无 CN2</td>
|
||
<td>无需</td>
|
||
<td><strong>API 自动化首选</strong>;三亚洲节点全覆盖;NVMe 性能好;适合批量消耗自动轮换</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Servury</strong></td>
|
||
<td>$3.99/月<br><code class="port ops">$0.55/天</code></td>
|
||
<td>新加坡 · 欧洲</td>
|
||
<td>BTC / XMR / ETH;<strong>完全零 KYC</strong>(无需邮箱,32 位随机凭证)</td>
|
||
<td><span class="badge ops">✗</span></td>
|
||
<td>普通 BGP</td>
|
||
<td>完全无需</td>
|
||
<td><strong>极匿名消耗品</strong>;按日计费便于快速轮换;凭证无账号体系,极隐私</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>ExtraVM</strong></td>
|
||
<td>$4.5/月</td>
|
||
<td>SG · TYO · LAX · AMS</td>
|
||
<td>50+ 币种(BTC/XMR/USDT等);零 KYC</td>
|
||
<td><span class="badge ops">✗</span></td>
|
||
<td>普通 BGP</td>
|
||
<td>无需(仅邮箱)</td>
|
||
<td>多区域同时部署;币种最全;AMD Ryzen/EPYC NVMe 高性能</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>RackNerd</strong></td>
|
||
<td>$1.88/月<br><small>年付特惠</small></td>
|
||
<td>新加坡 · LA(DC-02)</td>
|
||
<td>BTC 等 30+ 种;接近匿名</td>
|
||
<td><span class="badge ops">✗ 仅管理已有机</span></td>
|
||
<td>LA-DC02 部分 CN2;SG 普通 BGP</td>
|
||
<td>无需</td>
|
||
<td>价格最低($1.88);无 API 开退机,需手动;适合预算极紧且愿意手动维护的场景</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Vultr</strong></td>
|
||
<td>$6/月</td>
|
||
<td>HK · SG · TYO · Osaka</td>
|
||
<td>BTC via BitPay</td>
|
||
<td><span class="badge ctrl">✓ REST API v2</span><br><small>Terraform provider</small></td>
|
||
<td>普通 BGP;HK 走 163 骨干,晚高峰丢包 5–15%</td>
|
||
<td>信用卡或 BTC</td>
|
||
<td>API 完整成熟;覆盖 HK/JP/SG;IP 段曝光度高,需频繁换;不适合做长期精品节点</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>AkileCloud</strong><br><small>HK Lite 系列</small></td>
|
||
<td>¥9/月<br><small>≈ $1.3</small></td>
|
||
<td>HK · JP</td>
|
||
<td>USDT;无 KYC</td>
|
||
<td><span class="badge ops">✗</span></td>
|
||
<td>NTT/PCCW,非大陆优化线路</td>
|
||
<td>无需</td>
|
||
<td>国内 USDT 付款最方便;HK Lite 延迟低适合消耗接入;Pro 系列升精品池</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Hetzner</strong><br><small>通过 Caasify/BitLaunch</small></td>
|
||
<td>€3.99/月<br><code class="port ops">小时计费</code></td>
|
||
<td>新加坡(唯一亚洲)</td>
|
||
<td>官方不接受;需 Caasify 等第三方 BTC 购买</td>
|
||
<td><span class="badge ctrl">✓ 行业最强 API</span><br><small>Terraform/Pulumi</small></td>
|
||
<td>普通 BGP;SG 无中国优化</td>
|
||
<td>第三方付款可绕过</td>
|
||
<td>API 能力最强 + 真正小时计费;SG 无 CN2 是缺点;适合工程化自动化程度高的场景</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<h4>5.2.2 精品落地池候选厂商(Exit 节点 · 稳定保留)</h4>
|
||
<div class="tbl-wrap"><table>
|
||
<thead><tr><th>厂商</th><th>月价范围</th><th>推荐节点</th><th>线路类型</th><th>延迟→大陆</th><th>IP 质量 / 解锁</th><th>支付方式</th><th>推荐场景</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>DMIT</strong><br><small>Pro 系列</small></td>
|
||
<td>TYO: $21.9/月<br>HK: $39.9/月<br>LAX: $36.9/年起</td>
|
||
<td>TYO · HKG · LAX</td>
|
||
<td><strong>CN2 GIA 三网全向</strong><br><code>CN2 + AS9929 + CMIN2</code></td>
|
||
<td>HK: 30–60ms<br>TYO: ~80ms<br>LAX: 150ms</td>
|
||
<td>DC IP;HK/TYO 部分解锁 Netflix 港/日区;换 IP:每 15 天免费 1 次</td>
|
||
<td>BTC + 支付宝 + WeChat;无 KYC</td>
|
||
<td><strong>精品落地首选</strong>;CN2 GIA 行业口碑最佳;晚高峰稳定无抖动;TYO Pro 性价比最高</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Misaka Network</strong></td>
|
||
<td>$4.75/月起</td>
|
||
<td>HK · TYO · SG</td>
|
||
<td>自有 AS + Equinix 接入<br>高质量 IP Transit</td>
|
||
<td>HK: 10–30ms<br>TYO: 50–80ms</td>
|
||
<td><strong>原生 IP</strong>;Equinix HK2 顶级机房;流媒体解锁能力强(Netflix / YouTube Premium)</td>
|
||
<td>Alipay / Visa;无 KYC</td>
|
||
<td>原生 IP 精品;对 IP 纯净度和解锁效果要求最高的落地场景;价格较低</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>AkileCloud</strong><br><small>HK Pro 系列</small></td>
|
||
<td>¥35/月<br><small>≈ $4.9</small></td>
|
||
<td>HK</td>
|
||
<td>电信 CN2<br>联通 CUG<br>移动 CMI</td>
|
||
<td>广州: 8–15ms<br>上海: 30–70ms<br>三网全优化</td>
|
||
<td>香港原生 IP;Netflix 港区可解锁;B 站 / YouTube Premium</td>
|
||
<td>USDT + 支付宝;无 KYC</td>
|
||
<td><strong>性价比最高精品</strong>;CN2+CUG+CMI 三网全覆盖;价格仅 DMIT HK 的 1/8</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>搬瓦工</strong><br><small>BandwagonHost</small></td>
|
||
<td>LAX: $17/月<br>HK: $90/月<br>Osaka: $50/月</td>
|
||
<td>HK · LAX · Osaka</td>
|
||
<td>CN2 GIA-E 三网<br>(KiwiVM 可一键迁机房 = 换 IP)</td>
|
||
<td>HK: 55ms<br>LAX: 140–160ms</td>
|
||
<td>原生 IP;各区域解锁对应区 Netflix;换 IP 可迁机房(免费)</td>
|
||
<td>信用卡 / PayPal;无 KYC;未明确 Crypto</td>
|
||
<td>行业稳定性标杆;HK 价格贵但质量天花板;换 IP 有机房迁移机制;适合预算充足场景</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>V.PS</strong><br><small>TYO Focus 系列</small></td>
|
||
<td>€25/月</td>
|
||
<td>TYO</td>
|
||
<td>CN2 GIA + AS9929<br>三网回程双优化</td>
|
||
<td>~80ms</td>
|
||
<td>DC IP;解锁能力未明确;需实测</td>
|
||
<td>Crypto / PayPal;无 KYC</td>
|
||
<td>东京 CN2+AS9929 备选;库存受限,需关注补货;价格适中</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>GreenCloudVPS</strong><br><small>HK CN2 GIA</small></td>
|
||
<td>$15/月起</td>
|
||
<td>HK · SG · TYO</td>
|
||
<td>HK: CN2 GIA / GT<br>SG: 普通 BGP</td>
|
||
<td>HK: ~50ms</td>
|
||
<td>DC IP;流媒体解锁弱;<span class="badge warn">⚠ HK 中国直连限速 10 Mbps</span></td>
|
||
<td>BTC;无 KYC</td>
|
||
<td>预算受限备选;HK 带宽上限 10 Mbps 是硬伤,大流量不适合;BTC 支付方便</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<div class="callout"><b>选厂商优先顺序</b><br>
|
||
<strong>消耗品池</strong>:HostHatch(API自动化)→ Servury/ExtraVM(极匿名)→ RackNerd(最便宜但手动)→ Vultr(API好但IP脏)<br>
|
||
<strong>精品落地池</strong>:DMIT TYO/HK Pro(首选,CN2 GIA口碑最佳)→ Misaka(原生IP/解锁)→ AkileCloud HK Pro(性价比)→ 搬瓦工(预算充足时)<br>
|
||
每家厂商使用独立账号体系,不产生关联(见 §6.5)。</div>
|
||
|
||
<ul>
|
||
<li>每家厂商独立账号、独立邮箱、加密货币付款——厂商之间、厂商与域名/收款之间不产生身份关联(红线,见 06 章)。</li>
|
||
<li>控制面(API + MySQL + Redis)部署在与节点完全无关的稳定云上,不放任何代理流量;节点全灭不影响控制面,反之亦然。</li>
|
||
</ul>
|
||
|
||
<h4>5.2.3 域名注册商候选(接入域名 · 控制面域名)</h4>
|
||
<p class="muted" style="font-size:var(--text-sm);margin-bottom:var(--space-3)">数据来源:各注册商官网 + KYCnot.me 隐私评级 + 社区实测,调研日期 2026-06。</p>
|
||
|
||
<h5 style="font-size:var(--text-sm);font-weight:700;color:var(--fg2);margin:var(--space-4) 0 var(--space-2)">消耗品接入域名(批量注册 · 频繁轮换)</h5>
|
||
<div class="tbl-wrap"><table>
|
||
<thead><tr><th>注册商</th><th>.COM 年价</th><th>加密货币支付</th><th>WHOIS 隐私</th><th>API 自动化</th><th>KYC 要求</th><th>管辖地</th><th>推荐场景</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Porkbun</strong></td>
|
||
<td>$9.73 注册<br>$10.91 续费</td>
|
||
<td>BTC / BCH / ETH / LTC / USDC</td>
|
||
<td><span class="badge ctrl">✓ 永久免费</span></td>
|
||
<td><span class="badge ctrl">✓ REST API</span><br><small>注册/删除/DNS 全支持</small></td>
|
||
<td>标准(美国 ICANN)</td>
|
||
<td>美国(俄勒冈)</td>
|
||
<td><strong>消耗品首选</strong>;价格最低 + 多 Crypto + API 齐全;轮换成本约 $10/域/年</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Dynadot</strong></td>
|
||
<td>~$10.88 续费</td>
|
||
<td>BTC / ETH / LTC 等多种</td>
|
||
<td><span class="badge ctrl">✓ 永久免费</span></td>
|
||
<td><span class="badge ctrl">✓ REST API</span><br><small>含 dropcatch(抢注到期域名)</small></td>
|
||
<td>标准(美国 ICANN)</td>
|
||
<td>美国(加州)</td>
|
||
<td>API 含抢注 + 后市场功能;适合需要回收旧域名的场景;400+ TLD</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Namecheap</strong></td>
|
||
<td>$8.99 注册<br>$18.48 续费</td>
|
||
<td>BTC / BCH via Cryptomus</td>
|
||
<td><span class="badge new">⚠ 首年免费,次年 $2.88/年</span></td>
|
||
<td><span class="badge ctrl">✓ XML API</span><br><small>功能最全但续费价涨幅大</small></td>
|
||
<td>标准(美国 ICANN)</td>
|
||
<td>美国</td>
|
||
<td>注册价最低 $8.99;续费涨价严重($18.48),批量长期使用需注意成本</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<h5 style="font-size:var(--text-sm);font-weight:700;color:var(--fg2);margin:var(--space-4) 0 var(--space-2)">控制面 / 高隐私稳定域名(稀少 · 长期保有 · 极匿名)</h5>
|
||
<div class="tbl-wrap"><table>
|
||
<thead><tr><th>注册商</th><th>.COM 年价</th><th>加密货币 / 匿名</th><th>WHOIS 隐私</th><th>API</th><th>KYC</th><th>管辖地</th><th>推荐场景</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Njalla</strong><br><code class="port ops">njal.la</code></td>
|
||
<td>$17.47/域/年</td>
|
||
<td><strong>XMR(Monero)主要支付</strong>;最匿名;可 Tor 登录</td>
|
||
<td><span class="badge ctrl">✓ 最强</span><br><small>Njalla 是法律上的域名所有人,你持使用权</small></td>
|
||
<td><span class="badge ctrl">✓ JSON-RPC 2.0</span></td>
|
||
<td><strong>完全零 KYC</strong>;支持 XMPP 注册无邮箱</td>
|
||
<td>瑞典(Pirate Bay 创始人 Peter Sunde 创立)</td>
|
||
<td><strong>控制面首选</strong>;域名所有权法律隔离 + XMR + 零KYC + Tor,身份隔离最彻底</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>1984.is</strong></td>
|
||
<td>请直接询价<br><small>冰岛注册商</small></td>
|
||
<td>BTC + XMR</td>
|
||
<td><span class="badge ctrl">✓ 免费保护</span></td>
|
||
<td><span class="badge ops">✗ 无公开 API</span></td>
|
||
<td>低 KYC;隐私优先</td>
|
||
<td>冰岛(非 14 眼联盟成员)</td>
|
||
<td>管辖地多样化备选;BTC+XMR;冰岛法律体系与美国/EU 独立;适合备用控制面域名</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>OrangeWebsite</strong></td>
|
||
<td>请直接询价</td>
|
||
<td>BTC;匿名注册</td>
|
||
<td><span class="badge ctrl">✓ 免费保护</span></td>
|
||
<td><span class="badge ops">✗ 无公开 API</span></td>
|
||
<td>Level 2 KYC(Crypto 付款时)</td>
|
||
<td>冰岛(2009 年创立,自由言论导向)</td>
|
||
<td>冰岛第三选;不推荐主力,API 缺失 + 部分 Crypto 需 KYC</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Gandi</strong></td>
|
||
<td>$11 注册<br><span class="badge warn">⚠ $38 续费(高!)</span></td>
|
||
<td>无 Crypto;信用卡/转账</td>
|
||
<td><span class="badge ctrl">✓ GDPR 强制保护</span></td>
|
||
<td><span class="badge ctrl">✓ REST API</span></td>
|
||
<td>EU 标准 GDPR</td>
|
||
<td>法国(EU)</td>
|
||
<td>EU 司法管辖备选;续费 $38 价格贵;无 Crypto 是硬伤;不推荐为首选</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<h5 style="font-size:var(--text-sm);font-weight:700;color:var(--fg2);margin:var(--space-4) 0 var(--space-2)">DNS 解析服务选择</h5>
|
||
<div class="tbl-wrap"><table>
|
||
<thead><tr><th>服务</th><th>价格</th><th>特点</th><th>注意事项</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Cloudflare DNS</strong>(免费版)</td>
|
||
<td>免费</td>
|
||
<td>最快 anycast 解析;全球 TTFB 最低;API 完整;支持 Proxy 模式(CDN + 源站 IP 隐藏)</td>
|
||
<td><span class="badge warn">⚠ 必须使用与个人 EC2 <strong>完全独立</strong>的 Cloudflare 账号</span>——两个账号一旦被关联(同邮箱/支付方式),VPN 域名被封会连累 51yanmei.com 个人账号</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Cloudflare DNS</strong>(付费 $20/月)</td>
|
||
<td>$20/月起</td>
|
||
<td>DDoS 保护增强;高级防火墙规则;适合控制面 API 域名</td>
|
||
<td>控制面 API 域名量少,可考虑 Pro 增强防护</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>HE.net(Hurricane Electric)</strong></td>
|
||
<td>免费</td>
|
||
<td>老牌 DNS,完全免费;适合作 Cloudflare 的 Secondary DNS 备份</td>
|
||
<td>仅做备份,不作主 DNS;主 DNS 出问题时 HE.net 接管防止域名失联</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<div class="callout danger" style="margin-top:var(--space-4)"><b>⛔ 绝对禁用 —— 中国大陆注册商 / DNS 服务</b><br>
|
||
阿里云域名(万网)/ DNSPod / eName / West.xyz / 中国万网及其他陆资注册商:均受《网络安全法》管辖,政府可随时强制接管域名或 DNS 记录,<strong>无法用于 VPN 基础设施</strong>。<br>
|
||
<b>.CN / .中国 TLD 同样禁止</b>:域名受 CNNIC 管辖,实名制,无匿名性。</div>
|
||
|
||
<div class="callout" style="margin-top:var(--space-3)"><b>域名选购优先级</b><br>
|
||
<strong>消耗品接入域名</strong>:Porkbun(最低成本 + 多 Crypto + REST API)→ Dynadot(API 含抢注)→ Namecheap(注册便宜但续费贵)<br>
|
||
<strong>控制面域名</strong>:Njalla(XMR + 零KYC + 法律代持,首选)→ 1984.is(冰岛管辖多样化备选)<br>
|
||
<strong>DNS 解析</strong>:Cloudflare(独立账号)+ HE.net 作 Secondary 备份<br>
|
||
<strong>账号隔离</strong>:注册商账号 / Cloudflare 账号均独立于 EC2 个人账号体系(见 §6.5)</div>
|
||
|
||
<h3>5.3 监控告警</h3>
|
||
<ul>
|
||
<li>节点心跳缺失(>90s)、池水位、自动更换熔断、探针自身失联、兑换失败率、注册转化漏斗。</li>
|
||
<li>告警出口:TG bot(运营专用匿名号)。所有告警附 runbook 链接(05 章)。</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════
|
||
§6 节点选购、单机→多机扩容方案与轮换策略
|
||
══════════════════════════════════════════════════════════════ -->
|
||
<section id="procurement">
|
||
<h2><span class="num">§6</span>节点选购、扩容方案与轮换策略</h2>
|
||
<p>本节回答三个实操问题:<strong>买什么机器</strong>、<strong>从 1 台到 N 台怎么演进</strong>、<strong>哪些机器需要频繁轮换</strong>。VPN 生产网络与 EC2 个人测试机彻底分离,独立账号、独立支付、独立域名体系。</p>
|
||
|
||
<h3>6.1 首台测试机推荐</h3>
|
||
<p>第一台机器用来跑通「接入点+落地节点」合一的单跳架构,验证 REALITY / Hy2 可用性。</p>
|
||
<div class="tbl-wrap"><table>
|
||
<thead><tr><th>维度</th><th>推荐</th><th>说明</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><strong>厂商</strong></td><td>Vultr / Racknerd / BuyVM / 搬瓦工</td><td>支持加密货币付款、隐私注册;避免 AWS/GCP/Azure(IP 段被重点封锁)</td></tr>
|
||
<tr><td><strong>区域</strong></td><td>HK / JP / SG(首选)· LA / 韩国(备选)</td><td>靠近大陆,延迟低(50–120ms);HK 被封风险高但速度好,SG 稳定</td></tr>
|
||
<tr><td><strong>规格</strong></td><td>1 vCPU / 1 GB RAM / 20 GB SSD / 1 TB 带宽</td><td>sing-box 极轻量,实际流量带宽是瓶颈;1 TB/月约够 100 用户日常使用</td></tr>
|
||
<tr><td><strong>计费</strong></td><td>按月 $3–8,或按小时(消耗品机器)</td><td>接入点用按小时,落地和控制面用包月稳定套餐</td></tr>
|
||
<tr><td><strong>OS</strong></td><td>Ubuntu 22.04 LTS(minimal)</td><td>社区脚本最多,cloud-init 支持好;不用 CentOS</td></tr>
|
||
<tr><td><strong>网络</strong></td><td>原生住宅或数据中心 IP(非共享 NAT)</td><td>共享 NAT 的 IP 通常已被批量标记;要独立 /32 IP</td></tr>
|
||
</tbody>
|
||
</table></div>
|
||
<div class="callout warn"><b>首台机器不要买大厂</b> AWS / Google Cloud / Microsoft Azure 的 IP 段被 GFW 重点盯防,REALITY 伪装效果大幅降低。测试首选 Vultr Tokyo 或 Racknerd HK,几美元/月,被封直接换。</div>
|
||
|
||
<h3>6.2 单机到 N 台:演进路径</h3>
|
||
|
||
<!-- ── 1台 ── -->
|
||
<div class="path-block">
|
||
<div class="path-title">
|
||
<span class="badge new">1 台</span>
|
||
<span style="font-weight:700">单跳直出(接入 = 落地)— 测试 / 极小规模</span>
|
||
</div>
|
||
<div class="path-steps">
|
||
<div class="hop"><span class="n">机器</span><span class="arrow">→</span><span class="node">1 台 VPS(消耗品 or 精品)</span><span class="sub">· 接入点和落地节点合一</span></div>
|
||
<div class="hop"><span class="n">部署</span><span class="arrow">→</span><span class="node">sing-box(REALITY + Hy2)</span><span class="sub">· 用户 tcp:443 + udp:443 直接进来、直接出去</span></div>
|
||
<div class="hop"><span class="n">优点</span><span class="arrow">→</span><span class="node">最简单,1 台搞定,配置量最小</span></div>
|
||
<div class="hop"><span class="n">缺点</span><span class="arrow">→</span><span class="node">IP 被封 = 全部用户断线</span><span class="sub">· 没有隔离,IP 换了客户端配置也要更新</span></div>
|
||
<div class="hop"><span class="n">控制面</span><span class="arrow">→</span><span class="node">可暂时手动管理(无 API Server)</span><span class="sub">· 仅适合 <10 人内测阶段</span></div>
|
||
</div>
|
||
<div class="role-bar">适合阶段:Phase 0 验证 · 个人测试 · 不建议用于正式上线</div>
|
||
</div>
|
||
|
||
<!-- ── 2台 ── -->
|
||
<div class="path-block">
|
||
<div class="path-title">
|
||
<span class="badge ctrl">2 台</span>
|
||
<span style="font-weight:700">接入 + 落地分离(推荐起步架构)</span>
|
||
</div>
|
||
<div class="path-steps">
|
||
<div class="hop"><span class="n">台 1</span><span class="arrow">→</span><span class="node">接入点(消耗品 VPS)</span><span class="sub">· 用户看见的 IP · 运行 sing-box · 被封即换</span></div>
|
||
<div class="hop"><span class="n">台 2</span><span class="arrow">→</span><span class="node">落地节点(精品 VPS)</span><span class="sub">· 用户看不见 · 实际出境 IP · 稳定不换</span></div>
|
||
<div class="hop"><span class="n">流量</span><span class="arrow">→</span><span class="node">用户 → 接入点 → 内部隧道(WireGuard)→ 落地节点 → 互联网</span></div>
|
||
<div class="hop"><span class="n">好处</span><span class="arrow">→</span><span class="node">接入点被封:换台 1 即可</span><span class="sub">· 台 2(精品IP)几乎不会被烧 · 客户端只需更新接入 IP</span></div>
|
||
<div class="hop"><span class="n">控制面</span><span class="arrow">→</span><span class="node">可以用 API Server(第 3 台独立机器)或暂时手动</span></div>
|
||
</div>
|
||
<div class="role-bar">适合阶段:Phase 1 · 正式上线起步 · 推荐从这里开始</div>
|
||
</div>
|
||
|
||
<!-- ── 3台 ── -->
|
||
<div class="path-block">
|
||
<div class="path-title">
|
||
<span class="badge warn">3 台</span>
|
||
<span style="font-weight:700">多接入点 or 加入中转层</span>
|
||
</div>
|
||
<div class="path-steps">
|
||
<div class="hop"><span class="n">方案 A</span><span class="arrow">→</span><span class="node">2 台接入点 + 1 台落地</span><span class="sub">· 多地区接入(如 HK + SG),提升覆盖和可用性</span></div>
|
||
<div class="hop"><span class="n">方案 B</span><span class="arrow">→</span><span class="node">1 台接入 + 1 台中转 + 1 台落地</span><span class="sub">· 接入→中转隧道→落地:隐藏落地 IP 更彻底,抗溯源</span></div>
|
||
<div class="hop"><span class="n">推荐</span><span class="arrow">→</span><span class="node">方案 A(更实用)</span><span class="sub">· 方案 B 适合落地 IP 极难获取的情况(如解锁用原生 IP)</span></div>
|
||
<div class="hop"><span class="n">控制面</span><span class="arrow">→</span><span class="node">此时强烈建议上 API Server</span><span class="sub">· 手动管 3 台节点的配置/密钥同步成本已很高</span></div>
|
||
</div>
|
||
<div class="role-bar">适合阶段:Phase 1+ · 开始商业化 · 几十到几百用户规模</div>
|
||
</div>
|
||
|
||
<!-- ── N台 ── -->
|
||
<div class="path-block">
|
||
<div class="path-title">
|
||
<span class="badge data">N 台</span>
|
||
<span style="font-weight:700">完整弹性架构(§1 目标形态)</span>
|
||
</div>
|
||
<div class="path-steps">
|
||
<div class="hop"><span class="n">入口池</span><span class="arrow">→</span><span class="node">N 台消耗品接入点(自动开退机)</span><span class="sub">· 分布 HK/JP/SG/LA · 免费用户/付费用户独立池</span></div>
|
||
<div class="hop"><span class="n">中转池</span><span class="arrow">→</span><span class="node">2–4 台中转节点(可选)</span><span class="sub">· 大带宽低价 · 各区域就近</span></div>
|
||
<div class="hop"><span class="n">落地池</span><span class="arrow">→</span><span class="node">3–5 台精品落地节点</span><span class="sub">· 不同解锁特征(Netflix/Disney+ 原生 IP)</span></div>
|
||
<div class="hop"><span class="n">控制面</span><span class="arrow">→</span><span class="node">1 台 API Server(稳定云,可 HA)</span><span class="sub">· MySQL + Redis · 管理所有节点生命周期</span></div>
|
||
<div class="hop"><span class="n">探针</span><span class="arrow">→</span><span class="node">境内多 ISP 拨测节点</span><span class="sub">· 自动判封 → 触发补新 · 详见 §4</span></div>
|
||
</div>
|
||
<div class="role-bar">适合阶段:Phase 2–3 · 千级用户规模 · 需要 Terraform + 多厂商账号体系</div>
|
||
</div>
|
||
|
||
<h3>6.3 各类机器规格与预算参考</h3>
|
||
<div class="tbl-wrap"><table>
|
||
<thead><tr><th>角色</th><th>规格</th><th>厂商画像</th><th>区域</th><th>预算</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>接入点</strong><br><span class="badge data">消耗品</span></td>
|
||
<td>1 vCPU / 512 MB–1 GB / 1 TB 带宽</td>
|
||
<td>冷门小厂 ≥3 家:Vultr / Racknerd / CloudSilk / BuyVM · 支持加密货币</td>
|
||
<td>HK / JP / SG / LA</td>
|
||
<td>$3–6 / 月 · 按小时更佳</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>中转节点</strong><br><span class="badge warn">低频换</span></td>
|
||
<td>1 vCPU / 1 GB / 2–5 TB 带宽</td>
|
||
<td>大带宽便宜厂商:BandwagonHost / Vultr / Hetzner</td>
|
||
<td>JP / SG / 法兰克福</td>
|
||
<td>$5–12 / 月</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>落地节点</strong><br><span class="badge ok">稳定</span></td>
|
||
<td>1 vCPU / 1 GB / 1 TB 带宽 · 原生 IP</td>
|
||
<td>稳定精品厂商:Linode / DigitalOcean / GreenCloudVPS · 原生住宅 IP 优先</td>
|
||
<td>HK / JP / SG · US West</td>
|
||
<td>$6–15 / 月</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>API 控制面</strong><br><span class="badge ctrl">永久</span></td>
|
||
<td>2 vCPU / 2 GB / 40 GB SSD</td>
|
||
<td>最稳定厂商:DigitalOcean / Linode / Hetzner · 不需要靠近中国</td>
|
||
<td>US East / 法兰克福(低延迟不是首要)</td>
|
||
<td>$10–20 / 月</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<h3>6.4 轮换频率策略</h3>
|
||
<div class="tbl-wrap"><table>
|
||
<thead><tr><th>机器角色</th><th>轮换频率</th><th>触发条件</th><th>轮换方式</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>接入点</strong></td>
|
||
<td><span class="badge data">高频</span></td>
|
||
<td>① 被封即换(自动触发)<br>② 主动:每 2–4 周轮换一次,防止 IP 被画像</td>
|
||
<td>厂商 API 自动开新机 → 探活 → 替换旧机 → 删旧机;全程无需手动 SSH</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>中转节点</strong></td>
|
||
<td><span class="badge warn">中频</span></td>
|
||
<td>① 带宽严重限速时<br>② 每季度主动评估</td>
|
||
<td>手动 or 半自动替换;中转 IP 不直面用户,被封概率低</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>落地节点</strong></td>
|
||
<td><span class="badge ctrl">极低频</span></td>
|
||
<td>① 极少数情况被目标网站 ban IP<br>② 解锁需求变化</td>
|
||
<td>手动替换;精品 IP 轮换成本高,需提前备份配置;draining 期 ≥1h</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>API 控制面</strong></td>
|
||
<td><span class="pill ok" style="display:inline-flex;padding:2px 8px"><span class="dot"></span>不轮换</span></td>
|
||
<td>不轮换机器本身,只升级软件版本</td>
|
||
<td>HA 蓝绿部署(API 有状态,MySQL 主从);IP 可绑定 CF Access,不公开暴露</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<div class="callout ok"><b>最重要的轮换原则</b> 接入点是消耗品,被封不是事故而是预期;落地节点是资产,应尽量保护不暴露。<strong>用户看见的 IP = 接入点 IP = 可以随时换掉的</strong>;落地 IP 只在内部隧道中传递,GFW 无法直接观测。</div>
|
||
|
||
<h3>6.5 账号隔离红线(与 EC2 彻底分开)</h3>
|
||
<ul>
|
||
<li>VPN 节点机器用<strong>独立厂商账号</strong>,独立邮箱(一次性或匿名域名邮箱),<strong>加密货币支付</strong>,与 EC2(AWS)账号零关联。</li>
|
||
<li>各厂商账号之间也不产生关联:不使用同一个邮箱、不使用同一张卡、SSH 密钥各账号独立。</li>
|
||
<li>Pangolin VPN 域名(vpn.*.com)与个人 EC2 上的域名(51yanmei.com)<strong>不共用 Cloudflare 账号</strong>——分别使用不同的 Cloudflare 账号,防止账号被封连累。</li>
|
||
<li>API Server、MySQL 的存储不放任何可识别用户真实身份的信息(见 06 章);VPN 节点上零用户库。</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>
|