foril@blog ~
  __            _ _ 
 / _| ___  _ __(_) |
| |_ / _ \| '__| | |
|  _| (_) | |  | | |
|_|  \___/|_|  |_|_|
// developer & blogger
💻theme: auto
[░░░░░░░░░░░░░░░░░░░░] 0%

2026-03-21-从零构建NEXUS-Gate网关

📅 2026-03-21|⏱ ~7 min read|#开发小记

从零构建 NEXUS Gate:基于 Tailscale + Caddy 的内网穿透与统一认证网关

📅 配置日期:2026-03-21 最后更新:2026-03-21

今天花时间对家里的内网服务进行了一次彻底的“产品化”重构成,把散落在各个端口和配置文件里的内网应用(Porta、Cron-Panel 等),统一整合进了一个极其优雅的自研控制面板 NEXUS Gate。不仅简化了反向代理的操作难度,还彻底解决了手机端 HTTP Basic Auth 反复弹窗输入密码的痛点,实现了真正的 SSO 单点登录

在这里记录下整套防御塔和网关系统的构建逻辑,以此作为未来的灾难恢复与维护手册。


##一、架构概览

整套系统围绕四个核心组件运转:

  1. 真实服务节点 (mini-lan):跑在内网的实体机(Mac Mini),所有的实际业务服务(如下载器、OpenClaw 面板、编辑器联调后台)都在这上面运行。
  2. 安全隧道 (Tailscale):建立 mini-lan 和公网 VPS 之间的点对点加密隧道,让内网节点完全不暴露在公网,又能在局域网内无缝握手。
  3. 公网暴露层 (cc VPS):一台带有公网 IP的服务器环境。它只做一件事——运行 Caddy Web Server 作为流量入口,将公网流量通过 Tailscale 的 100.x.x.x 内网 IP 反代给实际服务。
  4. NEXUS Gate (网关 + 面板):自研的 Node.js 集中式大屏面板,同时它也是 Caddy 的 forward_auth 统一认证授权网关。

##二、核心源码仓库 (备份于 GitHub)

所有跑在这个架构之上的关键业务代码和配置文件均已推送到私有仓库。如果以后需要换电脑或重新部署,请克隆以下仓库:

  1. foriLLL/nexus-gate
    • 作用:基于 React + 毛玻璃 UI 的核心管理前端,以及接收 HTTP/REST 请求用于操控 Caddyfile、签发 Auth Cookie 分布式身份牌的 Node.js 后端。
  2. foriLLL/porta-custom
    • 作用:基于 Vite 的前端项目,用于 PWA 远程控制 Antigravity IDE 实例。包含专门定制好的跨域放行逻辑。
  3. foriLLL/cron-panel-custom
    • 作用:OpenClaw 管理面板后端。

##三、灾备恢复:如何在一台全新服务器上拉起这一套?

假设主运行环境 (cc) 或边缘节点崩溃了,可以通过如下 4 步在全新的 VPS 上重建光复:

1. 基础环境准备

新机器必须装有 Node.js (v20+), PM2 控制台进程管理器以及 Caddy 运行环境。建议直接使用 nvm 安装:

bash
# 安装 nvm 和 Node.js curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install --lts # 安装 PM2 进程管家 npm install -g pm2

2. 配置主 Caddyfile 与公共 DNS 服务

  • 去 Cloudflare 添加一条 泛解析 A 记录(如 *.foril.site),全部指向你的 VPS 服务器 IP。代理状态设为“仅 DNS(灰云)”。
  • 在 VPS 覆写主 Caddy 配置文件 (/etc/caddy/Caddyfile):
caddy
{ servers { protocols h1 h2 } } # 这里是精髓:完全不碰具体的业务配置,全部下放引流到外部自定义目录 import /etc/caddy/nexus_configs/*.caddy

3. 克隆 NEXUS Gate 与自动化构建

执行仓库内的 install.sh 安装脚本,一键完成文件赋权和 pm2 守护装载:

bash
git clone git@github.com:foriLLL/nexus-gate.git cd nexus-gate bash install.sh

该脚本采用 Caddy Admin API (localhost:2019/load) 发起 无需 sudo 级别的热重载,对整个系统权限的介入降到最低。

4.自举 (Bootstrap) 暴露大门

部署完毕后,面板此时只在内部 127.0.0.1:3001 生效。

  1. 在本地机器打开终端挂靠本地回环:ssh -L 3001:127.0.0.1:3001 cc
  2. 本地打开浏览器 http://localhost:3001 进入内网安全控制台视角。
  3. 点击「Add Target」,输入想对外公开的内网大门入口(如:caddy.foril.site),目标填写 127.0.0.1:3001,并且必定勾选【Auth Protection 加密】
  4. 点击 Deploy 即可。之后就可以关闭终端 SSH 的临时引流,直接以公网加密模式访问面板本体。

##四、技术拆解:Forward Auth 统一认证是怎样完成单点登录的?

以往配置 basic_auth 时,每个独立的独立站点都有隔离的 401 安全层。如果内网有 10 个子门户,你需要在每台手机、每一款 APP 上反反复复地输入用户名密码,极度降低体验。更严重的是,现代手机(特别是移动端 PWA APP 容器)经常吃掉或拒绝缓存基础的 Authorization 附带层,从而导致浏览器抽风式无限弹窗。

破局方案:NEXUS Gate + Caddy Forward Auth。

带有密码保护的安全站点,在生成时会被自动注入如下反代配置:

caddy
apps.foril.site { # 白名单匹配器,避开验证请求引发反复横跳死循环 @auth not path /auth/* /assets/* # 将实际的校验业务外包转交给网关去判断 forward_auth @auth 127.0.0.1:3001 { uri /auth/check copy_headers X-Auth-User } reverse_proxy 100.x.x.x:9999 }
  1. 工作原理: 每当有访客访问 apps.foril.site,Caddy 这个门神由于受到 forward_auth 指令,会瞬间挂起这个公网请求,并去默默敲一下在 127.0.0.1:3001 监听着的 NEXUS Gate,问一句:“这兄弟带了我们发放的隐性 Cookie 没有?”
  2. 拦截回跳: 若未找到/失效 Cookie,网关接口返回 302 Found 带着回迁回调 URI 跳转参数,强制把页面踢入带有毛玻璃全特效的主验证网关页(caddy.foril.site/auth/login)。
  3. 一处签证,全域名通行: 一旦登录成功,网签授权系统就会在顶级的 .foril.site Domain 上种下为期一个月的授权 Cookie。由于所有的子应用如 porta.foril.siteclaw.foril.site 都在该广义域名下,浏览器便会自动透传这枚令牌。
  4. 结局: 实现了无痛级别的 SSO (Single Sign-On 最大级别整合与单点登录化),一地注册,各处秒开!

##五、日常操作手册:如何上架一个全新的本地内网服务?

在有这套系统扶持后,所有的操作被简化为傻瓜两步:

  1. 启动服务跑在内网: 在 mini-lan 家用主机上启动任意应用。可以用 pm2 脚本,也可以直接起 Docker,确保其占用了一个局域网有效端口(例 3000)。
  2. 面板可视化签发通行证: 用任意设备打开 https://caddy.foril.site,登录网关界面,点击 Add Target。在 Domain 里直接填入你刚想好的子域名,在 Target 里把你的 100.x.x.x:3000 IP 送入其中。勾选或取消 Auth 安全开关,接着按下 Deploy

系统将在 0.5 秒内通过 Caddy Admin API 热推 Caddyfile 的结构,自动完成 DNS 和 TLS/SSL 证书的轮换申请,网站随即便在全球互联上线可用。

$ tree --headings