mrlee aafff522d8 feat(frp): frps vhost 回源端口支持 80/443,公网反代在该配置下不再适用
- 服务端表单不再硬性拒绝 vhostHTTPPort=80 / vhostHTTPSPort=443,改为保存时弹窗二次确认;
  确认后请求携带 allow_privileged_vhost_ports 提交并由后端校验放行,未携带标记的请求(含直接调 API)仍被拒绝
- frps.toml 生成改为写入风险注释、不再报错;各规则的公网反代回源地址随 80/443 自动跟随
- 「公网反代」页检测到 80/443 后显示说明卡片并隐藏统计/Nginx/规则台账/漂移区块,
  同时跳过 agent 的路由、漂移与健康请求
- 后端 DeployAgentRoute 与 RedeployAllRoutes(含漂移一键修复)拒绝下发,自动下发路径 syncAgentRoute 跳过
- 新增 internal/frp/vhost_port_test.go:校验、二次确认、frps.toml 生成、反代回源跟随与守卫对照
2026-10-11 15:07:07 +08:00
2026-09-23 09:40:59 +08:00
2026-09-23 09:40:59 +08:00
2026-10-07 19:26:02 +08:00

Havline Logo

Havline

让 NAS 访问更简单

面向 飞牛 fnOS 的轻量公网访问管理工具
反向代理 · DDNS · HTTPS 证书 · 内网穿透 · Cloudflare Tunnel · 一站式 Web 管理

发布版本 飞牛 fnOS 其他环境未测试 Go Vue 3 Nginx GPL-3.0


简介

Havline 是一款主要为 飞牛 fnOS 编写的反代与管理工具,帮助你在 NAS 上快速搭建稳定的公网访问能力:通过 Web 界面管理 Nginx 反向代理、自动同步 DDNS、申请与续期 Let's Encrypt 证书,并在一个仪表盘里查看服务状态、访问日志与流量统计。

无需手写 Nginx 配置,也无需在多个工具之间切换。当前开发与测试环境以飞牛 fnOS 为主,群晖、威联通、自建 Linux 等其他环境尚未充分测试,部署前请自行验证。

Havline 基于开源项目 O96u/Fonu 1.0.2 继续开发,保留上游在反向代理、DDNS、证书和内网穿透上的基础能力,并继续扩展公网 Agent、Cloudflare Tunnel、一键升级和飞牛应用交付。

功能特性

模块 说明
反向代理 多域名、多端口、HTTP/HTTPS、自动重定向;实时访问日志、流量统计、当前连接 IP
DDNS 支持 Cloudflare、DNSPod、阿里云、腾讯云、火山引擎 DNS;单任务多根域名,自动同步公网 IP
HTTPS 证书 ACME 自动申请与续期;证书/私钥/ZIP 下载;申请进度实时日志
仪表盘 公网 IP、域名、证书、服务状态一览;请求趋势与运行健康度
日志中心 系统日志、Nginx 访问日志、Nginx 错误日志;分页筛选与自动刷新
内网穿透 FRP 多服务端管理,支持 TCP/UDP/HTTP/HTTPS 等代理类型;客户端按需下载、配置与运行诊断
公网 Agent 通过 SSH 安装和维护 VPS Agent,远程管理 frps、Nginx、证书和路由
Cloudflare Tunnel cloudflared 按需下载、隧道与路由管理、DNS 同步、健康检查和漂移修复
一键升级 含 updater 的 Compose 部署支持镜像构建、主服务重建和版本健康检查
系统设置 常规 / 通知 / 安全 / 高级分栏;邮件/Webhook/Telegram 告警、备份与恢复
其他 深色模式、配置导出/导入、版本更新提示

相比上游 Fonu 的主要增量

方向 Havline 增量
公网服务端 通过 SSH 安装、升级和维护 VPS 上的 havline-agent,远程管理 frps、Nginx、证书和公网反代
FRP 管理 多服务端管理、FRP 客户端按需下载、代理规则校验、运行诊断、路由健康与漂移检测
Cloudflare Tunnel cloudflared 按需下载、Account/API Token 预检、隧道与路由管理、DNS 同步、健康巡检和漂移修复
一键升级 Compose + updater sidecar,支持构建/重建/健康检查,并在部分失败场景下尝试回滚
飞牛交付 提供 Docker 离线镜像包与 Native 应用两种形态,支持统一网关 /app/havline 接入
文档体系 增加图文操作手册、部署/升级/迁移文档、飞牛打包方案和 Cloudflare/FRP 专题方案

