2026-04-14 10:57:06 +08:00
2026-04-14 18:05:32 +08:00
2026-09-29 11:34:18 +08:00
2026-04-14 10:57:06 +08:00
2026-04-14 10:57:06 +08:00
2026-09-29 11:34:18 +08:00
2026-04-14 10:57:06 +08:00
2026-04-14 18:05:32 +08:00
2026-04-14 18:05:32 +08:00
2026-04-14 10:57:06 +08:00
2026-04-14 10:57:06 +08:00

HY2 Panel

单机自托管的 Next 16 管理面板,面向 Hysteria 2 HTTP 鉴权与多节点流量聚合场景。

功能包括:

  • 单管理员本地登录,基于 SQLite 持久化会话
  • hy2 用户管理:启用/禁用、重置密码、到期时间、总流量上限、稳定 auth_id
  • 多节点管理:每节点独立鉴权 URL + token、trafficStats URL/secret、轮询间隔
  • 公开 HTTP 鉴权接口:返回标准 200 + { ok, id }
  • 后台轮询 trafficStats、聚合用户流量、记录同步错误与鉴权审计
  • 对禁用、过期、超额用户调用节点 kick 做准实时断开

Environment

复制 .env.example 为 .env,至少设置:

APP_URL=http://127.0.0.1:3000
SESSION_SECRET=your-long-random-secret
SESSION_COOKIE_SECURE=auto
ADMIN_PASSWORD=your-strong-admin-password

说明:

  • ADMIN_USERNAME / ADMIN_PASSWORD 是单管理员账号,启动时会同步到数据库中的唯一管理员记录
  • SESSION_COOKIE_SECURE=auto 时会按 APP_URL 协议决定是否开启 Secure cookie;如果你是直接用 http://IP:3000 访问,不要强制设成 true
  • DATABASE_PATH 默认是 ./data/hy2-panel.db
  • POLLER_ENABLED=true 时,Next instrumentation.ts 会在 Node 进程启动后启动轮询器

Development

npm install
npm run dev

打开 http://127.0.0.1:3000。

Build

npm run lint
npm run build

这里将生产构建固定为 next build --webpack。原因是 Next 16 默认 Turbopack,但在部分受限环境下会触发构建期端口绑定问题;Webpack 构建已验证通过。

HY2 Node Access

面板里的每个节点都会生成独立鉴权 URL,例如:

auth:
  type: http
  http:
    url: http://127.0.0.1:3000/api/hy2/nodes/tokyo-01/auth?token=YOUR_TOKEN
    insecure: false

根据 Hysteria 官方文档,HTTP 鉴权回调请求体是:

{
  "addr": "123.123.123.123:44556",
  "auth": "username:password",
  "tx": 123456
}

面板响应:

{
  "ok": true,
  "id": "immutable-auth-id"
}

多节点识别依赖“不同的 URL 路径”,不是依赖 hy2 自动附带节点 ID。

trafficStats

节点需启用:

trafficStats:
  listen: :9999
  secret: some_secret

面板会轮询:

  • GET /traffic?clear=1
  • GET /online
  • GET /dump/streams
  • POST /kick

systemd

已提供示例单元文件 deploy/hy2-panel.service。

典型流程:

npm install
npm run build
sudo cp deploy/hy2-panel.service /etc/systemd/system/hy2-panel.service
sudo systemctl daemon-reload
sudo systemctl enable --now hy2-panel

Nginx 反代

已提供示例站点配置 deploy/nginx-hy2-panel.conf。

如果你的公网域名是 hy2.xn--876a.net,建议生产环境把 .env 中的 APP_URL 改成:

APP_URL=https://hy2.xn--876a.net
SESSION_COOKIE_SECURE=auto

示例配置默认反代到 127.0.0.1:3000,证书路径为:

/etc/nginx/ssl/hy2.xn--876a.net/fullchain.pem
/etc/nginx/ssl/hy2.xn--876a.net/privkey.pem

典型启用流程:

