分层
整条链路只有一件事在流动:把浏览器的一个动作,送到那台具体的电台上,再把结果送回来。 下面六层是这件事在物理上的六个落点。
8888)。CAT/CI-V
控制、双向音频、频谱、以及 PTT 释放的权威。
:8989 → Hub
上属于你的回环端口 188xx。客户侧零入站。
:9988 与
:8899,均为 TLS)。终结 TLS、按 Host
取呼号、查表得端口、按实例名校验上游证书(信任包里钉着
各实例的公钥)、透明转发数据通道。呼号自助注册是另一个
vhost。
www.vlsc.net 的 443 路径入口。标准端口 + 真证书
+ 前缀透明。定位是退化路,不是主路。
每层职责与边界
边界比职责更重要 —— 明确写出"这层不做什么",才能知道该在哪一层找问题。
失效表现:本地页打不开;局域网就 502。
0600,装成常驻服务,带 KeepAlive
失效表现:Hub 侧 502;日志里
start proxy success 消失。
失效表现:未知呼号 →
404(不猜测别的实例);
上游证书与钉住的不符 → 502。
失效表现:
502,
或间歇性无响应(2026-10-01 已复现,见现状一节)。
关键决策
每条决策的价值不在结论,而在当时排除了什么。
| 决策 | 内容 | 为什么不选另一种 |
|---|---|---|
AD-H01实例主动出站 |
客户侧只出站,零入站 | 反过来的"Hub 连进来"需要在每家路由器上做端口映射 —— 家庭宽带做不到,4G/5G 更做不到。 |
AD-H02通配子域 |
一条通配 vhost + 注册表映射 | 每实例一个 vhost 是上一版的做法:加一个实例就要改中心配置, 还要处理正则与前缀的优先级。规模一上来就不可维护。 |
AD-H03控制面 / 数据面分离 |
无状态入口 ×N,有状态隧道网关 ×≥2 | 合成一个进程后,入口的横向扩容会牵着会话归属一起搬 —— 等于把无状态的部分也变成了有状态。 |
AD-H05单写者租约 |
每实例同时最多一个写者 | 允许多写者会让两个人同时按下 PTT。这个冲突在电台侧无法仲裁 —— 电台只知道"有人在发射"。 |
AD-H06PTT 权威在实例本地 |
Hub 只能关流通知,从不写下 PTT | 依赖云端超时释放,意味着云端一断网或一延迟,电台就一直发射。 释放的权威必须和电台在同一台机器上。 |
AD-H07会话凭据不进 URL |
走 Cookie 与握手,不进查询串 | 查询串必然落进代理与实例的访问日志 —— 这个失效模式在本项目早前的形态里真实发生过,不是理论风险。 |
AD-H08监听者语义 |
可听、可看频谱、可调频换模式、禁发射 | 简单做成"只读"会让人没法帮忙找台; 而调频并不改变"谁在发射"这个根本约束,所以放开它没有代价。 |
AD-H15呼号即身份 |
租户名 = 呼号;入口 = 呼号.域名 | 另建一套用户名体系,会把"这是谁家的电台"变成一个要查表的问题, 而它本来是可以从地址里直接读出来的。 |
三条安全不变量
这三条是不能被"优化掉"的。任何实现如果违反它们,就是错的,不管跑得多快。
Hub 与隧道只能发送"关流"这类通知并回收授权, 不得直接下发"切到接收"的指令。多一个写者,就会出现两条互相矛盾的释放路径, 实例侧的仲裁逻辑随之失效。
包括 Hub、实例、以及链路中间任何代理的访问日志。 这一条同时约束前端(不拼查询串)与运维侧(日志格式不得记录查询串)。
每一跳都校验对端证书。关掉它(哪怕"只是为了先跑通") 等于把中间人攻击变成默认配置 —— 而且这类关闭一旦上线, 通常不会有人再回头打开。
现状与目标态
这张表区分"已经跑通"和"设计好了但还没做"。两者不能混着看。
| 能力 | 状态 | 说明 |
|---|---|---|
| 实例出站隧道 | 已跑通 | 阶段 1 用成熟反向隧道验证通路;目标态是内置的实例代理进程 |
| 通配子域接入 + 真证书 | 已跑通 | 一条通配 vhost + 注册表;证书为真发证书,每日自动续期 |
| 数据通道透明转发 | 已跑通 | 五条通道的握手、长连接与关闭语义,与直连一致 |
| 逐跳证书校验 | 已开启 | Hub 到实例这一跳也校验,没有一处是关闭校验换来的 |
| 会话凭据不进 URL | Hub 侧已实现 | Hub 侧日志格式不记查询串(已实测 0 命中);实例侧前端拼串已在 mrrc_modern feat/hub 修复(C2),未合并 main,Stable 渠道仍是旧行为 —— 现状见概览 · 能力现状表 |
| 海外边缘入口 | 间歇可用 | 2026-10-01 实测 6 次中 3 次 20 秒无响应。 已排除本地链路、www 静态服务、www 上另一条代理腿、Hub 侧 SNI/Host 组合; 问题定位在 www → Hub 这一跳,待进一步取证。 |
|
PTT 半开连接释放 (远程会话活性) |
实例侧已有 隧道层待做 | "TCP 还活着但对端已失联"的情形(拔网线、NAT 掉表)。 实例侧已有可开的心跳闸门(默认关闭,Hub 模式建议 3–5 s); 隧道层的主动关流还没做 —— 在此之前释放靠实例本地多层兜底,会慢一些。 |
| 自助注册 Portal(呼号核验四步) | 公网入口已上线 |
代码在 portal/(零第三方依赖,标准库
HTTP),服务为
mrrc-portal.service,本体只绑回环; 对外经
nginx 暴露为
portal.mrrc.vlsc.net:8899 并在该层限流。授予后
gen_hub_routes.py + reload 仍由 root
手执行(有意分工)。
|
| 实例证书链(hub → 实例这一跳的一机一证) | 机制就位 |
make_instance_cert.sh
签一张签给实例自己入口名的自签证书, 公钥钉进
trust-bundle.pem,nginx 按
$mrrc_tls_name 逐实例校验 —— 校验始终开着,
自签靠"钉住它"通过。
现网当前实例尚未迁到这条链(注册表第三列仍为旧的
radio.vlsc.net)。
|
| 实例安装器 | 脚本就位 |
deploy/install_instance_tunnel.{sh,ps1}:自取
frpc 并 校验 SHA-256、与 frps 版本 pin
死、三平台常驻。 仍是仓内脚本,无公开发布的安装包下载。
|
| 一机一证(隧道自身的设备证书) | 阶段 2 | 隧道认证仍是 frp 的单个共享凭证 —— 这是它被定位为过渡通道的原因。 与上面那条证书链是两件事:一个是"谁能接入隧道", 一个是"这台实例是不是它声称的那台"。 |
| 独占写者租约 | 阶段 2 | 现阶段由实例侧仲裁谁在发射 |
| 成员管理与单独撤销 | 阶段 2 | 现阶段只能改监听口令,会影响所有持有它的人 |
边界声明
本页只讲接入层:隧道、入口、路由、证书、身份、边缘。
电台控制、音频编解码、频谱、以及 PTT 安全释放的全部细节, 权威在 MRRC Modern 自己的设计记录里 —— 本页不复制它们, 只定义与它们相邻的接口。
- 要到产品站看 MRRC Modern 的设计与操作指南 → MRRC Modern
-
要看本项目的完整设计记录(需求、用例、决策、风险) →
mrrc_hub 仓库的
SDD/目录 -
实测的运维事实(主机、端口、证书流程、排障) →
SDD/12 §12.8
本页所有事实来自 2026-10-01 对现网实际配置、证书与注册表的现场读取。 如果你发现页面说的和实际不符,是页面该改 —— 欢迎提 issue 指出。
← 回到 概览 ·
照做走一遍
接入四步 ·
遇到问题 排障
本页事实基线:2026-10-01 现场取证(现网 nginx
配置、证书有效期、注册表内容、入口可用性实测)。