跳转至

公网入口迁移到 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

statusconsoleapidocs 使用相同的 MM 回源地址:

http://100.64.0.1:39200

MM 宝塔为每个域名创建独立站点和证书,反向代理保持原始 Host,并传递 X-Forwarded-ForX-Forwarded-Proto=httpsX-Forwarded-Hostapiconsole 不启用代理缓存;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 与 Headscale server_urlhttps://mesh.yohan.fun,域名不变,只迁移入口位置;
  • 用 Windows 和 Linux 客户端重启后的控制面同步、tailscale status、DERP 健康状态共同验收。

Mesh 专用边缘服务设计

组件 部署位置 监听 职责
宝塔 Nginx MM 公网 80/tcp443/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 不与普通网站一起切换,必须按以下四阶段执行:

  1. Codex 预部署:构建 GHCR 镜像,在 MM 启动 agentmeshos-derp-edge,持久化 DERP 私钥,放行 39478/udp,只检查 127.0.0.1:39479/derp/probe。此阶段不改 DNS、不改 Headscale DERP Map。
  2. 项目负责人配置宝塔与证书:在 MM 创建 mesh.yohan.fun 站点,先保持基础回源为 http://100.64.0.1:39200,申请证书;证书生效后将 DNS A 记录切至 207.174.28.120。不要设置普通 UDP 转发。
  3. Codex 深度激活:在 MM 站点配置中将 /derp/derp/probe/derp/latency-check 指向 http://127.0.0.1:39479,保留其他路径回源主节点;在主节点发布 MM 的自定义 DERP Map,并关闭主节点嵌入式 DERP 自动发布。
  4. 共同验收:Windows 与 Linux 客户端分别重启 Tailscale,验证 tailscale statustailscale debug derp-maptailscale 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 保持 60sproxy_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.funconsole.yohan.funapi.yohan.fundocs.yohan.funnomad.yohan.funmesh.yohan.fun

HTTPS 跳转策略

所有已经迁移并启用证书的公网域名必须拒绝明文业务访问。

  • statusconsoleapidocs:宝塔“强制 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 例外,再使用:

if ($agentmeshos_https_redirect = 1) {
    return 308 https://$host$request_uri;
}

MM 宝塔填写规则

每个已启用域名都使用:

站点域名:<domain>.yohan.fun
公网监听:80 / 443
反代协议:http
反代地址:100.64.0.1
反代端口:39200

不要把 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。