sudo mkdir -p /etc/nginx/ssl/hy2.xn--876a.net
sudo cp fullchain.pem /etc/nginx/ssl/hy2.xn--876a.net/fullchain.pem
sudo cp privkey.pem /etc/nginx/ssl/hy2.xn--876a.net/privkey.pem
sudo cp deploy/nginx-hy2-panel.conf /etc/nginx/sites-available/hy2-panel.conf
sudo ln -sf /etc/nginx/sites-available/hy2-panel.conf /etc/nginx/sites-enabled/hy2-panel.conf
sudo nginx -t
sudo systemctl reload nginx

如果你当前的 hy2 节点仍然直接访问 http://38.246.237.36:3000/api/hy2/... 作为鉴权地址,可以继续保留这一入口。上面的 Nginx 只接管 80/443 上的域名访问,不会替换或中断现有的 :3000 直连。

面板内部生成链接时会优先使用反代传入的 X-Forwarded-Host / X-Forwarded-Proto,如果是直接访问 http://38.246.237.36:3000,则会自动退回到当前请求的 Host。

UI 与交互

界面使用 shadcn/ui(本地组件位于 components/ui),以列表、行内展开和中性色分隔线为主。代理组节点排序使用 dnd-kit,支持鼠标、触屏,以及空格开始、方向键移动、空格放下、Escape 取消的键盘操作。修改排序后点击保存,也可撤销。

用户、节点和最近 100 条审计记录支持本页即时搜索和状态筛选。用户、节点与模板表单支持 Ctrl/Cmd + Enter 提交,保存失败会保留输入;删除操作通过确认对话框执行。

运行浏览器回归:

npx playwright install chromium
npm run test:e2e

测试自动启动 3106 端口的开发服务,使用 /tmp 中独立的临时数据库并关闭节点轮询,不访问现有数据库。覆盖排序持久化、鼠标/键盘/模拟触屏、列表筛选、用户编辑、复制链接、删除确认、失败保留输入和移动端溢出检查。截图输出在 test-results/。运行前请停止同一工作目录的其他 Next 开发服务。

自定义订阅节点与数据库兼容

在「节点管理 → 新增自定义订阅节点」填写显示名、Slug 和单个 Clash/Mihomo proxy 的 YAML。支持单对象、单节点列表,以及 proxies: 包装。协议参数(例如 AnyTLS 的 password、sni、alpn)由 YAML 提供;订阅名使用 YAML name,面板显示名独立。原始 YAML 和注释按原样保存,输出订阅时才解析、序列化。格式错误会在表单内提示并保留输入。

自定义节点与 HY2 节点共用列表、启停、删除、主组拖拽排序及自定义分组。自定义节点仅分发配置,不参与 HY2 HTTP 鉴权、轮询或面板流量计量,也不生成 HY2 服务端配置。代理的访问控制和流量限制由该代理服务自身负责。

数据库升级沿用服务器现有的 SQLite user_version = 4,保留 hy2_nodes.node_type(默认 hy2)和 hy2_nodes.custom_config_yaml(默认空字符串)的原名称、类型和默认值:

  • 全新数据库、版本 1–3 的数据库在启动时自动迁移。
  • 服务器已有的完整版本 4 不再重复添加列,也不重写现有记录。
  • 对于版本 3/4 中已部分添加的自定义节点字段,只补充缺失列。
  • 迁移在一个 SQLite 写事务中执行,失败回滚;更高版本的数据库会拒绝启动,避免错误降级。
  • 节点 ID、用户 ID、订阅 token、加密凭据、额度、会话、历史流量和代理分组 JSON 都不因迁移而重建。

升级时保留原 .env、DATABASE_PATH、SESSION_SECRET 和管理员配置。尤其不能更换 SESSION_SECRET,现有 HY2 用户凭据依赖它解密。发布前应停服务并通过 SQLite backup API 备份数据库(包含 WAL 中已提交的数据),不要仅复制正在写入的 .db 文件。随后更新代码、安装锁定依赖、构建并启动;无需导出导入业务数据,也无需手工执行 ALTER TABLE。