技术栈

层级 技术
后端 Go 1.23、标准库 HTTP、SQLite(modernc.org/sqlite)
反向代理 内置 Nginx(动态生成配置、热重载)
证书 go-acme/lego(ACME DNS-01)
DDNS Cloudflare / DNSPod / 阿里云 / 腾讯云 / 火山引擎 DNS API
内网穿透 FRP 客户端按需下载;多服务端和代理规则管理,支持公网 Agent
隧道 Cloudflare Tunnel / cloudflared
前端 Vue 3、TypeScript、Vite、Naive UI、ECharts
部署 Docker 多架构镜像(amd64 / arm64)、GitHub Actions CI

项目结构

路径 说明
cmd/havline 主程序入口,提供 Web 管理后台、API、调度和内置 Nginx/FRP 管理
cmd/havline-agent 公网 VPS 上的 Agent,接收主程序下发并管理 frps、Nginx、证书和路由
cmd/havline-updater 一键升级 sidecar,仅它挂载 Docker Socket,并通过 Unix Socket 与主程序通信
internal/api HTTP 路由、鉴权中间件、请求处理器和 API 响应封装
internal/app 应用启动、服务装配、统一网关和运行生命周期
internal/nginx、internal/nginxtmpl Nginx 配置生成、共享模板、安全/限流/geo/TLS 片段和热重载
internal/proxy、internal/service 反向代理规则、证书绑定、访问策略和 Nginx 配置编排
internal/frp FRP 多服务端、规则、运行进程、Agent 安装、诊断、健康和漂移检测
internal/cloudflared Cloudflare Tunnel 设置、隧道、路由、DNS、健康事件和漂移修复
internal/agent Agent 服务端实现,包括鉴权、监听策略、防火墙提示、Nginx/frps 操作
internal/updater updater 服务端、客户端、执行器和远端版本读取
internal/ddns、internal/certificate、internal/acme DDNS 服务商、证书存储、导入和 ACME 申请续期
internal/backup、internal/notify、internal/monitor、internal/metrics 备份恢复、通知渠道、监控采集和指标导出
web/src Vue 3 前端,包含 API 客户端、组合式函数、组件、路由、样式和页面视图
migrations SQLite 数据库迁移
docker-compose*.yml Host、Bridge 和单文件 Git 构建部署编排

部署

源码仓库:https://github.com/mrlee233/havline · 发布版本

以下方式均从源码构建,不使用上游 Docker 镜像。

场景 推荐方式 说明
飞牛 fnOS 常规安装 Host 模式 Compose 避开系统已占用的 80/443,默认使用 6893/18080/9443
非 host 网络或自定义端口映射 Bridge 模式 Compose 主服务和 updater 通过端口映射访问,适合测试或自建 Linux
只拿一个 Compose 文件部署 单文件 Git 构建 updater 从远端仓库读取版本并构建,本地不需要完整源码
飞牛应用商店安装 Docker 离线包或 Native FPK 见下方「飞牛 fnOS 应用」章节

快速部署(推荐 · 飞牛 fnOS · Host 模式)

飞牛系统已占用 80/443,使用 host 网络 + 高位反代端口,避免与系统 Nginx 冲突。

git clone --branch main https://github.com/mrlee233/havline.git
cd havline
docker compose -f docker-compose.host.yml up -d --build
入口 地址
管理后台 http://<NAS-IP>:6893
HTTP 反代(默认) http://<NAS-IP>:18080
HTTPS 反代(默认) https://<NAS-IP>:9443
  • 默认命名卷挂载到 /data,存放数据库、Nginx 配置、证书与日志;可通过 HAVLINE_DATA_PATH 选择绑定目录,已有数据须先迁移
  • Host 编排设置反代默认端口为 18080、9443,可通过环境变量修改;该编排不包含 updater

其他部署方式

本地源码 + Bridge 网络

在已克隆的源码目录中执行:

docker compose -f docker-compose.yml up -d --build

默认映射 6893:6893、18080:80、9443:443。主程序首次启动时会在共享卷中自动生成 updater Token,updater 等待并读取同一文件,不会创建额外的初始化容器;只有 updater 挂载 Docker Socket。

