一键安装与日常维护
新原生 Linux 服务器使用下面的已核验入口。先核对发布者提供的脚本 SHA256 与发行公钥指纹;安装脚本会选择面板或 Agent、识别架构并获取匹配的签名发行包。服务器不需要访问 GitHub。
复制一行,按提示安装
只有运营者配置真实 HTTPS 发布地址和 SHA256 后,上方按钮才启用。命令先下载到私有临时目录,只接受 HTTP 200 且不跟随跳转;SHA256 校验通过后运行。root 用户直接执行,其余用户使用 sudo。需要 Bash、curl、sha256sum;后续签名安装还需 Python 3、OpenSSL、systemd 等依赖。
安装入口无参数运行,交互选择 panel 或 agent,默认使用兼容的 latest。下载 Token 与 Agent Token 按提示隐藏输入;不要把秘密放在网页配置、URL 或命令历史。软件许可证在面板安装完成后登录管理页面激活,不在安装命令中激活。
装好后,输入 halo
sudo halo
sudo halo-manage 是同一维护入口。中文菜单提供状态、启停、更新、回退与卸载;在已安装组件的对应服务器执行。已经是 root 时可省略 sudo。
sudo halo update panel latest sudo halo update agent 0.6.1 sudo halo rollback panel 0.6.0 sudo halo uninstall agent
升级版本可填 latest、指定 x.y.z,或省略版本使用 latest;版本必须真实存在、签名有效且兼容。回退只使用本机保留的兼容历史,不恢复旧数据库。卸载先显示计划,再要求在本机确认,默认保留数据、配置和证书。先迁移转发业务,再卸载入口、出口或面板。
halo 不会直接接管其容器、目录或数据。继续使用该部署自己的 Compose 和固定镜像摘要更新;迁移到原生需单独备份、迁移及验收。发布域名尚未购买配置,上方无可执行公网命令,也尚未完成“官网复制 → 公网安装 → 升级回退”的端到端验收。01 · 准备服务器
面板建议 2 核 / 2 GB / 20 GB SSD,Agent 小流量建议至少 1 核 / 1 GB。预留日志、备份及多个程序版本所需空间;这些是起步建议,吞吐和并发上限需要压测。
操作系统与依赖
- Linux x64 或 arm64。新机优先以 Debian 13 或 Ubuntu 24.04 LTS 联调;Debian 12 与 Ubuntu 22.04 LTS 可按依赖核对。
- Ubuntu 26.04 LTS 为候选兼容目标;Linux 发行版兼容性尚未逐项验收。macOS 程序不能安装到 Linux。
- 手动面板需要 Node.js 24 LTS,Rust Agent 需要匹配架构与 libc 的程序。离线安装包可携带运行环境,无需目标机编译。
- Docker 方式需要 Docker Engine 与 Compose v2。SQLite 默认;使用 MySQL 时选择 MySQL 8.4 LTS,并保留独立数据目录。
- 签名初装需要 Bash、Python 3、OpenSSL(支持 Ed25519)、systemd 与系统 CA 证书;下载/校验工具按离线包准备。
- nftables / iptables / realm、ICMP Ping 为可选能力,按目标系统安装对应工具与权限。
网络、域名与端口
面板用自己的 HTTPS 域名对外提供服务;9810 默认只监听回环地址,由反向代理转发。入口监听端口只按规则放行;出口 TLS 隧道端口只向入口开放。3X-UI 管理接口只向面板开放,落地业务端口优先只向你的出口开放。数据库不必开放公网端口。云安全组与本机防火墙需要分别核对。
02 · 安装控制面板
推荐 Docker 部署面板、systemd 部署 Agent。客户从维护者取得已核验的运行包或签名镜像,无需访问私有 GitHub 源码。商业发行包还需固定许可证服务、公钥与 HTTPS 面板域名,再在管理员界面激活;没有有效许可时管理界面可用,转发暂停。详见下方“商业域名授权”。标注“源码”的方式只供有仓库权限的维护者;首次安装拒绝覆盖已有目录,已有服务器按更新流程处理。
Docker 运行包:默认 SQLite
先导入维护者提供的镜像,核对 HALO_PANEL_IMAGE 为已提供的真实镜像。在面板运行包目录准备权限 600 的 .env,设置首次管理员密码(至少 12 位)、PANEL_URL 为真实 HTTPS 域名;使用反向代理提供证书。
docker compose up -d --no-build
包内 Compose 保留 panel-data 数据卷。首次管理员密码仅用于初始化,已存在数据库时不会覆盖旧账号。
Docker 运行包:MySQL 8.4
.env 另外设置 MYSQL_DATABASE、MYSQL_USER、MYSQL_PASSWORD 与一个不同的 MYSQL_ROOT_PASSWORD。数据库没有映射公网端口。
docker compose -f compose.yaml -f compose.mysql.yaml up -d --no-build
更新时保留 panel-data 与 mysql-data。不要通过删除数据卷解决升级问题。
维护者源码试运行:先在回环地址验证
仅在有权访问的私有面板源码目录运行。安装 Node.js 24 后,使用随源码提供的依赖包,无需 npm 联网;客户生产安装使用签名发行包和独立环境文件。
bash deploy/install-node-dependencies.sh node --version read -r -s -p '首次管理员密码(至少 12 位):' HALO_ADMIN_PASSWORD export ADMIN_USERNAME=admin ADMIN_PASSWORD="$HALO_ADMIN_PASSWORD" export HOST=127.0.0.1 PORT=9810 PANEL_URL=http://127.0.0.1:9810 node server/main.mjs
上面的交互命令使用 Bash。服务模板为 deploy/halo-panel.service,配置模板为 deploy/panel.env.example。公网 HTTPS 启用后修改 PANEL_URL 与安全 Cookie 设置。
离线部署与“一键”安装
先由联网 Linux 构建机制作与目标架构匹配的完整运行安装包,再把校验值与压缩包上传到目标机。校验后运行安装器,会创建服务目录和服务账号。没有签名 Linux 发布包时,页面不会展示一个伪造的公网安装地址。
sha256sum -c halo-forward-linux-offline.tar.gz.sha256 mkdir halo-offline tar -xzf halo-forward-linux-offline.tar.gz -C halo-offline sudo bash halo-offline/install-offline.sh
目标服务器不需要访问 GitHub。Docker 离线包还需目标机已有 Docker 与 Compose v2,导入镜像后按安装器输出的命令启动。升级与首次安装使用不同流程,首次离线安装器拒绝覆盖已有 /opt/halo-forward。
sudo bash ./install-release.sh --bundle ./halo-forward-panel-0.6.1-linux-x64.tar.gz --manifest ./manifest.json --public-key ./release-public.pem --component panel --manifest-url https://你的发布域名/releases/manifest.json
上例要求真实签名包已制作并上传;文件名、架构与域名须替换为实际值。安装器一次安装一个组件,已有部署不要重复覆盖。
03 · 部署入口与出口 Agent
分别添加服务器与接入令牌
- 在“服务器节点”创建入口和出口,分别填写真实地址与角色;每个节点使用独立 Agent Token。
- 上传目标 Linux 架构的 Rust Agent、systemd 模板与配置文件。令牌放在仅服务账号可读的文件中。
- 出口配置 TLS 证书、私钥、隧道监听地址和入口允许使用的密钥;入口配置对应的出口地址。
- 按安装包实际说明启动 Agent,验证心跳、角色与核心版本上报。入口与出口可以在同机分别配置,或使用双角色。
- 建立“入口 → TLS 隧道 → 出口 → 目标”的测试规则,使用真实 TCP / UDP 客户端连接,核对双向返回、用量与日志。
Agent 签名安装
在该 Agent 服务器准备匹配 Linux 架构的真实发布包、可信安装脚本、签名清单和发布公钥。以下以 x64 为例,版本、文件名与域名须换成实际发布资产:
sudo bash ./install-release.sh --bundle ./halo-forward-agent-0.6.1-linux-x64.tar.gz --manifest ./manifest.json --public-key ./release-public.pem --component agent --manifest-url https://你的发布域名/releases/manifest.json
安装器一次初始化一个组件,不覆盖已有 /opt/halo-forward。完成后编辑 /etc/halo-forward/agent.env,配置面板地址、该节点独立令牌、角色与证书;出口或双角色还须让服务启动命令带 --exit。令牌推荐由 AGENT_TOKEN_FILE 读取;不要写入命令历史。配置完成后启动系统服务:
sudo systemctl enable --now halo-agent.service sudo systemctl status halo-agent.service sudo journalctl -u halo-agent.service -n 100 --no-pager
核对心跳、真实核心版本与 software_license_lease_v1 许可能力,再测试业务连接。商业面板遇到缺少许可能力的旧 Agent 会暂停该节点转发,升级到 0.6.0 或兼容后续版本后再接入。已有同机面板部署时先按部署指南完成迁移或组件接入。
也可用 Docker 运行 Agent
提供 Linux 主机网络的 compose.agent.yaml 与 deploy/agent.docker.env.example。先准备真实 agent.env 和 agent-secrets 中的令牌 / 出口证书;镜像须已导入、下载,或在联网构建机通过 Dockerfile.agent 构建。
cp deploy/agent.docker.env.example agent.env chmod 600 agent.env # 编辑 agent.env,上传实际令牌/证书后执行 sudo chown -R 10001:10001 agent-secrets sudo chmod 700 agent-secrets sudo chmod 400 agent-secrets/* docker compose -f compose.agent.yaml up -d --no-build
容器以 UID/GID 10001 运行,秘密文件只允许该身份读取。出口 / 双角色取消 Compose 的 command: ["--exit"] 注释,并填写 TUNNEL_CERT_FILE、TUNNEL_KEY_FILE 与 TUNNEL_LISTEN。Docker Agent 不运行 root 原生更新器,HALO_UPDATE_ENABLED=0;更新与回退通过签名镜像 SSH 命令重建容器。
TLS 服务器名称与 CA PEM 是什么?
TLS 服务器名称是入口拿来核对出口证书的名字,必须匹配出口证书的 SAN。它可以是你控制的出口域名,不能随便填写别人的域名。
出口证书 CA PEM是签发出口证书的可信 CA 公钥证书,文本通常以 BEGIN CERTIFICATE 开头。入口用它验证出口身份;出口证书私钥只留在出口服务器。使用私有 CA 时把 CA 的公开证书交给入口;不要复制出口私钥到面板字段。
04 · 接入多个 3X-UI 落地
最多接入 32 个独立 3X-UI 2.9.4 面板,每台分别填写根地址、管理账号、凭据与公网地址。不会把所有落地强制放到一台服务器。
- 在“授权与集成 → 多个 3X-UI 落地服务器”选择“添加落地服务器”。地址包含你自己的面板登录路径。
- 逐台测试连接,再点击某台服务器的“在此服务器创建落地”;创建窗口也可切换所属服务器。
- 选择客户、监听端口、REALITY 目标、上游地址、流量额度与期限。接口失败或超时时先核对上游结果,避免重复创建。
- 创建成功后可“复制节点”,或“创建入口规则”,让客户通过你的 Rust 入口连接落地。
- 按所属服务器筛选落地列表,检查入口链路、客户端握手及流量额度实际生效。
3X-UI / Xray 额度与 HaloRelay 套餐独立。限制落地端口只允许你的出口访问,才能让流量经过 HaloRelay 转发计费。HaloRelay 版本更新不会代替第三方 3X-UI 升级。
05 · 开通客户与套餐
- 创建邀请码,设置有效期、使用次数、可用节点与规则数量;邀请码仅显示一次,私下交给客户。
- 客户注册并登录后下单;管理员核实人工收款,确认订单并开通订阅。
- 在账号或套餐设置节点授权、端口与目标范围,选择单向 / 双向口径与倍率。
- 每条转发规则的操作按钮可查看 IP 数量、并发数、限速及访问日志。来源 IP 限制与账号单会话登录是两种独立设置。
- 单会话登录打开后,新登录使旧会话失效;多个标签页共享同一浏览器会话,不能用来识别物理设备。
06 · 探针、日志与异常提醒
“链路探测”查看最近时间窗口的延迟与可用性;TCP 显示建连失败率,只有 ICMP 显示网络丢包率。机器探针和规则计费统计口径不同。
在“授权与集成”创建公开探针链接,选择要展示的节点和失效时间。持链接的人无需登录,但看不到服务器 IP、客户规则和访问日志;随时可以撤销。
管理员配置 SMTP 或 Telegram 通道,管理员与客户在“我的账号与提醒”各自填写收件人并发送测试提醒。测试加入队列不等于已送达,应查看投递结果。
在“部署与设置”设置自动保留天数与日志上限,也可手动清理日志。清理不会重置累计计费。SQLite 整理可以回收空闲页;MySQL 统计更新不会缩小磁盘文件。
07 · 备份与恢复
管理员下载“数据库与外观备份”,另外保存 integration-key、Agent Token、隧道私钥、系统服务配置、DATA_DIR/releases、/etc/halo-forward/release.json 与发布公钥。通用业务数据库下载不包含发布源配置、缓存与更新任务。另独立保存许可配置 /etc/halo-forward/license.json 和 DATA_DIR/software-license/state.json;许可状态包含激活码与实例身份,普通业务数据库导出不能替代它。备份包含敏感数据,应保存在受控位置。
恢复时选择本面板导出的文件,输入当前管理员密码并确认。系统先保存恢复前的回滚副本,再替换数据库;完成后所有用户重新登录。跨机恢复需同时恢复集成密钥,或重新填写 SMTP、Telegram、3X-UI 凭据。
不要把程序回退和数据库恢复混为一谈。恢复旧备份会丢失备份之后的订单、规则和计费变化,必须事先确认时间点并保管当前副本。
08 · 发布、在线更新与回退
面板控制台、接口与资源随面板版本整体切换。此介绍站独立部署、独立更新,不包含在面板签名包中;Agent 与第三方 3X-UI 版本也独立维护。
先建立可信发布源与主机更新器
管理员在“版本与更新”配置真实 HTTPS 清单 URL、Ed25519 公钥与部署方式。服务器首次安装时固定发布信任;公钥须通过可信渠道核对,网页填写不能代替服务器上的主机信任。
控制面约每 15 分钟检查签名清单,网页每 10 秒刷新状态。检查只提示可用版本,不自动切换。原生更新器启用并获授权后可在线提交任务,也可复制 SSH 命令;Docker 使用签名镜像命令。halorelay.com 已购买,下载站规划为 dl.halorelay.com;必须先构建并上传资产、配置 HTTPS,示例地址不能直接用来安装。
sudo halofctl status sudo halofctl capabilities
面板更新:先备份,再选择版本
下载数据库备份,另存集成密钥、配置、发布信任与证书。选择签名清单中兼容的新版本,在线提交或把命令复制到面板服务器 SSH。下例适用于已有较低版本且发布源包含 0.6.1 的原生面板:
sudo halofctl update panel 0.6.1
更新器先备份业务数据,再切换程序;健康检查失败会恢复旧程序。排队、下发与最终执行成功是不同状态。面板重启短暂断开,恢复后查看最终任务状态。Docker 面板使用页面生成的签名镜像摘要命令,固定 HALO_PANEL_IMAGE 后重新创建 Compose 容器并保留数据卷;不能使用原生 halofctl 替换容器。
Agent 更新:先一台,再逐台
复制命令到所选 Agent 对应服务器。原生 Agent 在线、更新器启用且获授权后可接受在线任务;Docker Agent 使用签名镜像 SSH 命令。先更新备用入口或出口,核对版本心跳及真实链路,再逐台更新:
sudo halofctl update agent 0.6.1
更新可能断开业务连接。无需改变核心时可只更新面板;有最低核心版本要求时按签名清单核对兼容性。普通组件更新不会自动改写固定 root 工具、发布公钥或服务器授权配置。
回退:保留旧程序并核对数据格式
在本机历史列表选择已保留、通过摘要校验且与当前数据格式兼容的版本。商业授权发行基线为 0.6.0,只回退到仍具备授权能力的已验证版本。下例用于未来本机当前版本高于 0.6.0 且已保留兼容的 0.6.0 资产;当前就在该版本时无需执行:
sudo halofctl rollback panel 0.6.0 sudo halofctl rollback agent 0.6.0
程序回退不会恢复旧数据库;数据格式不兼容时运行器拒绝切换,应按备份恢复方案处理。不能把回退到 0.6.0 以前的无授权旧版作为商业维护方案。旧 Agent 没有许可能力时,商业面板暂停向它下发转发规则,须升级后再接入。Docker 用保留的签名镜像摘要重建容器,保留 panel-data、mysql-data 和 Agent 秘密挂载。
09 · 卸载面板与 Agent
0.6.0 初装包含 halofctl 1.2.0。先查看计划,再在要卸载的那台 Linux 服务器执行。删除面板节点记录与卸载服务器程序是两件事。旧签名安装先按下节刷新已验证的固定 root 工具;工具因活动任务、安全检查或恢复记录拒绝时,独立脚本不会绕过。
原生面板:保留数据库、配置和同机 Agent
sudo halofctl uninstall panel --dry-run sudo halofctl uninstall panel
停止并移除本机面板服务、current-panel 链接及全部历史面板程序。保留数据库、日志、账户、集成密钥、备份、panel.env、管理员密码、证书及同机 Agent;没有删除面板业务数据的 purge 选项。传统手动布局仅删除明确的 server、web、node_modules 和包清单,保留共享 runtime、tools、deploy 与 data。
保留 Agent 服务不等于业务不中断:控制面不可用后,Agent 默认在 90 秒控制租约到期时停止转发。迁移或卸载面板前准备并验证替代控制面。业务目录或配置的密钥位于待删程序内,或存在跨服务停机关系、自定义 unit 时,自动卸载拒绝;先核对并迁移配置。
原生 Agent:保留令牌、证书及面板数据
先停止向该入口或出口分配规则,验证备用节点,再到该 Agent 服务器执行:
sudo halofctl uninstall agent --dry-run sudo halofctl uninstall agent
停止并移除 Agent 服务、current-agent 链接、历史 Agent 程序和旧式二进制。默认保留 Agent 配置、令牌和证书,不删除面板数据库;同机面板及其历史程序保留。远端面板节点记录不会自动删除,需另行撤销令牌并移除记录。
需要清理标准 Agent 配置时才使用:
sudo halofctl uninstall agent --purge-agent-config
只额外删除 /etc/halo-forward/agent.env、agent-token、agent-token.txt,不沿环境变量继续删除自定义令牌、共享 CA、证书或私钥。
中断恢复与共享更新器
卸载与升级共用锁,存在未完成更新或另一组件恢复日志时拒绝并发。卸载中断后重跑同一卸载命令恢复;运行器也可处理原生卸载恢复日志。撤销对应组件更新授权,取消晚到的该组件更新;同机另一组件程序、授权与任务保留。没有剩余组件时停用更新定时器,仍保留固定管理工具和发布信任。
归档只保存路径、摘要与执行元数据,未保存令牌、私钥或数据库,不是完整重装备份。重装须另行核验程序、配置和授权。
旧签名安装:手工刷新固定 root 工具到 1.2.0
程序升级与固定 root 工具维护分开。先用原签名运行器把本机已有的 panel 或 agent 更新到 0.6.0,核对包签名、SHA256、已安装文件及 root 所有权。不能用任意源码解压目录代替已验证发行资产。下列流程只适用于标准 /opt/halo-forward、/etc/halo-forward 和 /var/lib/halo-forward-update 布局。
- 记录 halo-updater.timer 原来的启用与运行状态,停止定时器:
sudo systemctl stop halo-updater.timer。 - 确认 halo-updater.service 未运行、其他 SSH 没有 halofctl 进程,spool 内没有更新锁、pending_activation、卸载恢复日志或未完成任务。存在活动时停止维护,不替换文件。
- 把 updater/tools、updater/server、updater/deploy 及现有更新服务 / timer 模板备份到 root 0700 目录。保留 runtime、release.json、发布公钥、下载令牌和证书。
- 下面以已验证的 panel 为例;仅有 Agent 的服务器将 HALO_VERIFIED_COMPONENT 改为 agent。逐段检查结果;链接或版本不匹配、文件缺失或能力检查失败时停止,恢复旧工具及模板,daemon-reload 后按原状态恢复定时器。
HALO_VERIFIED_COMPONENT=panel
HALO_VERIFIED_PACKAGE=/opt/halo-forward/releases/0.6.0/$HALO_VERIFIED_COMPONENT
[ "$(readlink -f /opt/halo-forward/releases/current-$HALO_VERIFIED_COMPONENT)" = "$HALO_VERIFIED_PACKAGE" ] || { echo '当前组件不是已核验的0.6.0版本,请停止维护'; exit 1; }
sudo install -m 0644 -o root -g root "$HALO_VERIFIED_PACKAGE/tools/halofctl.mjs" "$HALO_VERIFIED_PACKAGE/tools/release-archive.mjs" "$HALO_VERIFIED_PACKAGE/tools/pre-update-backup.mjs" "$HALO_VERIFIED_PACKAGE/tools/agent-uninstall.py" /opt/halo-forward/updater/tools/
sudo install -m 0644 -o root -g root "$HALO_VERIFIED_PACKAGE/server/release-format.mjs" /opt/halo-forward/updater/server/
sudo install -m 0755 -o root -g root "$HALO_VERIFIED_PACKAGE/deploy/manage.sh" "$HALO_VERIFIED_PACKAGE/deploy/uninstall-agent.sh" "$HALO_VERIFIED_PACKAGE/deploy/uninstall-panel.sh" /opt/halo-forward/updater/deploy/
printf '%s\n' '#!/bin/sh' 'exec /bin/bash /opt/halo-forward/updater/deploy/manage.sh "$@"' | sudo tee /usr/local/bin/halo-manage >/dev/null
sudo chown root:root /usr/local/bin/halo-manage
sudo chmod 0755 /usr/local/bin/halo-manage
sudo install -m 0644 -o root -g root "$HALO_VERIFIED_PACKAGE/deploy/halo-updater.service" "$HALO_VERIFIED_PACKAGE/deploy/halo-updater.timer" /etc/systemd/system/
sudo systemctl daemon-reload
sudo halofctl capabilities输出必须为 runner_version 1.2.0,且包含 agent_uninstall_v1 和 panel_uninstall_v1。确认后按维护前状态恢复定时器,再查看对应卸载计划。此流程只维护固定工具和服务模板,不改发布公钥、root 信任、业务令牌或证书。
传统手动安装:随包卸载脚本
没有 halofctl 的传统手动布局,在已核验完整运行包根目录保留同包 deploy 脚本与 tools/agent-uninstall.py,再执行:
sudo bash deploy/uninstall-panel.sh --dry-run sudo bash deploy/uninstall-panel.sh sudo bash deploy/uninstall-agent.sh --dry-run sudo bash deploy/uninstall-agent.sh
只执行需移除的组件命令,不必同时卸载两者。版本目录安装必须使用可信更新器;旧签名工具缺能力时,脚本拒绝处理,先按上节维护。Linux 实机卸载仍需演练,本机测试不能替代生产验证。
Docker:仅移除指定容器,保留数据卷
在对应 Compose 目录执行。下面只停止面板,保留数据库容器、panel-data 和 mysql-data;先备份并准备业务迁移:
docker compose stop panel docker compose rm -f panel
Agent 使用自己的 Compose 文件,保留配置、证书与令牌挂载:
docker compose -f compose.agent.yaml stop agent docker compose -f compose.agent.yaml rm -f agent
MySQL 叠加部署需加实际部署时使用的 -f compose.yaml -f compose.mysql.yaml 参数。不要给 Docker 服务执行原生 halofctl 卸载,也不要添加删除数据卷的选项。
10 · 上线前检查实际结果
- 确认 HTTPS、管理员登录、邀请码注册与权限隔离。
- 测试真实入口 / 出口 TCP、UDP、正确和错误证书、客户节点握手。
- 验证 IP / 连接 / 速率 / 流量 / 到期限制,与面板账单口径核对。
- 从实际 Agent 网络验证探测、日志增长、邮件和 Telegram 投递。
- 演练面板与一台 Agent 的安装、更新、回退及保留数据卸载,再演练健康失败恢复和数据库备份恢复。
- 记录 CPU、内存、磁盘、并发与吞吐。当前单实例控制面尚未完成高可用验收。
Linux、Docker、真实 3X-UI 与签名发布安装链路需要在你的机器上联调。不要把当前本机测试通过写成云服务器已经部署成功。
11 · 私有双仓库与版本发布站
源码、客户运行包、公共教程分开保存
维护者私有源码仓库:halo798/halo-forward 与 halo798/halo-forward-site。两个仓库为 Private,保存开发源码与提交历史,访问需要维护者授权。本机独立保留源码包和加密备份;每次发布核对远程提交与版本标签,确认推送完成后再视为远程备份可用。
开发源码和提交历史保存在私有 Git 仓库,另留加密备份。客户取得运行发行包或镜像;自有 HTTPS 发布站或对象存储提供签名清单、安装包与保留的历史版本。介绍站仅发布 public/ 中的公开静态资源,不得上传私钥、账户、令牌、完整仓库或客户数据。
下载令牌只限制安装包访问。商业软件许可证由独立服务签发,绑定面板域名,一份授权管理多个 Agent;邀请码和客户套餐用于使用你运营的转发服务。发布签名私钥与许可签名私钥独立保存。Node 面板运行代码仍可读,私有仓库和剔除开发文件不能保证防止分析或复制。
维护者发布下一版
- 在对应私有仓库迭代源码、更新版本号与发布说明,完成测试后推送提交与版本标签。
- 在可信 Linux 构建机为 x64 / arm64 分别构建面板与 Rust Agent 运行资产,核对许可、签名、摘要和兼容要求。
- 先上传新资产,验证下载和摘要,再发布签名 manifest.json。保留旧版本,不以新内容覆盖同一版本摘要。
- 面板检查并提示新版本;管理员选择在线提交或复制命令到对应服务器 SSH,先灰度一台、验证结果,再逐台更新。
- 介绍站按自己的仓库及静态流程更新,不随面板覆盖;回退可恢复保留的旧静态目录或镜像。
构建机命令模板,不是公网安装地址
下列命令只在有私有源码权限的可信 Linux 构建机运行。首次生成 Ed25519 密钥,私钥权限 600,放在发布输出目录和 Git 仓库之外;后续版本沿用原发布身份,不在普通更新中重新生成密钥。
node tools/publish-release.mjs --init-key /可信构建机/halo-release-private.pem --public-key /可信构建机/halo-release-public.pem RELEASE_PRIVATE_KEY=/可信构建机/halo-release-private.pem RELEASE_BASE_URL=https://你的发布域名/releases/ bash deploy/build-offline.sh release /可信构建机/publish
输出签名组件包、manifest.json、公开验证公钥与初装脚本。所有示例路径和域名须替换;目前没有可直接运行的公网安装入口。目标服务器可离线接收资产,无需访问 GitHub。
发布工具还生成公开 bootstrap.sh;输出 JSON 的 installation 包含 installerUrl、installerSha256 和 publicKeySha256。运营者核验上传结果后,把前两项写入独立介绍站 public/config.js,发行公钥指纹通过独立可信渠道交付。每次更换 bootstrap.sh,都须同步官网的 installerSha256;摘要不一致时安装停止,不自动接受变化。
Docker 镜像先真实构建并上传,取得 image:tag@sha256:摘要 后,发布器可追加 --docker-panel / --docker-agent 签名引用。发布器不代替镜像构建与上传;源码 ZIP 不是客户安装包。
独立介绍站如何部署?
介绍站源码包 halo-forward-site 与面板源码包 halo-forward 分开保存。本站无需数据库、Agent、客户账号或面板接口权限。修改 public/config.js 中的网站名、图标、背景外链、panelUrl 和 downloadUrl 后,可直接把 public/ 上传到静态网站空间。
本机预览或 Docker 运行
node server.mjs # 或在介绍站源码目录运行 docker compose up -d --build
默认仅监听 127.0.0.1:9811;生产用自己的介绍站域名和 HTTPS 反向代理。面板的 DOCS_URL 配置指向该独立域名。文档站版本不与面板强制同步;面板升级不会修改本站。法国服务器已有 0.6.0 私有部署,正式生产域名与公网安装流程仍待配置验收。
13 · 自建公网下载站
独立运维服务位于面板项目 deploy/release-site,与静态介绍站和面板分开运行。需要 Node.js 24;建议下载与许可证小规模同机从 2 核 / 2 GB / 40 GB SSD 起步,按历史包和备份增长调整。已有法国服务器 0.6.0 私有部署,halorelay.com 已购买,官网、下载站和许可证服务规划部署在法国发布机,实际面板在另一台服务器安装;下面是待替换模板,不表示公网已上线。
准备发行文件与下载授权
在匹配架构的可信 Linux 构建机制作真实签名包,再上传已验证输出。公开目录只保存 manifest.json、release-public.pem、install-release.sh、脚本摘要与 Linux 程序包;发布私钥仅留构建机。源码 ZIP 不能冒充 Linux 安装包。下列 CLI 在面板项目根目录运行:
sudo install -d -m 0755 /srv/halo-releases/public sudo install -d -m 0700 /srv/halo-releases/private sudo node tools/release-access.mjs init --file /srv/halo-releases/private/access.json --public-dir /srv/halo-releases/public sudo node tools/release-access.mjs issue --file /srv/halo-releases/private/access.json --public-dir /srv/halo-releases/public --name "客户面板下载" --days 30
令牌原文只在签发时显示一次,存私有密码管理器;下载站仅保存 SHA256。令牌到期 / 撤销在下次请求生效,已开始下载可能继续。先将真实发行文件放入 public/,再启动下载服务。公开文件包括 manifest.json、release-public.pem、install-release.sh 及其摘要、bootstrap.sh 及其摘要;程序包仍由下载服务按令牌鉴权,不改为公开静态目录。
Docker + Caddy 公网 HTTPS
sudo chown -R 10001:10001 /srv/halo-releases/private sudo chmod 0700 /srv/halo-releases/private sudo chmod 0600 /srv/halo-releases/private/access.json cd deploy/release-site cp .env.example .env chmod 0600 .env docker compose up -d --build docker compose ps
检查 .env 的目录与 UID/GID,冲突时使用独立服务账号。修改同目录 Caddyfile.example 为真实下载域名,DNS 指向服务器,合并到已有 Caddy 配置并加载。主机 Caddy 反代回环 9820,不直接开放该端口;容器内 Caddy 须按实际网络修改上游。不要记录敏感请求头,不把服务改为暴露全部文件的静态目录。
清单、公钥和初装脚本公开;程序包要求 Bearer 鉴权且通过有效签名清单、大小与摘要检查。下载上限四个并发、512 MiB 快照预算、单包 256 MiB;留意内存与临时空间。防火墙只开放 SSH、HTTPS 和明确业务端口。
客户核验与更新凭据
通过 0.6.1 bootstrap 一键入口成功安装后,下载令牌已受保护地保存并配置到更新器,无需重复创建。下面只供低层安装或缺失凭据时补配;检查模式和失败安装不保存令牌。
先从独立可信渠道核对安装脚本 SHA256 与公钥 DER 指纹,再执行本地安装器。同站提供的脚本和摘要不能证明独立真实性。下载令牌存 0600 curl 配置文件,避免进入命令参数、URL 或历史;不携鉴权头自动跨站重定向。
sudo install -m 0600 /dev/null /etc/halo-forward/release-download-token sudoedit /etc/halo-forward/release-download-token sudoedit /etc/halo-forward/release.json
install 只用于初次创建,已有文件直接编辑,避免清空。保留 release.json 原有配置,新增 auth_token_file 指向此文件。固定更新器只向同源程序包发 Bearer;公开清单不需要下载令牌。status 只看本机状态,不证明网络已通过。
14 · 商业软件:绑定面板域名
一份许可证绑定一个完整面板域名,可管理多台 Agent,并限制 Agent / 规则数量。软件许可、下载令牌和客户套餐分别管理;发布签名私钥和许可签名私钥独立保存,介绍站不读取任何私有数据。
运营者初始化与签发
在许可证服务器、面板项目根目录运行,需要 Node.js 24。所有 example.com 地址都须替换。私有目录禁止放进 Git 或公网目录,客户只取得公开公钥与激活码:
sudo install -d -m 0700 /srv/halo-license/private sudo node tools/license-admin.mjs init --dir /srv/halo-license/private --issuer-url https://license.example.com sudo node tools/license-admin.mjs issue --dir /srv/halo-license/private --name "客户A" --domain panel.customer.example.com --days 365 --max-agents 10 --max-rules 1000
初始化返回独立公钥、指纹与客户配置模板。激活码只显示一次,数据库仅存哈希。域名不含协议、端口、路径、查询串或通配符;子域名是独立绑定值。客户 PANEL_URL 使用该域名的 HTTPS 地址。
独立许可服务 Docker 部署
sudo chown -R 10001:10001 /srv/halo-license/private sudo chmod 0700 /srv/halo-license/private cd deploy/license-site cp .env.example .env chmod 0600 .env docker compose up -d --build docker compose ps
核对目录和 UID/GID。同目录 Caddy 模板使用独立许可域名,HTTPS 反代主机 127.0.0.1:9830,不开放内部端口。服务没有公网发码管理 API,维护者在受信任 SSH 中维护许可。先保管私钥与一致性数据库备份再升级,不能在每次启动重新创建签发身份。
续期、撤销与改绑
在许可证服务 Compose 工作目录操作,编号、时间与域名必须换成真实值:
docker compose run --rm --no-deps license-site node tools/license-admin.mjs list --dir /private docker compose run --rm --no-deps license-site node tools/license-admin.mjs renew --dir /private --id 从列表取得的UUID --until 2027-10-05T00:00:00.000Z docker compose run --rm --no-deps license-site node tools/license-admin.mjs revoke --dir /private --id 从列表取得的UUID docker compose run --rm --no-deps license-site node tools/license-admin.mjs rebind --dir /private --id 从列表取得的UUID --domain new-panel.customer.example.com
正常约 15 分钟刷新签名许可;网络不可达时旧租约最长有效 72 小时,并受许可证到期时间约束。撤销和改绑在联网刷新时生效,旧离线租约可能持续至窗口结束,不能承诺立即断开全部离线机器。错误状态不能无限延长旧许可。
客户面板激活
原生安装用 sudoedit 修改 /etc/halo-forward/panel.env 的 HTTPS PANEL_URL 与 SECURE_COOKIES=1。root 固定 /etc/halo-forward/license.json,权限 root:halo-forward 0640;使用初始化输出的 issuer_url 和 public_key_pem。这是许可公钥,不是发行公钥,客户不取得私钥:
sudo install -m 0640 -o root -g halo-forward /dev/null /etc/halo-forward/license.json sudoedit /etc/halo-forward/license.json sudo systemctl restart halo-panel.service
install 只用于新配置文件,已有文件直接编辑。进入管理员软件授权页面激活,核对域名、期限、Agent / 规则上限与最近刷新时间。商业发行包未配置、到期或失去有效租约时,管理界面可用,转发暂停;Agent 设置 HALO_LICENSE_REQUIRED=1,依赖面板许可与短期控制租约。
Docker 先在私有 license-private/ 目录创建 license.json,.env 的 HALO_LICENSE_PRIVATE_DIR 指向绝对目录,并叠加只读配置。MySQL 需再加实际 compose.mysql.yaml:
docker compose -f compose.yaml -f compose.license.yaml up -d --no-build --pull never
许可缓存 DATA_DIR/software-license/state.json 与配置独立备份,普通业务数据库备份不能替代它。同一 DATA_DIR 只运行一个面板进程,不启用多进程集群或多副本共享许可缓存。迁移机器或许可状态丢失时由运营者重新绑定实例;不要删除缓存尝试绕过绑定。服务器 root 可控制本地文件,运行代码仍可读,不能承诺许可可绝对防修改或逆向。