tests/fixtures/remote-v4-schema.sql 是从服务器只读获取的实际表结构,不含生产数据。npm test 使用该结构和模拟业务数据验证兼容性、重复迁移、失败回滚、原始 YAML 保留、订阅生成,以及自定义节点不参与鉴权和轮询。npm run test:e2e 验证新版 UI 的新增、校验、编辑、分组、禁用和删除流程。

证书托管与服务器自动安装

管理员进入「证书与安装」,上传 PEM 完整证书链(CRT)和未加密私钥(KEY)。证书私钥使用 SESSION_SECRET 派生密钥加密保存,不在页面回显;请保留原有 SESSION_SECRET 并备份数据库。本功能使用覆盖 *.p.xn--876a.net 的通配符证书;只管理上传的证书,不申请或自动续期,也不会自动更新已安装服务器的文件。

选择证书、填写节点名称与 Slug,生成并下载安装脚本。每份脚本限一个节点,有效期 24 小时,可在平台撤销。脚本不内嵌证书私钥,运行时通过 HTTPS 获取配置和证书,安装完成后凭据不能再次获取私钥。

在使用 systemd 的 Linux 服务器上以 root 运行(支持 x86_64、ARM64、ARMv7):

sudo bash install-jp1.sh
# 或显式指定参数;jp1 可替换为任意合法的单级子域名前缀:
sudo bash install-jp1.sh --domain jp1 --hy2-port 23456 --stats-port 23457
# NAT 内外端口不同:
sudo bash install-jp1.sh --domain jp1.p.xn--876a.net \
  --hy2-port 23456 --stats-port 23457 \
  --hy2-listen-port 443 --stats-listen-port 9999

无参数时交互输入域名和两个端口。短域名自动补全 .p.xn--876a.net;完整域名用作订阅地址和 SNI。请提前将域名解析至服务器公网 IP,在 NAT / 云防火墙设置 UDP 的 HY2 映射和 TCP 的统计 API 映射。脚本不能代替云厂商配置端口转发或 DNS。统计 API 使用随机密钥,建议将其 TCP 端口限制为仅面板 IP 可访问。

脚本安装 curl/jq/openssl 等依赖,从 Hysteria 官方下载入口下载服务端,保存 /etc/hysteria/config.yaml、server.crt、server.key,创建 hy2-panel-node.service 并设置开机启动。先以禁用状态注册,检查本机统计 API 健康后启用节点。公网 NAT 连通性请通过平台的节点同步状态确认。

重复执行仅允许同一安装记录、同一域名和端口,不覆盖其他已有 HY2 配置。失败后修复问题,在凭据有效期内重试;已启用的节点不因删除安装记录而删除。凭据过期且已有部分安装时,请先检查并清理对应的禁用节点和服务器配置,再生成新的安装记录。

平台 APP_URL 必须是服务器能访问的公网 HTTPS 地址(本地测试允许 localhost HTTP)。新迁移使用数据库版本 5,只新增 managed_certificates / node_installations 表,兼容现有 v4 节点、用户和订阅数据。部署前仍应备份数据库;不要用旧版本程序打开已升级的数据库。

托管 AnyTLS / sing-box

「证书与安装」选择 AnyTLS · TCP / sing-box,下载脚本后运行:

sudo bash install-jp2-anytls.sh --domain jp2 --port 51046 --listen-port 51046