单文件 Git 构建(不需要本地源码)
mkdir -p /opt/havline && cd /opt/havline
curl -fsSLo docker-compose.hub.yml \
  https://github.com/mrlee233/havline/raw/branch/main/docker-compose.hub.yml
docker compose -f docker-compose.hub.yml up -d --build

BuildKit 从当前仓库 main 分支构建,默认使用 Bridge 端口映射。Token 由主程序自动生成,HAVLINE_VERSION 只控制镜像标签,不锁定源码提交。

手动构建镜像
docker build -t havline:local .

在源码根目录执行;构建镜像不会自动启动容器,部署时仍需选择合适的 Compose 编排。

首次登录

  1. 启动后查看容器/运行日志,获取自动生成的 admin 初始密码
  2. 访问 http://<NAS-IP>:6893/login 登录
  3. 在 设置 中立即修改管理员密码

FRP 内网穿透(无公网 IP)

适用于无法端口映射、无公网 IPv4 的场景。Havline 在 内网穿透 页面统一管理多个服务端与代理规则,frpc 按需下载:

  • Web 网关:外网 HTTP/HTTPS 经 VPS 上的 frps 中转至本地 Havline Nginx(默认 18080 / 9443),域名分流、证书、访问控制、日志仍由 Nginx 处理
  • 端口转发(TCP/UDP):将 VPS 远程端口映射到内网服务(如 SSH、数据库、DNS/游戏等 UDP);可与 Web 网关同时启用,纯端口穿透可不配置 Web 域名
  • 服务端设置:填写 frps 地址、端口、认证和 TLS 选项;保存后添加代理规则,校验配置再启动

Web 流量路径:用户 → DNS(解析到 VPS)→ frps → frpc → Havline Nginx → 内网服务

端口转发流量路径:用户 → VPS 公网 IP:远程端口 → frps → frpc → 内网 IP:端口(TCP 或 UDP)

1. VPS 部署 frps

在具有公网 IP 的 VPS 上安装 frp,选择与本地 frpc 兼容的版本。在服务端详情中查看生成的 frps.toml 参考,也可通过公网 Agent 管理 frps。

典型 Web 网关示例:

bindAddr = "0.0.0.0"
bindPort = 7000

auth.method = "token"
auth.token = "your-secret-token"

vhostHTTPPort = 80
vhostHTTPSPort = 443

启动:frps -c frps.toml。安全组/防火墙需放行 7000(控制连接)、80/443(Web 虚拟主机),以及 隧道远程端口(在 Havline 添加规则后按提示放行;UDP 隧道需在防火墙同时放行对应端口的 UDP)。

2. Havline 配置 frpc

在侧栏 内网穿透 页面:

  1. 添加服务端,填写服务器地址、端口、认证信息和 TLS 选项,与 VPS 上 frps 保持一致。
  2. 添加 HTTP / HTTPS 代理时填写域名和本机 Nginx 目标端口;Host 编排默认使用 18080 / 9443,Bridge 容器内通常为 80 / 443,以实际规则为准。
  3. 添加 TCP / UDP 代理时填写 VPS 远程端口及内网目标地址;开放对应安全组和防火墙端口。
  4. 在应用配置中下载或激活 FRP 客户端,校验配置后启动,通过服务端诊断和日志检查运行状态。

控制连接成功不等于业务已连通,还需检查代理端口、内网目标、DNS 和 Nginx 路由。

3. DNS 与证书

  • DDNS:FRP 访问域名应解析到 VPS 公网 IP,而非 NAS IP;按需使用自定义 IP 或在 DNS 服务商处配置
  • HTTPS 证书:Web 网关推荐继续使用 DNS-01 验证(Cloudflare、阿里云、腾讯云、DNSPod、火山引擎等已支持);证书仍在 NAS 侧 Nginx 终结
  • 纯端口穿透:无需为 TCP/UDP 隧道单独配置域名证书

公网 Agent 与 Cloudflare Tunnel

  • 公网 Agent:在公网 Agent 页面配置 VPS 信息,按需通过 SSH 安装并测试连接,再管理 frps、Nginx 和证书;需要公网反代时部署对应路由。限制 Agent 管理通道访问,不要仅凭业务端口可用判断管理通道安全。
  • Cloudflare Tunnel:配置 Account ID 和 API Token,预检授权并按需下载 cloudflared;创建隧道后,在反向代理规则中选择 Cloudflare 出口和目标隧道,检查路由、DNS 与连接状态。托管模式从本地规则派生 ingress,修复漂移前先确认本地配置。

