Nfrp 0.5.4发布修好了一大堆安全问题
NFrp 0.5.4 发布 | Rust 写的 frp 兼容内网穿透 这次把安全债还完了
上面的视频是这次发布宣传片 想先看效果可以直接拖进度条到有界面的那一段
这次发的是什么
桌面端 NFrp 0.5.4 手机端 NFrp for Android 1.0.4 两个一起发
NFrp 是 fatedier/frp 的 Rust 重实现 线协议 v1 与 v2 全部兼容 跟官方 frps / frpc(对着 v0.71.0 逐包抓密文对拍过)可以直接互连 第三方 frp 平台下发的配置拿来就能用
默认走 v1 跟官方默认值一致 所以官方那头的客户端和服务端一个字都不用改就能接上
常驻内存约 3.5 MB 同样负载下 Go 版 frps 是 28.8 ~ 31.8 MB 单文件丢上去就能跑 没有运行时依赖
为什么又写一个 frp
frp 本身很好 但有三件事一直没被解决
一是内存 二是跨平台分发 三是安全债 frp 的历史包袱不轻 而内网穿透这个东西天生就长在公网上 攻击面全开着
NFrp 就是冲这三条去的 Rust 写内存省一大截 Windows / Linux / Linux arm64 / Android 四个平台原生二进制 顺手把三轮安全审计共 52 项问题全还了(17 + 11 + 24 详见仓库内 SECURITY-FIXES.md)
代理类型八种 一个不缺
跟官方清单完全对齐 不是我挑着做的
| 类型 | 干什么用 |
|---|---|
tcp |
最常用的端口转发 |
udp |
UDP 转发 每个代理只占一条工作连接 靠访客地址分会话 |
http |
按域名路由 支持 locations 前缀 Basic Auth Host 改写 自定义请求与响应头 |
https |
只嗅探 ClientHello 里的 SNI 做路由 不终止 TLS 证书仍由内网服务自己提供 |
tcpmux |
HTTP CONNECT 复用 多条代理共用一个服务端端口 支持 routeByHTTPUser 二级路由 |
stcp |
私密隧道 服务端不开公网端口 secret_key 校验 + allow_users 白名单 |
sudp |
跟 stcp 同一套鉴权 数据面走 UDP 同样不占公网端口 |
xtcp |
UDP 打洞 + QUIC / KCP 直连 数据不经服务端 打不通自动回退中继 |
传输层能折腾的地方都在
- frp v1 / v2 双线协议 默认 v1 想显式上 v2 就
transport.wireProtocol = "v2" - QUIC 传输 1-RTT 握手 流级多路复用
- KCP 弱网通道 既能当 xtcp 的直连通道 也能单独当传输协议用
- yamux 多路复用 控制连接和工作连接挤同一条 TCP
- TLS 加密 含官方那套自定义首字节伪装 服务端自动生自签证书
- WebSocket / WSS 同一端口按路径自动认 能穿只放行 HTTP 的防火墙
- Proxy Protocol v1 / v2 把真实客户端 IP 透给 Nginx / HAProxy
客户端插件九个 全实现了
http_proxy socks5 static_file unix_domain_socket http2http http2https https2http https2https tls2raw
frpc 自己就能当前置代理 也能当静态站点服务器 也能当 TLS 终结器
0.5.4 这一版修的是什么
三轮审计 52 项 0.5.4 这一轮 24 项 其中 5 个高危 最要紧的三个
负载均衡组的密钥一直形同虚设 原先只比对组名 任何持合法 token 的客户端只要知道别人的组名就能挤进那个组 那个端口上约 1/N 的连接会被转到攻击者的服务
重复 Content-Length 可以走私请求 原先只读第一个却把两个都转发给内网服务 现在重复的 非数字的 带符号的一律 400 转发前还会做同名头去重
服务端能让客户端去连任意地址 也就是 SSRF 服务端可以指使客户端去连云元数据服务或内网主机 现在远程下发只允许回环地址
另外几项也值得单独说
- 热重载能绕过面板鉴权 删掉配置里的
dashboard_port行就能让安全检查误以为面板没开 而监听器其实还活着 这是 0.5.3 修复的漏网之处 - 客户端 store 恢复路径绕过安全校验 store 文件里写
plugin_local_path这类字段 重启后直接生效 能读任意本机文件 - 未认证连接可各占 8 MiB 内存 解密缓冲区原先没上限 约 1000 条连接就能吃掉数 GB 顺手给登录握手加了 30 秒总超时
- 空 token 且显式绑对外地址时拒绝启动 原先只打一条警告就放行 那等于对外开放一个任何人都能用的服务端
- 签名缺失或失败不再静默通过
release.py原先在「没有私钥」和「gpg 签名失败」两种情况下都返回 0 会发出未签名的制品
0.5.4 起会拒绝启动的情况
这几条是有意为之 不是 bug
| 配置 | 怎么办 |
|---|---|
| 空 token 且显式绑了对外地址 | 配 token 或绑 127.0.0.1 或显式写 allow_insecure_no_auth = true |
面板绑非回环且无 dashboard_user |
配凭据 或绑回环 或写 allow_insecure_dashboard = true |
客户端 [webServer] 绑非回环且无凭据 |
逃生开关 allowInsecureRemote = true |
[acl] 段键名拼错 |
现在会报错 按提示改拼写(原先 denny 这种拼错会让整段访问控制悄悄消失) |
Android 版把内核装进了手机
1.0.4 这版界面是纯 Java + XML 写的 观感整套对着 KernelSU 管理器做 折叠大标题 分段列表 悬浮底栏 液态玻璃 逻辑层全部是 C(JNI 是唯一接缝)隧道内核是那个跟官方 frp 对拍过的 Rust 实现
- 一条隧道一个内核进程 之前是「已有一条在跑就不许再启」现在放开了 各跑各的 各自的工作目录 pid 文件 配置 日志 谁也不碰谁
- 折射是实时的 底栏玻璃抓的是此刻栏后面的画面 不是「切到第几页就换一张贴图」判据是「这一帧的遍历是不是我自己要来的」 屏幕静止时回调一次都不会被调 不自转 不耗电
- 拖动有阻尼 按住底栏左右拖 松手自动吸附到最近一格 胶囊永远慢手指一点 于是有重量
- 节点下拉不再空白 对着官方 Open API 逐个接口核过 隧道列表的数组键是
data.list而节点列表是data.nodes之前那份猜键名的名单里没有nodes
支持 Android 9 到 17 arm64-v8a 真机 / x86_64 模拟器两个架构都打了 装好第一次运行问通知权限 给了的话隧道运行时会有一条常驻通知 拒绝也能用
拿来就能用的东西
- 内置 Web 面板 配了
dashboard_port就有 面板里能直接增删代理 踢客户端 不用改配置不用重启 - Prometheus
/metrics业务指标直接被 scrape 免鉴权健康检查端点也有 - Dashboard API v2
/api/v2/*统一错误信封 + 分页 + 稳定排序 v1 接口行为不变 - 健康检查 tcp / http 探测 连续失败自动摘后端 恢复自动回归
- 带宽限流 每个代理可配
bandwidth_limit(比如1MB)令牌桶精确限速 - 资源上限 客户端数 / 代理数 / 转发连接数 / 待处理队列 五个维度都能限并计入指标
- OIDC 认证 对接 Keycloak / Google / Azure AD 等任意标准 IdP 客户端走 Client Credentials 服务端验签 JWKS
- RBAC 角色表 按序匹配 +
deny_unknown/default_role兜底 - 审计日志 JSONL 追加写 + 内存环形缓冲 关闭时零开销
- 客户端本地 Web UI
[webServer] port = 7400看隧道 / 连接 / 流量 也能增删代理
工程质量
- 612 个自动化测试 含真实 QUIC 栈握手 端到端集成 以及与官方 frpc/frps 真实抓包密文的解密回归
- CI 跑
fmt/clippy/ 三系统全量测试 / 两个 musl 目标交叉构建 / 端到端冒烟 - 第三方 GitHub Action 全部 pin 到 commit SHA cosign 签名失败即红灯
- 发布产物附
SHA256SUMS.txt+ Ed25519 分离签名(公钥指纹763896b5d759c6cbe1f208c3c35c9f71)
怎么拿
| 平台 | 文件 | 大小 |
|---|---|---|
| Windows x64 | nfrp-windows-amd64.zip |
3.76 MB |
| Linux x64 | nfrp-linux-amd64.tar.gz |
4.13 MB |
| Linux arm64 | nfrp-linux-arm64.tar.gz 全静态链接无 glibc 依赖 |
4.55 MB |
| Android aarch64 + x86_64 | nfrp-android-v0.5.4.zip |
7.95 MB |
| Android APK | nfrp-android-v1.0.4.apk |
— |
包内七个文件 frps / frpc(Windows 是 .exe)frps.toml frpc.toml LICENSE NOTICE README.md 二进制名跟官方一致 不改
校验完整性
1 | sha256sum -c SHA256SUMS.txt |
两句必须说清的话
OIDC 部署必须配 TLS OIDC 的凭证是原样的 access token 会明文出现在登录报文里
客户端 transport.tls 只加密不校验对端证书 跟官方 frp 一致 防偷看 不防中间人 要防中间人就自己上 mTLS
兼容性一个字没动
-v 仍输出裸 0.71.0 线协议魔术字与版本串不变 包内仍叫 frps / frpc 官方 frpc / frps 双向互通照旧 第三方 frp 平台照旧
版本号从 0.5.0 起由 rustunnel 改名为 NFrp(crate 与二进制都是 nfrp-*)私有能力协商字段从 _rustunnel 换成 _nfrp 跟老版本混用时不协商私有能力 退化成纯 frp 行为 不会出事
完整修复清单 SECURITY-FIXES.md
源码与发布页 Rust-Frp