只需映射代理 TCP 端口。sing-box 与管理程序使用独立目录和 systemd 单元,不覆盖已有 HY2。管理 API 自动分配本机端口,节点每 15 秒通过 HTTPS 主动向面板同步,无需开放公网管理端口。支持 Debian/Ubuntu、dnf 系发行版的 x86_64 / ARM64。

  • 每用户派生独立的 AnyTLS 密码,订阅自动生成对应节点。更改用户密码会更新 AnyTLS 凭据。
  • 用户禁用、到期、额度耗尽及节点禁用在下次同步时生效。当前通过重启 sing-box 应用配置,所有已有连接会断开;配额为周期检查,可能产生一个同步周期的超额。
  • 连续无法同步超过 90 秒,或本地已到租约到期时间时停止代理;重新连接面板后自动恢复。管理程序异常退出也会停止代理。
  • 从 V2Ray API 读取累计用户流量,以进程启动标识和累计值去重;待发送报告落盘,网络重试不重复计费。流量为应用层统计,异常掉电/崩溃可能丢失最后一次采样之后的数据,不能当作精确的计费凭证。在线用户数暂不展示,连接数来自 Clash API。
  • 数据库迁移 v6 只增加安装协议字段和累计采样表,原 HY2 / 自定义节点保持兼容。

官方 sing-box 默认发行包未启用 with_v2ray_api。部署面板前运行 bash scripts/build-sing-box.sh,构建未经修改的 sing-box v1.14.2(固定源码 commit af6e64c3b69e6132ebaee0e1a3d24e93903f6709),启用 with_v2ray_api,with_clash_api,with_utls。需要 Go 1.25.5 或更新版本。将生成的 data/artifacts/ 作为部署产物保存到面板同一路径;程序不会把二进制或任何凭据提交到 Git。安装脚本从面板 HTTPS 下载二进制并核对 SHA-256;没有产物时下载端点返回 503。

上游源码与许可:https://github.com/SagerNet/sing-box/tree/v1.14.2 ,GPL-3.0-or-later。lib/templates/stats.proto 来自该版本,许可说明见同目录 sing-box-LICENSE。构建脚本提供可复现的源码获取与编译步骤。

真实协议回归可运行:SING_BOX_TEST_BINARY=/path/to/sing-box AGENT_TEST_PYTHON=/path/to/python npx tsx tests/anytls-runtime.ts(Python 环境需 grpcio 和 grpcio-tools)。它验证 TLS 校验、实际转发、按用户统计及停用后的拒绝连接。

中转主机与线路

「中转线路」新增入口主机,下载安装 SH,以 root 在该主机运行。脚本安装固定版本 Realm v2.9.6(官方 Linux musl x86_64 / ARM64 产物,内置 SHA-256),独立使用 /etc/hy2-panel-relay、/usr/local/lib/hy2-panel-relay、hy2-panel-relay.service 和 hy2-panel-relay-agent.service。不覆盖已有代理服务,不自动修改防火墙;需放行选定的监听端口,并配置云防火墙/NAT 公网端口映射。脚本含长期管理凭据,应按密钥保管;删除主机可撤销凭据。

新增线路时选择入口主机、原目标节点,填写公网端口与本机端口。第一版支持托管 HY2(UDP)和 AnyTLS(TCP),保留原节点直连。入口只转发加密流量,不持有节点证书、私钥或用户密码;订阅地址切换到入口,但 SNI 保留原目标域名。AnyTLS 仍允许在 TCP 隧道内转发 UDP 业务。

管理程序每 15 秒主动获取配置,检查本机端口冲突及 Realm 实际监听情况,配置变更会重启这一台主机的 Realm 并断开已有中转连接。启用、停用、删除在下次同步生效;无法联系平台约 90 秒后停止转发,联网后恢复。页面显示配置/进程状态,不能代替真实协议或大陆线路质量测试。UDP 空闲映射保留 300 秒。

仅最近上报、配置已应用且服务运行的线路进入订阅,可复用订阅拖拽排序和分组。目标节点停用时其中转线路也停止发布并从转发配置移除。数据库 v7 仅新增 relay_hosts、relay_routes,中转线路不会插入 hy2_nodes 或参与节点轮询;用户流量仅由落地节点计量一次,第一版不区分同一用户的直连/中转用量。删除被引用的目标节点前需先删除对应线路。

S
Description
No description provided
Readme
674 KiB
Languages
TypeScript 86.9%
CSS 5.9%
Shell 4.5%
Python 2.6%
JavaScript 0.1%