飞牛 fnOS 应用

Havline 提供两种飞牛应用形态,均支持统一网关入口 /app/havline。

Docker 应用(离线镜像包)

  • 独立仓库:https://github.com/mrlee233/havline
  • 安装包:havline-1.9.2.fpk
  • 包内包含 amd64 / arm64 离线镜像,安装时执行 docker load
  • Compose 使用本地镜像并设置 pull_policy: never,不依赖外部 Registry
  • 管理界面通过统一网关 /app/havline 访问

环境变量

变量 默认值 说明
HAVLINE_LISTEN :6893 管理后台监听地址
HAVLINE_DATA_DIR /data 数据目录(数据库、Nginx 配置、证书、日志)
HAVLINE_SESSION_SECRET 空,自动生成 会话与凭据加密密钥,保存在数据目录;已有数据后不要更换
HAVLINE_INITIAL_ADMIN_PASSWORD 空,自动生成 首次初始化管理员时使用的密码;不设置时会生成随机密码并输出到首次启动日志
HAVLINE_UPDATER_TOKEN 空,自动生成 可选覆盖值;未设置时读取共享 Token 文件
HAVLINE_UPDATER_TOKEN_FILE /run/havline-updater/updater.token 主程序与 updater sidecar 共享的 Token 文件
HAVLINE_UPDATER_SOCKET /run/havline-updater/updater.sock 主程序与 updater sidecar 通信的 Unix Socket
HAVLINE_DATA_PATH havline-data Compose 挂载来源,可配置宿主机目录
HAVLINE_NGINX_HTTP_PORT 80 新建 HTTP 反代规则的默认监听端口
HAVLINE_NGINX_HTTPS_PORT 443 新建 HTTPS 反代规则的默认监听端口
HAVLINE_NGINX_BIN nginx Nginx 可执行文件路径(本地开发可指定)
HAVLINE_FRPC_BIN frpc frpc 可执行文件路径(运行时可按需下载)
HAVLINE_FRP_PID {DATA_DIR}/frp/frpc.pid frpc 进程 PID 文件路径
HAVLINE_GATEWAY_SOCKET 空 飞牛统一网关接入时使用的 Unix Socket
HAVLINE_GATEWAY_PREFIX 空 统一网关访问前缀,例如 /app/havline
HAVLINE_AGENT_LISTEN 127.0.0.1:7700 Agent 默认监听地址
HAVLINE_AGENT_ALLOW_REMOTE 0 是否允许 Agent 监听非回环地址;启用前应确认防火墙和 HTTPS/隧道策略
HAVLINE_AGENT_TOKEN 安装时生成 Agent Bearer Token
HAVLINE_UPDATE_PROJECT_DIR /workspace updater 容器内 Compose 项目目录
HAVLINE_UPDATE_COMPOSE_FILE docker-compose.yml updater 允许操作的 Compose 文件
HAVLINE_UPDATE_MODE local 升级模式,支持 local 或 git
HAVLINE_UPDATE_REPO 无 git 模式下的远端仓库地址
HAVLINE_UPDATE_BRANCH main git 模式下的分支
HAVLINE_UPDATE_HOST_DIR 自动发现 宿主机 Compose 文件目录;自动发现失败时必须显式设置

数据目录速查

路径 内容
/data/havline.db 管理员、会话、代理、DDNS、FRP、Cloudflare、健康事件等 SQLite 数据
/data/session_secret 会话签名与敏感凭据加密主密钥;已有数据后不可随意更换
/data/nginx/ 生成的 Nginx 配置、日志和相关运行文件
/data/certs/ ACME 证书与私钥
/data/frp/ frpc 配置、二进制、PID 和运行状态

