公网入口迁移到 MM
本页定义 AgentMeshOS 将公网域名入口从主节点迁移到 agentmeshos-worker-mm 的实施规则。MM 负责公网 80/443、TLS 证书和域名路由;主节点继续承载全部应用、控制面和数据。
目标拓扑
客户端
-> DNS: <domain> = 207.174.28.120 (MM)
-> HTTPS: MM 宝塔 Nginx :443
-> Tailnet: 100.64.0.6 -> 100.64.0.1:39200
-> 主节点私有回源网关
-> 127.0.0.1:<应用原端口> 或 Nomad TLS :39046
DNS 记录只填写 MM 公网 IP 207.174.28.120,不填写端口。用户访问始终使用 https://<domain>:443;回源端口只在 MM 宝塔反向代理配置中使用。
当前全部端口、协议、绑定地址和暴露边界统一记录在 端口与服务映射。本页只维护 MM 迁移流程和特殊反代要求,不再把内部端口当成用户访问入口。
主节点私有网关只监听 100.64.0.1:39200,并只允许 MM 100.64.0.6 访问。它保留各服务现有的 127.0.0.1 本地监听,避免为了迁移逐个扩大服务暴露面。
域名映射表
| 域名 | DNS A 记录 | MM 基础回源 | 类型 | 迁移要求 |
|---|---|---|---|---|
status.yohan.fun |
207.174.28.120 |
http://100.64.0.1:39200 |
标准 HTTP | 保留 Host、X-Forwarded-* 和健康检查 |
console.yohan.fun |
207.174.28.120 |
http://100.64.0.1:39200 |
标准 HTTP | 保留 Host、X-Forwarded-* 和健康检查;站点反代必须 proxy_cache off |
api.yohan.fun |
207.174.28.120 |
http://100.64.0.1:39200 |
HTTP API | 禁止缓存;保留 Host、X-Forwarded-* |
docs.yohan.fun |
207.174.28.120 |
http://100.64.0.1:39200 |
文档与脚本下载 | 验证首页、脚本下载与 SHA-256 |
nomad.yohan.fun |
207.174.28.120 |
http://100.64.0.1:39200 |
Nomad HTTPS UI | 保留 WebSocket、长超时、ACL;主节点网关校验 Nomad CA |
mesh.yohan.fun |
207.174.28.120 |
http://100.64.0.1:39200 |
Headscale / Headplane / DERP | 保留完整路径、升级连接、长超时;MM 另需专用 DERP/STUN 服务 |
auth.yohan.fun |
207.174.28.120 |
http://100.64.0.1:39200 |
认证入口 | 已启用;主节点 A-Auth 后端监听 127.0.0.1:39150,MM 必须保留 Host 与 X-Forwarded-* |
www.yohan.fun |
暂不切换 | 预留 127.0.0.1:39100 |
项目官网 | 公开阶段启用 |
哪些可以直接反代
第一批:标准 HTTP
status、console、api 和 docs 使用相同的 MM 回源地址:
MM 宝塔为每个域名创建独立站点和证书,反向代理保持原始 Host,并传递 X-Forwarded-For、X-Forwarded-Proto=https、X-Forwarded-Host。api 和 console 不启用代理缓存;Console 的首页携带版本化静态脚本,边缘缓存旧首页会使已登录用户长期加载旧工作台。docs 切换后必须验证下载脚本与仓库哈希一致。
私有回源网关不得把 39200 写入任何公网 Location 响应。mesh.yohan.fun 根路径由主节点返回相对跳转 /admin/;MM 同时配置 proxy_redirect http://mesh.yohan.fun:39200/ https://mesh.yohan.fun/; 作为边缘保护,避免内部 HTTP 回源协议和端口出现在浏览器地址栏。验收时必须使用带随机查询参数的未缓存请求检查 Location,不能只验证已缓存的首页响应。
Cloudreve 系统云盘数据面
cloud.yohan.fun 是当前系统云盘入口:客户端或 WebDAV 客户端经 MM 的 BaoTa Nginx 公网 HTTPS 直接到 dd Cloudreve。该数据面不经过主节点私有回源网关、101/103、Nomad 或 Tailnet;Tailnet 只保留控制、SSH、调度和健康检查用途。
Cloudreve 当前部署、反代和容量策略保持现状。任何未来调整必须先在公网完成上传、下载和校验验证,并明确回滚方案;不得把旧 disk.yohan.fun、KodBox 或中间文件系统重新接入。
第二批:Nomad UI
nomad.yohan.fun 仍从 MM 回源到私有网关,但不能按匿名静态站点处理。必须保留:
- 浏览器携带的 Nomad ACL Token;
- WebSocket 和 HTTP/1.1 Upgrade;
- 长连接读取超时;
X-Forwarded-Proto=https;- 主节点到 Nomad
https://100.64.0.1:39046的 CA 校验。
第三批:Headscale 控制面
mesh.yohan.fun 同时承载 Headscale 协议、Headplane /admin/ 和嵌入式 DERP。MM 的普通 HTTPS 反代必须保持请求路径,不能把 Headscale 请求重写到 /admin/。
此外还必须完成:
- 不使用普通 Nginx UDP 代理转发 STUN。它会隐藏客户端真实公网地址,导致 STUN 映射结果错误;MM 必须运行专用、保留 STUN 语义的 DERP/STUN 服务;
- MM 上的
derper容器固定监听127.0.0.1:39479/tcp和公网39478/udp;宝塔只将/derp路径反代到本机39479,STUN UDP 由容器直接处理; - MM 为 DERP 关闭响应缓冲并保留连接升级与长超时;
- 主节点 Headscale 将 MM
100.64.0.6加入trusted_proxies; - Headplane 保持
base_url与 Headscaleserver_url为https://mesh.yohan.fun,域名不变,只迁移入口位置; - 用 Windows 和 Linux 客户端重启后的控制面同步、
tailscale status、DERP 健康状态共同验收。
Mesh 专用边缘服务设计
| 组件 | 部署位置 | 监听 | 职责 |
|---|---|---|---|
| 宝塔 Nginx | MM | 公网 80/tcp、443/tcp |
TLS、ACME、Headscale / Headplane 私有回源、/derp 路径反代 |
agentmeshos-derp-edge |
MM Docker | 127.0.0.1:39479/tcp、公网 39478/udp |
DERP TCP 中继、STUN NAT 探测、客户端身份校验 |
| 主节点私有回源网关 | 主节点 | 100.64.0.1:39200/tcp |
把非 DERP 的 mesh 路径路由到 Headscale 和 Headplane |
| Headscale | 主节点 | 127.0.0.1:39088/tcp |
控制面与 /verify 客户端准入接口,发布 MM DERP Map |
采用官方 derper 源码的固定版本 Docker 包装,而非第三方镜像或主节点 UDP 转发。它可与当前 Tailscale 客户端版本保持一致、镜像可追溯,并使 STUN 的公网响应直接从 MM 发出。
derper 使用 -verify-client-url=https://mesh.yohan.fun/verify 和 -verify-client-url-fail-open=false。未知客户端或 Headscale 验证不可达时都不能使用中继。迁移前该 URL 指向主节点;迁移后它经 MM 私有回源到主节点,因此 Headscale 域名保持不变。
Mesh 切流步骤
mesh 不与普通网站一起切换,必须按以下四阶段执行:
- Codex 预部署:构建 GHCR 镜像,在 MM 启动
agentmeshos-derp-edge,持久化 DERP 私钥,放行39478/udp,只检查127.0.0.1:39479/derp/probe。此阶段不改 DNS、不改 Headscale DERP Map。 - 项目负责人配置宝塔与证书:在 MM 创建
mesh.yohan.fun站点,先保持基础回源为http://100.64.0.1:39200,申请证书;证书生效后将 DNS A 记录切至207.174.28.120。不要设置普通 UDP 转发。 - Codex 深度激活:在 MM 站点配置中将
/derp、/derp/probe、/derp/latency-check指向http://127.0.0.1:39479,保留其他路径回源主节点;在主节点发布 MM 的自定义 DERP Map,并关闭主节点嵌入式 DERP 自动发布。 - 共同验收:Windows 与 Linux 客户端分别重启 Tailscale,验证
tailscale status、tailscale debug derp-map、tailscale debug derp agentmeshos-mm、新节点注册、Headplane 登录和mesh.yohan.fun/health。通过观察期后,才删除主节点旧公网mesh反代。
Headscale 的 systemctl reload headscale 只重载 ACL 策略,不会重新加载 DERP 配置。DERP Map、嵌入式 DERP 开关或 STUN 监听变更必须先通过 headscale configtest,再使用 systemctl restart headscale;该操作会造成数秒控制面重连,但不影响 SSH、MM 容器或既有 Tailnet 接口。
第三阶段的 MM 宝塔路径规则由 Codex 修改,核心结构如下。证书和 server 块仍由宝塔管理:
location ^~ /derp {
proxy_pass http://127.0.0.1:39479;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
这里的 3600s 是 代理响应超时时间(Nginx proxy_read_timeout),用于保持 DERP 的长期中继连接;它不是 TCP 连接超时。proxy_connect_timeout 保持 60s,proxy_send_timeout 同样设为 3600s。
分工与切流顺序
| 工作 | 负责人 |
|---|---|
| 主节点私有回源网关、Tailnet 防护、Nomad CA 回源、Headscale 信任代理 | Codex |
| MM 宝塔站点、证书、基础反向代理 | 项目负责人 |
| DNS A 记录切换 | 项目负责人 |
| MM 的 DERP/STUN 容器、宝塔深度路径配置、Headscale DERP Map | Codex |
| 每次切流后的回源、公网、浏览器与客户端验收 | Codex |
固定顺序:status -> console -> api -> docs -> nomad -> mesh。
每个域名切换前,先将 DNS TTL 调低,并确认 MM 证书和回源已就绪。切换后只验证当前域名;通过后才继续下一个。失败时将该域名 A 记录恢复到主节点 96.44.133.235,主节点原站点在观察期内保留以支持回滚。
当前已完成迁移:status.yohan.fun、console.yohan.fun、api.yohan.fun、docs.yohan.fun、nomad.yohan.fun 和 mesh.yohan.fun。
HTTPS 跳转策略
所有已经迁移并启用证书的公网域名必须拒绝明文业务访问。
status、console、api、docs:宝塔“强制 HTTPS”产生的301跳转可继续使用;当前 API Gateway 为只读接口。nomad:使用308跳转,确保未来带请求体的方法不会被改写为GET。同时保留/.well-known/acme-challenge/的 HTTP 访问,以支持证书续期。mesh:已在 Headscale、Headplane、DERP 和 Worker 验收后启用308跳转,并保留/.well-known/acme-challenge/的 HTTP 例外。
宝塔面板没有 301 / 308 状态码选择项。需要 308 时,在对应站点配置中保留原有 ACME 例外,再使用:
MM 宝塔填写规则
每个已启用域名都使用:
不要把 MM 回源写成主节点公网 IP 96.44.133.235,也不要把 DNS 解析到 100.64.0.1。前者会绕过迁移目标并形成公网链路依赖,后者是 Tailnet 私有地址,公网 DNS 无法使用。
验收与回滚
- MM 上验证
Host对应的私有回源返回预期页面或健康状态。 - DNS 切换后从公网验证 HTTPS 证书、页面正文和业务接口。
- 文档站额外比较线上
/scripts/文件与仓库源文件的 SHA-256。 - Nomad 验证 UI 登录、只读 ACL、WebSocket 和
https://nomad.yohan.fun/ui/。 - Mesh 验证
/health、Headplane 登录、新客户端注册、客户端重启后的控制面同步和 DERP。 - 当前 MM DERP Map 只发布
agentmeshos-mm一个 IPv4 区域;tailscale debug derp会提示单区域单点风险,且无 AAAA 记录时 IPv6 探针会显示预期错误。后续增加第二个独立 DERP 区域或 IPv6 前,不将这些提示误判为本次 IPv4 迁移失败。 - 失败时仅回退当前域名 DNS;不删除主节点服务、不重置 Tailnet、不修改 SSH。