- Linux 安装包:scripts/build-linux.ps1 交叉编译出 fonu-<版本>-linux-{amd64,arm64}.tar.gz(二进制 + migrations + systemd 安装脚本 + 运行时资源 + sha256),scripts/fonu-install.sh 负责装机(/opt/fonu、/var/lib/fonu、/etc/fonu/fonu.env 首次生成随机会话密钥)并新增 --reset-admin;装完直接打印初始管理员口令
- 证书 DNS-01:lego 默认读系统 resolv.conf(容器里是 Docker 的 127.0.0.11,不返回权威 NS)导致 could not determine authoritative nameservers;现显式传 AddRecursiveNameservers,默认 223.5.5.5/1.1.1.1/8.8.8.8,设置项 acme_dns_resolvers 可覆盖(system = 回到系统解析器)
- Buypass 已停止签发(2025-10-15)并终止服务(2026-04-15):从可选 CA 移除,历史记录仍可展示,直接提交会被拦下并给出中文原因
- ZeroSSL:422 时带出 error.type/error.code(非 JSON 退回截断正文);同时修掉网络错误把含 access_key 的完整 URL 写进任务日志与 app.log 的密钥泄露
- 测试:解析器列表解析 3 例 + ZeroSSL EAB 4 例(含不泄露密钥断言);gofmt / go build / go vet / go test 全绿
25 KiB
Cloudflare Tunnel(cloudflared)与 Fonu 的融合方案
日期:2026-09-25 对象:Fonu 1.0.2(VERSION 1.2.12) 方法:先查 Cloudflare 官方文档与同类开源项目,再逐个核对本仓库现有可复用面(下文带
文件:行的都是读过代码得出的)。 结论速览:值得做,但建议以「第二条出口」的形态并存,先做 locally-managed + 进程托管,不接 Cloudflare API。详见 §五、§六。
一、为什么值得做(对 Fonu 的战略意义)
Fonu 现在的穿透链路必须有公网服务端:本机 frpc → VPS 上的 frps → 域名。用户得有一台带公网 IP 的云主机,还得自己放行端口、签证书、配 DNS。
Cloudflare Tunnel 把「服务端」换成 Cloudflare 的边缘网络:本机 cloudflared 主动向外建立到边缘的长连接(出站 only),公网侧不需要任何监听端口,也不需要公网 IP——顺带白拿 CF 的 WAF / DDoS 防护与自动 HTTPS。
对 Fonu 的用户画像(家庭/个人 NAS)来说,这正好补上一类人:没有实体公网 IP、或不想为穿透长期租 VPS的人。
但要说清楚它替代不了什么(这决定了它是「并存」而不是「替换」):
| 场景 | frp | Cloudflare Tunnel |
|---|---|---|
| 内网 HTTP(S) 网站/面板(域名访问) | ✅ | ✅ 更省事(无需 VPS、无需放行端口) |
| 任意 TCP/UDP(游戏服、非 HTTP 协议) | ✅ | ⚠️ 需要访问端也装 cloudflared(cloudflared access tcp),不是通用 TCP 出口 |
| 客户端不需要额外软件的裸 TCP 端口 | ✅ | ❌ |
| 自持服务端 / 完全自主可控 | ✅ | ❌(流量必经 CF 边缘) |
| 大文件/视频流量 | ✅(自己带宽说话) | ⚠️ CF 条款限制非 Enterprise 的 CDN 视频/大文件用途,见 §七 |
所以定位是:HTTP 类公网访问走 Cloudflare 更划算,TCP 类与自主性要求高的仍走 frp。
二、同类项目(检索结果)
| 项目 | 做什么 | 对 Fonu 的借鉴 |
|---|---|---|
| WisdomSky/Cloudflared-web(≈451★,Vue) | Docker 镜像里打包 cloudflared + 简单 Web UI,用来 start/stop remotely-managed 隧道 |
最接近的同位产品:证明「面板管 cloudflared 进程」这个形态成立;但它的能力止步于开关,规则仍在 CF 面板里——这正是 Fonu 可以做得更好的地方(规则同源生成) |
| adyanth/cloudflare-operator(≈691★) | Kubernetes Operator,用 CF API 创建/管理 Tunnel 与 DNS | 演示了「API 驱动」的完整闭环;但需要 API Token + Account/Zone ID,是第二个凭据面(Fonu 第一轮不建议走,见 §六) |
| qingchencloud/cftunnel(≈338★) | 轻量隧道控制 | 佐证需求存在 |
| brenner-tobias/addon-cloudflared | Home Assistant 插件,locally-managed 与 remotely-managed 两种模式都支持 | HA 社区的做法可参考:两种模式并存,文档把差异讲透 |
| cloudflare/cloudflared | 官方客户端(Apache-2.0) | 我们的被托管对象;GitHub Release 提供多平台二进制 |
| 对照项:Pangolin / Tailscale Funnel / ngrok | 同类「免公网 IP」方案 | Tailscale Funnel 只开 HTTPS 且端口数量有限、ngrok 免费档收紧;CF Tunnel 免费档最宽松,这也是它值得优先支持的原因 |
docs/feature-benchmark-2026-09-24.md 里已经把 Pangolin 列为架构最近的同类项目;Cloudflare Tunnel 的差别在于:它把「服务端」外包给了 Cloudflare,Fonu 只需管好本机客户端。
三、cloudflared 的两种托管模型(选型的关键)
| locally-managed(本地管理) | remotely-managed(远程管理) | |
|---|---|---|
| 凭据 | cert.pem(cloudflared tunnel login 浏览器授权)+ <UUID>.json credentials |
一个 token(eyJ...,CF 面板生成) |
| 规则来源 | 本机 config.yml 的 ingress: |
CF 面板 / API(本地 config.yml 会被忽略) |
| 建隧道 | cloudflared tunnel create <name> |
CF 面板,或 POST /accounts/{id}/cfd_tunnel |
| DNS | cloudflared tunnel route dns <tunnel> <hostname> |
CF 面板自动建 CNAME |
| 与 Fonu 的价值取向 | ✅ 契合:反代规则由 Fonu 同源生成(和现在生成 frps.toml / nginx vhost 一个路子) |
⚠️ 冲突:规则跑到 CF 面板去了,Fonu 沦为「进程开关」 |
官方文档确认了这个分界(配置参考),社区也踩过坑:给 remotely-managed 隧道传 --config 时配置会被云端覆盖,日志里出现 No ingress rules were defined ... cloudflared will return 503(cloudflared#1029)。
结论:第一轮只支持 locally-managed。 若用户只想粘贴 token,提供「仅托管进程」的降级模式并在界面上明确写清「规则由 Cloudflare 面板管理」,不要让用户以为 Fonu 生成的规则生效了。
补充(参考 §九 后修正):这个二分法不够细。参考实现证明token 可以解码(base64 的 JSON,含
AccountTag/TunnelID/TunnelSecret),用它自己生成creds.json就能按 locally-managed 跑本地config.yml;再配合「云端 ↔ 本地 ingress 互相同步」,两种模式实际上是可切换的。所以 Fonu 的正确做法不是「二选一」,而是显式区分并同步:当前生效的是本地config.yml还是云端 ingress,以及「推送/拉取」两个动作。
健康探测(这点比 frp 更省事)
cloudflared tunnel --metrics 127.0.0.1:<port> run --config ... 会暴露 HTTP 端点,其中 /ready 在有到边缘的活跃连接时返回 200(CF 官方在 k8s livenessProbe 里就是这么用的)。Fonu 现在为了判断「隧道通不通」要绕 frps dashboard,还专门加过 tunnel_known 来区分「判不出来」和「不通」;CF Tunnel 则有明确的就绪端点,可以直接喂给现有健康链路。
四、本仓库可复用的面(已核对代码)
| 能力 | Fonu 现有实现 | 复用方式 |
|---|---|---|
| 二进制下载 / 启用 | Service.ListReleases(internal/frp/service.go:112)、ListBinaries(:120)、ActivateBinary(:258);internal/frp/runtime.go 的 fetchOfficialReleases / listBinaries / readActiveBinary / writeActiveBinary / versionFromBinaryPath |
cloudflared 同样发 GitHub Release,同一套框架泛化成「可指定仓库」即可(现在 URL 拼的是 frp 的 release 页) |
| 客户端进程托管 | internal/frp/manager.go:os.OpenFile(logPath, O_CREATE|O_APPEND|O_WRONLY, 0600) + cmd.Stdout/Stderr 重定向 + 状态/退出原因 + tailFile 读日志尾 |
与 cloudflared tunnel run 完全同构,可直接复用(日志追加、不截断的语义也一致) |
| 凭据加密与回显 | secret.Box + maskedToken = "********"(internal/frp/service.go:23)+ 「预览脱敏 / 下发原文」两分支约定(v1.2.12 刚修) |
token / credentials JSON 存加密字段;预览一律掩码 |
| 配置生成 | internal/frp/frps_template.go、internal/proxy 的 nginx vhost 模板 |
config.yml 的 ingress: 用同样思路生成,注释与安全提示的风格照搬 |
| 健康与可用率 | internal/monitor(Source 接口 + HealthRecorder)、migrations/026 的健康事件表、metrics_samples |
给 Source 加一个 provider(frp / cloudflared),/ready 作为判活依据 |
| 日志界面 / 公开状态页 | 日志页各页签、/status 公开状态页(默认关闭 + 访问码 + 限流) |
新隧道类型直接进现有页面,不用另造一套 |
| 规则模型 | frp.Proxy{ServerID, Type, LocalIP, LocalPort, CustomDomains, Options}(internal/frp/model.go:186) |
不再需要 ServerID 时用一个 provider 字段代替(见方案 B) |
五、三个方案
方案 A:独立模块「Cloudflare 隧道」(推荐第一轮)
新增一个与「公网服务端(FRP)」并列的模块,不碰现有 frp 规则模型:
- 管理一份 cloudflared 二进制(复用 §四 的下载/启用框架)。
- 管理 N 个隧道实例,每个实例 = 一份
config.yml+ credentials + 日志文件 + 子进程。 ingress规则由 Fonu 生成:从本机已有的反代规则里挑「要暴露的域名」,映射到http://127.0.0.1:<本地端口>,模板与 nginx vhost 同源风格;末尾固定给 catch-allservice: http_status:404(CF 要求最后一条兜底)。- 健康:
--metrics+/ready,写入现有健康与可用率链路;通知复用(隧道断开/恢复)。 - 前端:与「公网服务端」同构的列表 + 详情(状态 / 日志 / 配置预览 / 下发)。
优点:改动封闭、不动现有模型、可独立上线、风险低。 代价:规则要在两处维护(frp 规则 vs CF 隧道规则)——这是方案 B 要解决的。
方案 B:把「隧道出口」抽象成 provider(v2 方向)
在规则上加 provider: frp | cloudflare(frp.Proxy 增字段,配套迁移),规则本身只说「哪个域名 → 内网哪个端口」,出口由 provider 决定:
- 好处:一条规则可在 FRP / CF 之间切换,健康、可用率、状态页、漂移检测天然统一。
- 成本:动模型 + 迁移 + 前端多处(规则表单、健康四段、公网反代页),且
ServerID的语义要重新定义(CF 侧没有服务端)。 - 建议:等方案 A 稳定、用户真的需要在两种出口间迁移规则时再做。
方案 C:只做引导(不接管进程)
只生成 config.yml 与 DNS 指引,让用户自己跑 cloudflared。
不建议:不接管进程就没有状态、日志、健康、可用率,等于放弃 Fonu 的全部价值。
六、推荐落地路径(分阶段)
阶段 1:只读与引导(最低风险,先验证需求)
- 新增「Cloudflare 隧道」入口:粘贴 token(remotely-managed)或上传 credentials JSON + tunnel UUID(locally-managed),凭据加密存储。
- 生成
config.yml预览(脱敏,沿用 v1.2.12 的预览/下发两分支约定)并把文件写到<DataDir>/cloudflared/<name>/config.yml。 - 界面给出 CF 侧操作指引(建隧道、CNAME、
cloudflared tunnel route dns),不接管进程。 - 明确提示模式差异:locally-managed 才由 Fonu 生成规则。
阶段 2:托管进程与健康(核心价值)
- 把 §四 的 release/binaries 框架泛化,支持下载
cloudflared并启用指定版本;进程托管复用Manager(日志、状态、退出原因、tailFile)。 --metrics 127.0.0.1:<port>+/ready接入internal/monitor:新增 provider 判活,接入现有通知与metrics_samples可用率。- 子命令支持:启动 / 停止 / 重启 / 重载配置 / 查看日志(与「公网服务端」的操作面板一致)。
阶段 3:规则同源与界面完善
- 从本机反代规则推导
ingress(勾选要暴露的域名),生成后一键下发并重启;末尾自动补 catch-all。 - 前端补齐:状态卡、日志页签、配置预览(脱敏)、与 VPS 实际文件的漂移检测(沿用「配置漂移」的交互)。
- Access(Zero Trust)相关只做诊断提示(例如「此域名未启用 Access 保护」),不代配置策略。
阶段 4(可选,需单独评估)
- 接 Cloudflare API 自动建隧道与 DNS:需要 API Token(权限
Account: Cloudflare Tunnel: Edit+Zone: DNS: Edit)+ Account ID + Zone ID。这是第二个凭据面,收益是省掉几步手工操作,代价是多一份高权限凭据要保管——建议等前面稳定后再评估,并且只在用户显式开启时启用。
七、风险与边界(务必写进功能说明)
条款与合规
- Tunnel 本身免费、不限条数/带宽,但 Cloudflare 的 CDN 条款限制「用 CDN 提供视频与其他大文件」(非 Enterprise 需购买 Stream/Images 等付费服务)。社区里这条措辞有过调整,但仍应视为风险:用 CF Tunnel 做影音/大文件分发不在我们的推荐用法内,界面上要提示。
- TryCloudflare(快速隧道:
cloudflared tunnel --url http://localhost:PORT)官方明确「不保证 SLA 与可用性,仅供测试与开发」,域名随机、每次重启变化——不作为正式功能,最多做成「临时演示」按钮。
网络可用性
- 中国大陆访问 CF 边缘的延迟与稳定性不稳定,这对 Fonu 的用户群是现实问题:建议在文档与界面上对比说明「CF 适合海外访问优先的场景,国内链路以 frp + 自持 VPS 更可控」。
- 出站 only 意味着 VPS 上不需要任何放行端口,但也就读不到「CF 侧有哪些域名指向了这条隧道」——相关校验只能靠
cloudflared自身命令,不能靠 agent。
实现边界
- 不做 remotely-managed 的规则生成(会被云端覆盖,见 §三)。
- 不代配 Access 策略(只提示状态)。
- 不改现有 frp 链路:CF Tunnel 是并存出口;
internal/frp的规则、健康、状态页语义保持不变。 - 不做通用 TCP 出口:需要访问端装
cloudflared的场景超出「NAS 面板」的定位,只做说明。 - 凭据全部走
secret.Box加密 + 掩码回显;日志与 API 响应绝不出现明文 token(沿用maskedToken与「预览脱敏」约定)。
九、参考实现分析:cf-tunnel-manager(用户自有项目,Gitee li-hua-88/cf-tunnel-manager)
项目:Tunnel-Cloudflared-Manager v1.0.1,Rust + Actix-web + Tokio + Serde,前端原生 JS + Tailwind(
static/),JSON 文件存储,MIT;Linux systemd(tcm/cftm运维脚本)+ Docker 两套交付。 本节结论来自逐个读到源码的模块:src/services/{tunnel,binary,cloudflare_api}.rs、src/models/tunnel.rs、src/utils/{config_helper,paths}.rs、Cargo.toml。
9.1 它的定位与能力
| 维度 | 它做了什么 |
|---|---|
| 隧道类型 | 命名隧道(token 或 config-file 启动)+ 快速隧道(--url) |
| 进程管理 | TunnelProcessManager:HashMap<名称, Child> + 独立的 login_process + 快速隧道 URL 缓存 |
| 日志 | tokio::process 逐行读 stdout/stderr → WebSocket 广播(tunnel-log 事件),前端实时滚动 |
| 指标 | 每 2 秒抓 cloudflared 的 Prometheus 端点 → 同样用 WebSocket 广播(tunnel-metrics) |
| 二进制 | src/services/binary.rs 自管下载/替换/检测,不要求用户预装 |
| 账号模式 | --origincert + tunnel create + tunnel route dns,把生成的 creds.json 搬进自己的 data/tunnels/<名>/ |
| 云端同步 | src/services/cloudflare_api.rs 能按 tunnel 拉取/推送 ingress 配置(fetch_tunnel_config / push_tunnel_config) |
| 登录与安全 | JWT + bcrypt 管理员账号,默认 admin/admin666(首次登录强制改密) |
| 网络调优 | protocol(auto/http2/quic,Windows 或检测到代理时回落 http2)、ha-connections、edge-ip-version、originRequest(caPool/noTLSVerify/httpHostHeader)、代理环境变量开关 |
9.2 值得直接借鉴的六个做法
① token 可以解码成凭据,于是 token 模式也能本地管规则
initialize_token_tunnel 把 CF 隧道 token 解成 {AccountTag, TunnelID, TunnelSecret} 并写出 creds.json + config.yml——即「用户只给一个 token,但规则仍由面板本地生成」。这直接提升了 Fonu 方案的上限(§三 的补充已按此修正)。
② metrics 端口不去猜,从日志里读出来
命名隧道启动时故意不传 --metrics,让 cloudflared 用默认端口段(20241-20245),然后从 stderr 解析 INF starting metrics server on 127.0.0.1:65432/metrics 拿到真实端口——天然避开端口冲突(Fonu 现在给 frps dashboard 固定端口,多实例时会撞)。
③ localhost 必须归一化成 127.0.0.1
add_tunnel_endpoint 里把 localhost 换成 127.0.0.1,注释写明「避免 Cloudflare 将其转换为本地网络 IP」。这是 CF 侧的真实坑,Fonu 生成 ingress 时要照做。
④ 始终保留最后一条 catch-all
新增端点插在「数组倒数第一位之前」(insert_pos = len - 1),末条永远是 service: http_status:404。Fonu 改 ingress 时必须沿用这个不变式,否则配置校验不过。
⑤ 带宽指标:官方 metrics 没有 HTTP/2 字节数,它做了系统级兜底
- QUIC 下直接读
quic_client_receive_bytes/quic_client_sent_bytes/quic_client_smoothed_rtt。 - HTTP/2 下官方无字节数,改用按进程采 TCP 连接字节:Linux 走 netlink
SOCK_DIAG_BY_FAMILY+/proc/<pid>/fd取 socket inode;Windows 走GetExtendedTcpTable+GetPerTcpConnectionEStats(需要管理员,失败时给windows_estats_requires_admin降级原因)。 - 并且只统计公网远端 IP(过滤私有/回环/链路本地/
100.64/10CGNAT),延迟兜底用主动 HEAD 探测 ingress 里的公网 hostname(带?__cf_probe=<nonce>+ no-cache)。
对 Fonu 的意义:这一块可以先不做(我们已有规则级流量与可用率),但「降级要给出明确原因而不是空白」这个原则要学。
⑥ Windows 下起子进程要隐藏控制台窗口
creation_flags(CREATE_NO_WINDOW)(0x08000000)。Fonu 本机在 Windows 上跑,托管 cloudflared.exe 时必须带上,否则会闪黑窗。
9.3 与 Fonu 的差异(决定「借鉴什么、不借鉴什么」)
| 维度 | cf-tunnel-manager | Fonu 该怎么做 |
|---|---|---|
| 职责 | 专做 Cloudflare Tunnel 的一个独立面板 | 把 CF 作为第二条出口并入现有规则/健康/通知/状态页体系 |
| 存储 | JSON 文件(data/*.json)+ data/tunnels/<名>/ |
继续用 SQLite + 迁移;凭据进 secret.Box 加密字段 |
| 规则来源 | 面板自己的 ingress 列表(+ 云端同步) | 从本机已有反代规则推导(同源生成),避免第二份手工维护 |
| 健康 | metrics 端点 scraping + 主动探测(仅前端展示) | 接入 internal/monitor 的 Source/HealthRecorder,落库可用率 + 复用告警与通知 |
| 实时日志 | WebSocket 广播(专为「看着它滚」设计) | 沿用现有「读日志文件 + 日志页」模型(与 frpc 一致,无需引入 WS) |
| 多实例 | 多隧道并行(每隧道一个子进程) | 同模;但用 SQLite 建 tunnels 表而不是内存 HashMap |
| 认证 | 自带 JWT + 账号体系 | 复用 Fonu 现有会话 + API Token |
9.4 对方案本体的修订建议
- 方案 A 的第一阶段就加「凭据导入」两条路:
token(解码出 creds.json)与cert.pem + credentials JSON(账号模式),二者最终都落到「本地config.yml由 Fonu 生成」。 - 阶段 2 把「metrics 端口从日志发现」写成实现约定,不要固定端口。
- 阶段 3 增加「云端 ↔ 本地同步」两个动作(拉取 / 推送),并在界面上标明当前生效侧——这是参考项目比原方案更完整的地方。
ingress生成器锁定三条不变式:末条 catch-all、localhost→127.0.0.1、插入位置在 catch-all 之前;并补一个「生成后自检」的纯函数测试(参照本仓maskFRPSSecrets的测试写法)。
十、IP 优选:能不能做、能做到哪一步
结论一句话
隧道侧(本机 cloudflared → CF 边缘)可以优选,访问侧(浏览器 → CF 边缘)不行。 而国内用户最在意的那一段延迟往往在访问侧——所以不要把它宣传成「提速神器」,它的收益是可控但有限的。
隧道侧:三条可用手段(已核对官方文档与变更日志)
| 手段 | 具体做法 | 适用与代价 |
|---|---|---|
| 选协议 | --protocol quic / http2 |
国内 QUIC(UDP 7844)常被 QoS 掉,http2(TCP 7844)反而稳;这是成本最低、收益最直接的一项 |
| 选地址族 | --edge-ip-version 4 / 6 / auto,或环境变量 TUNNEL_EDGE_IP_VERSION |
⚠️ 2026.4.0 起默认值由 4 改成 auto(官方 CHANGES 里的 Breaking Change)——auto 会跟着系统解析器走,国内环境若 IPv6 路由差就可能反而变慢。建议 Fonu 显式下发 --edge-ip-version 4(除非用户自己有 IPv6 好线路) |
| 优选边缘 IP | 对 region1.v2.argotunnel.com / region2.v2.argotunnel.com 做延迟测速,选中最快的官方边缘 IP,写 hosts 覆盖解析 |
官方文档给出固定端点与端口:这类域名指向 CF 的 IPv4 段(198.41.192.7198.41.192.127、162.159.234.1162.159.234.10)与 端口 7844(TCP/UDP)。这是社区「Tunnel 优选 IP」的通行做法 |
优选时两条不能错的约束:
- 两个 region 都要覆盖。官方预检文档要求健康部署有四个活跃 replica、同时连上
region1与region2(或对应地区域名)——只改其中一个域名,另一半连接会跑到未优选(乃至不通)的路径上,净效果可能是变差。 - IP 列表不能硬编码。CF 改过端点与 hostname(例:
proxy-dns整条功能已在 2026.2.0 被移除),优选表要么给默认值 + 可配置,要么每次从官方 DNS 拉候选集再测。
关于实例数:--ha-connections 决定每个 region 开几条连接,也是「多路择优」的天然手段(参考实现 §9.1 已把它做成设置项)。
访问侧:Tunnel 模式下做不到
用 CF Tunnel 时,公域域名必须 CNAME 到 <tunnel-uuid>.cfargotunnel.com 并且开启代理(橙云)——解析结果由 CF 决定,用户无法自选边缘 IP。社区那套「测速 + 自选 IP」之所以常见,是因为他们用的是「CNAME 到优选 IP + 关闭橙云 + 自己回源」的方案;那恰好是 Tunnel 不能走的路(关掉代理就没有 Tunnel 了)。
也就是说:换域名解析 / 让访客改 hosts 都不现实,访问侧这一段在 Tunnel 架构下就是交给 CF 的。
对 Fonu 方案的落点
| 阶段 | 做什么 | 依据 |
|---|---|---|
| 阶段 2(建议直接做) | 「网络调优」三项做成设置项:protocol(默认 http2)、edge-ip-version(默认 4)、ha-connections;以命令行参数下发 |
参考实现已验证可行,且改一项就能治国内 QUIC 被打压的场景 |
| 阶段 3(可选) | 「边缘优选」工具:并发探测官方 IPv4 段的 TCP 7844 握手延迟 → 生成「两个 region 各 1~2 个优选 IP」的 hosts 建议;页面展示而不是代写 hosts(Windows 改 hosts 需管理员,Fonu 不应越权),并提供「复制这段内容」+ 生效检测 | 沿用本仓「不越权、降级要说明原因」的口径 |
| 阶段 3(可选) | 优选前后对比:用已有的 metrics_samples 延迟/可用率序列展示效果,而不是另造一套测速图 |
复用 §四 的健康与指标链路 |
必须写进功能说明的三句实话
- 优选只影响「本机 → CF 边缘」这一段;访客到自己那侧 CF 边缘的那段,Fonu 与用户都控制不了。
- 所以它不是「翻墙提速」类工具:国内访问 CF 的稳定性受链路与运营商影响,优选只能把「本机出口到边缘」这一段挑好。
- 官方端点会变(见上),因此把所有 IP/域名做成可配置 + 有默认值 + 可一键恢复默认。
十一、给用户的一句话结论(可直接对外)
Fonu 现在支持两类公网出口:frp(自持 VPS,任意 TCP/UDP,完全自主)与 Cloudflare 隧道(无需公网 IP 与 VPS,HTTP 类最省事,自带 CF 防护)。 要裸 TCP 端口、要完全自主,用 frp;要让内网 Web 服务零端口暴露地上公网,用 Cloudflare 隧道。 Cloudflare 隧道还提供网络调优(协议 / 地址族 / 连接数)与边缘 IP 优选(仅作用于本机到 CF 边缘这一段,访客侧无法自选)。
说明:本文只做方案分析,未改动任何代码。实施时沿用本仓库既有约定:每步验证
go build/vet/test+vue-tsc/vite build、agent 行为变更递增AgentVersion、提交同批更新CHANGELOG与VERSION、密钥相关内容必须过一遍「预览脱敏 / 下发原文」两头检查。