注意事项

  1. 密钥持久化:会话密钥未显式配置时自动生成并写入数据目录;已有数据不要更换密钥。含 updater 的编排会由主程序在共享卷中自动生成 Token,旧部署仍可用 HAVLINE_UPDATER_TOKEN 覆盖。
  2. 端口冲突:宿主机已有 Nginx(如飞牛系统)占用 80/443 时,不要让 Havline 反代规则监听 80/443;使用 18080/9443 或 host 模式 + 环境变量。
  3. 已有反代规则:修改 HAVLINE_NGINX_HTTP_PORT / HAVLINE_NGINX_HTTPS_PORT 后,不会自动更新数据库中已有规则的端口,需在反代页手动修改并保存。
  4. 访问日志:仅统计经 Havline Nginx 反代的域名流量,不包含管理后台 :6893 的请求。
  5. 证书与 DNS:DNS-01 申请不要求域名指向 NAS,但需确保 DNS 凭证能写入对应根域的验证记录,并等待传播。业务访问仍需正确解析、端口和路由。
  6. 数据持久化:Docker 部署请挂载 volume 到 HAVLINE_DATA_DIR,避免容器重建后配置丢失。
  7. 备份:可通过设置页导出数据;文件级备份前停止服务,保留整个数据目录(数据库、密钥、证书私钥和运行配置);显式环境密钥需另行安全保留。
  8. 升级:含 updater 的 Compose 实例可使用一键升级;仅重建后版本健康检查失败时尝试镜像回滚,构建失败和数据库迁移回退需人工处理。升级前保留备份和旧镜像。

常见问题

现象 优先检查
无法登录或忘记初始密码 首次启动日志中的 admin 密码;若日志已丢失,停止服务后从备份恢复,或按部署文档处理数据库
启动后提示端口被占用 飞牛系统通常占用 80/443;Host 模式请使用 6893/18080/9443,Bridge 模式检查端口映射
修改反代端口后旧规则不生效 HAVLINE_NGINX_HTTP_PORT / HAVLINE_NGINX_HTTPS_PORT 只影响新规则,已有规则需在反代页手动修改
证书申请失败 检查 DNS 服务商凭证、根域权限、ACME 邮箱、DNS 传播和 CA 限制;泛域名必须使用 DNS-01
DDNS 没有更新 检查 DNS API 权限、记录是否存在、公网 IP 探测结果;FRP 场景域名应解析到 VPS 公网 IP
FRP 客户端启动失败 确认 frps 地址/端口/Token/TLS 一致,VPS 安全组已放行控制端口和远程端口
Cloudflare DNS 未自动创建 确认根域名在同一个 Account ID 下,API Token 至少具备 Zone:Read 和 DNS:Edit
Cloudflare 隧道 502 或 Token 错误 使用 API Token 预检;Tunnel Token 与 Account API Token 不是同一种凭据
升级时找不到 Compose 文件 设置 HAVLINE_UPDATE_HOST_DIR 指向宿主机 Compose 所在目录,并确认容器名和 Compose 项目标签来自同一部署
升级后数据异常 恢复升级前备份,确认 HAVLINE_DATA_DIR、session_secret 和数据库迁移状态未变化
Agent 直连失败 确认 Agent 监听地址、端口、防火墙和 Token;默认策略应优先使用 SSH 隧道或 HTTPS,不建议直接暴露管理端口
公网访问失败 按 DNS → 端口/隧道 → Nginx 路由 → 内网服务逐段排查,不要只看 FRP 或 Tunnel 是否在线

本地开发

# 构建前端并准备嵌入目录
cd web
npm ci
npm run build
cd ..
New-Item -ItemType Directory -Force cmd/havline/web/dist | Out-Null
Copy-Item web/dist/* cmd/havline/web/dist -Recurse -Force

# 运行后端(需要可用 Nginx)
go run ./cmd/havline

前端热更新在另一终端执行 cd web、npm run dev。测试命令:

go test ./...
go vet ./...
cd web
npm run typecheck
npm test

版本来源为根目录 VERSION;Docker 构建注入前后端,本地 go run 未注入时显示 dev。

开源协议

本项目采用 GPL-3.0 开源。

Havline 基于 O96u/Fonu 1.0.2 版本继续开发,感谢上游作者及贡献者。保留原作者版权、来源与 GPL-3.0 下适用的源代码提供义务。

问题反馈:Havline Issues。请提供版本、部署方式、复现步骤和脱敏日志,不上传密码、Token、私钥或完整备份。

S
Description
Havline
Readme GPL-3.0
183 MiB
Languages
Go 56.5%
Vue 38.1%
TypeScript 4%
Shell 0.6%
PowerShell 0.4%
Other 0.3%