Nodus는 frpc의 Web 관리 패널로, frp 클라이언트, 내부망穿透 프록시 규칙, 연결 상태를 한곳에서 관리합니다. 설정 수정이나 로그 확인 같은 터미널 작업을 브라우저 클릭으로 대체합니다. 오픈소스 프로젝트 podux에서 파생되었으며 데이터 구조가 호환되어 기존 사용자가 그대로 마이그레이션할 수 있습니다. 주요 기능은 다중 노드 관리, 시각화된 프록시 규칙, 실시간 로그, 네트워크 모니터링, 데이터 대시보드, 권한 관리, 구성 가져오기이며, 스크립트·Docker·바이너리 세 가지 방식으로 배포되고 기본 계정 비밀번호가 없습니다. 보안 측면에서는 역할 권한 상승 취약점을 수정했고 민감한 값이 로그에 남지 않도록 했습니다. 이틀간 일곱 번의 릴리스를 내놓은 초기 v0.0.x 단계이며, Apache 2.0 라이선스입니다. 중요한 전제는 frps 서버를 직접 배포해야 하며 Nodus는 클라이언트 측만 관리한다는 점입니다.
人在外面,想连回家里内网的某台机器。于是打开终端,ssh 上去,vim 打开 frpc.toml,把端口改了一个数字,重启 frpc,然后盯着日志看它有没有起来。
改对了,长舒一口气;改错了,日志刷了一屏英文,从头排查。
如果你也在用 frp 做内网穿透,这个循环大概率眼熟。而我一直想问的是:为什么 2026 年了,管几个内网穿透规则还跟在编辑器里搬砖一样?
于是就有了 Nodus。
项目入口:本站项目列表 · Nodus 仓库 · 最新发布。本站项目卡片会打开对应仓库,下载、文档和问题反馈仍以仓库为准。
一、30 秒说清楚:Nodus 是什么
一句话:Nodus 是 frpc 的 Web 管理面板,用来集中管理 frp 客户端、内网穿透代理规则与连接状态。
具体说:
项目在这里:
Nodus 项目仓库(GitHub)。
先交代来源:Nodus 是从 podux 这个项目来的。podux 已经把"给 frpc 做个面板"这件事跑通了,Nodus 是在它基础上的二次开发——数据结构保持兼容,所以老用户的 pb_data 可以直接拷过来(第七节细讲)。我从它那儿拿了什么,又改了什么,具体看下面的对比。
一句话版本,我自己的说法是:把"配置文件 + 终端 + 猜状态"变成"浏览器里点几下"。
顺便说一个观察(这是我的观点,不是官方定位):frp 自带的 dashboard 以服务端(frps)视角为主,看的是"这台服务端上都有哪些代理在跑";而日常要反复增删改查、盯着看日志的,往往是你手上的客户端那侧。Nodus 想补的就是这个位置。
和原项目 podux 的区别:我改了什么
先说明来源:podux 是上游,Nodus 是从它来的,不是从零重写。所以下表列的都是增量——基本盘(多节点、代理规则、日志、配置导入)在 Nodus 里原样保留,我动的是它之外的部分。两个仓库都在更新,具体以各自 README 为准。
区别点
Nodus 相对 podux 的变化
上游与数据兼容
数据结构与 pb_data 兼容,podux 的老数据可以直接拷进 Nodus,不用重配一遍
网络监控
新增延迟探测与服务器地理位置信息
数据大盘
新增节点拓扑与连接统计的可视化视图
权限模型
新增管理员 / 普通用户两级角色,写操作必须是管理员;v0.0.3 专门修了一版角色提权漏洞
迁移工具
新增 migrate-to-nodus.sh,支持 podux / frpc-hub / frpc 三种来源,带 --dry-run 预览与自动备份;迁移指南里还附了一段可以直接粘给 AI Agent 的迁移指令
工程与文档
独立的 v0.0.x 版本节奏、golangci-lint 清零、内置 frp 跟到 v0.71.0;中文文档五篇(快速开始、迁移指南、配置说明、安装部署、API 与开发)
许可与协作
Apache 2.0,问题直接在 GitHub issue 走
一句话概括区别:podux 证明了方向,Nodus 把它补成一个能长期维护、能给别人接手的项目——多节点之外补了监控和大盘,配置之外补了权限,升级之外补了迁移路径。
Nodus 管理 frpc,不替你部署公网 frps。访问业务服务时,数据经过隧道;打开面板看到一个节点,并不等于业务已经可以从外面访问。
二、frpc 到底哪里难用:三个老毛病
先说做这个面板的原因。frp 本身是个非常好的项目,但它的客户端日常使用,有三个反复出现的摩擦点:
其一,一切都在 frpc.toml 里。
改一个端口要动文件、要重启进程;写错一个字段,客户端起不来,而原因只在日志的某一行里。配置即代码,可惜没人给它做 lint,也没人给它做回滚。
其二,多节点 = 多开。
家里一台机器、云上一台 VPS、单位一台,每个节点一份配置、一份日志、一个进程。想看第三个节点的状态,就得再开一个终端窗口,再 ssh 一次。
其三,"它到底连上了吗"是玄学。
没有一个直观的全局状态视图。连接断没断,得翻日志、ping 一下、靠猜。
这三条是我在实际使用 frpc 时反复撞到的摩擦点——也正是我想用一个面板解决掉的三件事。
三、现在能用的九项功能
README 里写的是"基于当前代码实现",也就是说下面这些不是路线图,是现在就能用的东西:
功能
它解决什么
多节点管理
同时接入多个 frps 服务器(frpc 客户端节点),统一启动 / 停止 / 重载
代理规则管理
可视化配置 tcp / udp / http / https 代理(stcp / xtcp 在界面中已预留)
连接与日志
查看节点运行状态,实时输出 frpc 日志
网络监控
延迟探测与服务器地理位置信息
数据大盘
节点拓扑与连接统计
开机自启
节点配置 autoConnection 后随服务自动启动
配置导入
导入现有 frpc.toml,批量生成服务器与代理
权限控制
管理员 / 普通用户角色,写操作需管理员
版本检查
界面内查看当前版本与最新 Release
其中几项要单独说:
常规设置可以分别调整延迟检测和位置检查的间隔。图中显示 30 秒和 60 秒,是本地演示环境的设置值,不是测得的网络延迟。实际节点是否连通,还要看连接状态、日志和业务访问结果。
四、5 分钟跑起来:三种部署方式
Nodus 默认端口是 8090。三种方式任选其一。
但先说一个不能省的前提:只装 Nodus,你什么都穿不通。Nodus 管的是客户端(frpc)这一侧,隧道本身要靠 frps 服务端。你必须先在一台有公网 IP 的机器上把 frps 部署起来,面板里的节点才有地方连;不部署 frps,Nodus 装得再漂亮也只是个空壳。
frps 的最小配置长这样:
起服务端:frps -c frps.toml。同时记得在云厂商的安全组 / 防火墙里放行 7000 以及你各条代理要用到的端口,否则客户端照样连不上。配置里的 auth.token 记下来,等下在面板"添加节点"时要填。如果你已经有在跑的 frps,这一步直接跳过。
方式一:一键脚本
支持的环境变量:PORT(默认 8090)、IMAGE、CONTAINER_NAME、VOLUME_NAME、MODE=docker|binary。完整说明见仓库里的搭建教程。
方式二:Docker
或者用仓库自带的 compose:
想锁版本(生产环境建议锁):
方式三:二进制
到 Releases 下载对应平台的压缩包(文件名含版本号),然后:
装完访问 http://<服务器>:8090,按界面提示创建管理员账号。
五、关于登录:为什么没有默认账号
这是很多人第一次上手会愣一下的地方:
Nodus 没有预置的默认账号密码,首次访问时引导你自行创建。
我认为这是必须的。自托管工具最经典的翻车方式之一,就是"装完忘了改默认密码",然后被扫描器扫到。没有默认密码,就不存在这个事故。
系统有三个入口:
登录入口
地址
说明
用户端(主界面)
http://<服务器>:8090
首次访问创建的邮箱 + 密码,用于管理服务器和代理
管理后台(PocketBase Admin)
http://<服务器>:8090/_/
首次访问时创建的超级管理员邮箱 + 密码,用于数据库管理
frps 服务端令牌
—
添加服务器节点时需填写 frps 的 auth.token,由你的 frps 配置决定
两点补充:
编辑服务器时,先对上 frps 的主机、连接端口、版本和认证,再看日志与传输选项。认证区里的令牌保持隐藏;TLS 证书字段属于连接设置,不是业务服务的端口。图中是本地演示节点,自动连接关闭,未建立真实隧道。
用户端账号、PocketBase 超级管理员和 frps 令牌不能互换。图里不放任何实际密码;添加服务器需要的令牌,应和已有 frps 配置对应。
六、一条典型工作流:装好之后我会怎么用
这七步跑完,你会发现原来那套"ssh + vim + 重启 + tail"的循环,基本消失了。
用一个 TCP 服务把字段对上
第一次新建规则,不必同时配置好几个服务。假设本地 Web 服务监听在 8080,准备通过 frps 的 18080 端口访问它,先确认 Nodus 所在机器能访问这个本地服务,再填代理。
服务器页填的是 frps 的地址、连接端口和认证方式;它不是你的业务服务地址。上图用本机 127.0.0.1:17000 做界面演示,节点保持停止,未连接真实 frps,也没有开放公网端口。正式使用时,换成你已经部署好的 frps 地址、端口与令牌。
在代理页选中服务器,名称填 demo-web,类型选 TCP;本地地址和本地端口指向业务服务,远程端口填 frps 一侧对外提供服务的端口。截图里的 8080 → 18080 是字段映射示例。这张图截于填写阶段;补充演示中已把规则保存到本地,但节点仍未启动,不代表隧道已通。
本地地址里的 127.0.0.1 指的是 frpc 运行环境自身。如果 Nodus 跑在容器里,它通常不是宿主机,更不是另一台内网设备。先确认这层地址,再检查 frps 的监听端口、认证与防火墙。规则保存后还要启动节点、看日志,并从外部访问业务端口;“已保存”和“服务可访问”是两次不同的检查。
选择 HTTPS 后,表单仍按域名或子域名组织规则。这个例子填本地 127.0.0.1:8443 和子域名 photo,只用于对照字段,没有提交规则、配置证书或验证 TLS 访问。选了 HTTPS 类型,不等于证书和服务端监听已经准备好。
首次跑通后,再决定是否开启自动连接。已有配置则优先走导入,不必照着编辑器逐条重填。字段说明见配置文档。
换成 HTTP 后,表单不再让你填 TCP 的远程端口,而是出现自定义域名与子域名。这里用本地 3000 端口和 blog.example.com 做示例;域名只是占位,没有配置 DNS,也没有验证公网访问。真正使用时,还要对上 frps 的 HTTP 监听和域名解析。
列表把两个例子放在一起:TCP 一行显示远程端口,HTTP 一行显示域名。规则“已启用”和连接“在线”是不同状态;截图中两条规则都已保存、已启用,但因节点没启动而保持离线。不能看到“已启用”就认为服务已经能从外面访问。
图用正文的端口例子解释连接关系,不是已经运行的拓扑。frps 连接端口、对外业务端口和内网服务端口不同;容器里的 127.0.0.1 还要按容器环境理解。
UDP 表单保留本地地址、本地端口和远程端口;图中用 5353 → 15353 做字段示例。端口数字只是演示,不代表对应服务已经运行。这条规则没有提交,节点也没有启动;正式使用时还要检查 UDP 的安全组、防火墙和真实服务响应。
七、老用户搬家:三种来源都能迁
如果你本来就在用别的工具,迁移路径是这样的:
1. 来自 podux(github.com/luckjiawei/podux)/ frpc-hub
数据结构兼容,直接拷贝 pb_data 即可无损迁移。
2. 来自原生 frpc
用配置导入功能接入现有 frpc.toml。
3. 用脚本一把梭
脚本会自动备份、复制数据、启动 Nodus 并导入 frpc.toml;支持服务器上已有的 podux / frpc-hub / frpc 三种来源,找不到旧数据时按全新安装处理。
迁移指南里还有一个我觉得相当务实的细节:里面准备了可以直接发给 AI Agent 的自动迁移指令,以及手动迁移步骤和回滚方式。也就是说,你可以把那段指令直接粘给 Claude 或 Cursor,让它替你在服务器上跑完。这类"给 AI 用的文档"以后应该会越来越多。
现有 frpc.toml 可以先解析成预览,逐条核对服务器、代理名称、本地地址和远端字段。图中检测到相同地址与端口的服务器,并提供是否覆盖的选择。这次只解析示例 TOML、停在预览,没有确认导入或覆盖任何节点;正式迁移前先备份旧数据,再决定保留、合并还是覆盖。
原生 frpc 走配置导入,podux/frpc-hub 则涉及兼容的数据目录。脚本执行前先预览和备份,再核对结果;图不是本次已经完成了一次迁移的证明。
八、往深了说:它是怎么造出来的
如果你只关心用法,上面就够了。这一节写给想读源码、或者想自己维护类似项目的人。
技术栈
组件
版本
Go
1.25
PocketBase
0.35.0
frp
0.71.0
React / TypeScript / Vite
19 / 5.9 / 7
为什么选 PocketBase
PocketBase 给了一个 Go 内嵌的后端骨架:SQLite 存储、鉴权、文件、管理后台,全在一个二进制里。对这种"个人或小团队用的自托管面板"来说,它的性价比很高——省掉了自研用户系统,/_/ 还能直接当数据库控制台用。
代价是:表结构管理必须有纪律,否则版本一升就乱。所以这个项目把 migrations/ 定为 PocketBase 集合结构的唯一真相源,而且要求每个迁移都是可回滚的 .go 文件;不允许通过改线上 SQLite、或者在管理后台手动改 schema 来绕过它。
分层与依赖方向
依赖方向是固定的 interfaces → application → domain,基础设施实现领域层定义的接口,main.go 负责集中装配(启动、hooks、监控调度、静态资源服务)。这条规矩看着朴素,但它决定了项目在长出十几个月后还能不能改得动——接口层永远不许直接摸数据库。
请求进来先经过传输层和用例编排,持久化实现则遵守领域层定义的接口。箭头表示依赖或装配关系,不是网络数据包在这几层间移动的真实抓包;领域层不依赖 PocketBase。
前端:site/ 目录
一个容易误会的点顺便澄清:docs/ 文档站是 VitePress(Vue 生态),但这不代表应用前端用了 Vue——应用前端是 React。文档是独立的一站。
单二进制背后的小设计
site/dist 会被拷贝到 pb_public/,再由 main.go 用 go:embed 打进 Go 二进制里。所以前端构建产物是 Go 构建的前置条件——这也是为什么验证流程长这样:
单二进制不是省掉前端构建,而是把已构建的前端资源嵌入进去。没有 pb_public 里的资源,后面的 go:embed 就没有可嵌入的文件。
九、安全:做了什么,也明确不做什么
这类工具的威胁模型其实很朴素:它手里握着你所有内网入口的凭据。所以仓库里写了几条红线:
写项目文档的人愿意把"我们明确不做什么"列出来,通常比列功能更能说明成熟度——至少说明写的人真的想过哪里会出事。
十、版本节奏:两天七个版本
截至发稿,版本历史是这样的:
日期
版本
内容
2026-09-25
v0.0.1
Nodus 首个版本
2026-09-25
v0.0.2
安全加固与全面缺陷修复
2026-09-25
v0.0.3
修复角色提权漏洞与文档资产名
2026-09-26
v0.0.4
文案修正、golangci-lint 清零、UI 作者署名更新
2026-09-26
v0.0.5
登录说明、版本号修复、代理页面访问按钮
2026-09-26
v0.0.6
内置 frp 升级至 v0.71.0
2026-09-26
v0.0.7
frp 代理名不再拼接 ID 后缀,frps 显示友好名称
我的读法是这样的:
同时它也说明另一件事:这是个非常早期的 v0.0.x 项目。迭代快是优点,但你得接受它还在动。
十一、它适合谁,不适合谁
适合你,如果:
先掂量一下,如果:
十二、写在最后
回到开头那个场景:改一个端口,原来要 ssh、vim、重启、看日志四步。现在是打开面板,改,保存,它自己重载。
Nodus 想做的事情,说白了就一句话:让内网穿透的管理回到"点几下鼠标"的正常水平。
它现在还很小,star 也不多。但一个两天推了七个版本、把提权漏洞放在第三版就修掉、把"别把密钥打进日志"写进红线的项目,值得你花五分钟部署一个试试——前提还是那句:frps 得你自己先备好。
有问题直接开 issue,我都在。
附录:速查卡
前提:先有 frps(不部署就用不了)
这个 auth.token 就是面板"添加节点"时要填的那个。
部署
迁移
三个入口
忘记密码:进 /_/,在 fh_users 集合中重置。