vpn_plugin 0.1.0
vpn_plugin: ^0.1.0 copied to clipboard
Flutter VPN engine embedding the sing-box core (iOS NetworkExtension / Android VpnService), with share-link parsing and config generation. GPL-3.0.
vpn_plugin #
vpn_plugin 是一个基于 Flutter 的 VPN 插件,底层使用 sing-box 核心,并通过 Android 的 VpnService 和 iOS 的 NetworkExtension 来驱动真正的 VPN 隧道。
这个包的目标很明确:把复杂的原生 VPN 接入流程封装成一套简洁的 Dart API,让你在 Flutter 应用里直接完成代理连接、状态监听、配置生成和日志查看。
平台支持 #
| 平台 | 支持情况 |
|---|---|
| iOS | ✅ 可以 |
| Android | ✅ 可以 |
| macOS | 🚧 暂无 |
| Windows | 🚧 暂无 |
需要定制各种功能,欢迎联系 Telegram @haxon_mc。
稳定、低费率:https://faspayment.com/
这套插件能做什么 #
这个插件提供了三类核心能力:
-
原生 VPN 隧道控制
- 启动 VPN
- 停止 VPN
- 查询当前状态
- 监听状态变化
- 读取 sing-box 内核版本和日志
-
分享链接解析
- 支持 vmess、vless、trojan、shadowsocks、hysteria2、tuic 等常见代理格式
- 支持普通链接、base64 链接、以及 sing-box JSON 订阅格式
-
sing-box 配置生成
- 可以从一个代理出站配置快速生成完整的 sing-box 配置
- 支持路由模式、MTU、IPv6、LAN 开关、日志等级等配置项
适合什么场景 #
这个插件适合下面这类项目:
- 需要在 Flutter 应用里接入自定义 VPN 能力的项目
- 需要解析用户分享的代理链接并直接启动连接的项目
- 需要做一套轻量的代理客户端、测试工具、内测工具或实验性网络应用的项目
- 需要在 Android 和 iOS 上都能复用一套 Dart 逻辑的项目
主要能力概览 #
-
SingboxVpnstart(String configJson)startOutbound(Map<String, dynamic> outbound)stop()currentStatus()statusStream()validateConfig(String configJson)coreVersion()readLogs()clearLogs()
-
parseShareLink(String link)- 把单条链接解析成 sing-box outbound 配置
-
parseSubscription(String content)- 把一段订阅内容解析成多个 outbound
-
buildSingboxConfig(...)/buildSingboxConfigJson(...)- 生成完整的 sing-box 配置 JSON
工作原理 #
这套插件的运行方式可以理解为下面这样:
Flutter Dart -> MethodChannel / EventChannel -> 原生桥接层
Android: VpnService -> sing-box libbox
iOS: NetworkExtension -> sing-box PacketTunnel 扩展
也就是说,Dart 层只负责调用和控制;真正的 VPN 逻辑仍然由原生平台和 sing-box 核心来完成。
安装方式 #
在你的 Flutter 项目里执行:
flutter pub add vpn_plugin
然后在 Dart 代码里导入:
import 'package:vpn_plugin/vpn_plugin.dart';
快速开始 #
下面是最常见的用法:
1. 直接用分享链接启动 #
import 'package:vpn_plugin/vpn_plugin.dart';
Future<void> startFromLink(String link) async {
final vpn = SingboxVpn();
final outbound = parseShareLink(link);
if (outbound == null) {
print('无法解析该链接');
return;
}
await vpn.startOutbound(outbound);
}
2. 监听连接状态 #
final vpn = SingboxVpn();
vpn.statusStream().listen((status) {
print('状态: ${status.state}');
if (status.message != null) {
print('说明: ${status.message}');
}
});
3. 生成完整配置后再启动 #
final vpn = SingboxVpn();
final outbound = parseShareLink('vless://...');
if (outbound == null) return;
final configJson = buildSingboxConfigJson(
outbound,
options: const SingboxConfigOptions(
routeMode: 'rule',
allowLan: false,
enableIpv6: false,
),
);
await vpn.start(configJson);
4. 停止连接 #
final vpn = SingboxVpn();
await vpn.stop();
代码示例 #
示例工程在 example/ 目录下,里面提供了一个简单的页面,用来测试链接解析与连接启动。
你可以在项目根目录执行:
cd example
flutter run
示例里会展示:
- 输入分享链接
- 解析链接
- 启动或停止 VPN
- 查看当前状态
配置项说明 #
SingboxConfigOptions 里有几个常用参数:
-
mtu- TUN 接口的 MTU 值
- 默认值是 9000
-
enableIpv6- 是否开启 IPv6 地址和 IPv6 解析
- 默认关闭
-
logLevel- sing-box 的日志等级
- 常见值:trace、debug、info、warn、error、fatal、panic
-
allowLan- 是否允许局域网流量走隧道
- 默认关闭
-
routeMode- 路由模式
global:所有流量都走代理rule:按规则分流,国内流量优先直连direct:所有流量都直连,不走代理
Android 平台说明 #
Android 端这部分是自动化的。
要求:
minSdk >= 24- 运行环境里需要有 Android NDK 和 JDK 17
插件内部会使用 VpnService 方式接入 VPN,第一次启动时系统通常会弹出权限提示,用户同意后才能继续。
iOS 平台说明 #
iOS 上的 VPN 不是直接在主 App 里跑的,而是通过单独的 NetworkExtension 扩展来运行。
这意味着你需要做一次性配置:
- 在你的应用工程里添加一个 PacketTunnel 扩展目标
- 配置 App Group
- 配置 NetworkExtension 权限
- 绑定 sing-box 的 libbox 核心
这个插件自带了一个辅助脚本,帮助你完成这一步:
cd ios
pod install
ruby .symlinks/plugins/vpn_plugin/tool/add_extension_target.rb
执行后,项目里会生成对应的扩展 target,并把必要的配置接入进去。
注意事项:
- iOS 需要付费 Apple Developer 账号
- 需要真实设备运行,模拟器不支持这个场景
- 扩展签名和权限需要你在 Xcode 里确认通过
核心文件是怎么来的 #
这个包没有把 sing-box 的大体积核心文件直接打进 pub.dev 包里,因为它们太大了。
实际做法是:
- 在本地运行脚本构建
libbox.aar和Libbox.xcframework.zip - 把这两个文件上传到你自己的 GitHub Release
- 在构建时从远程下载它们
相关脚本在 scripts/ 目录下:
scripts/build_libbox_android.sh
scripts/build_libbox_ios.sh
如果你要在自己的项目里用这个包,通常需要先准备好这两个核心产物,再把地址配置到构建流程里。
常见问题 #
1. 核心文件这么大,包是怎么发到 pub.dev 的? #
包里只有纯 Dart 代码和原生桥接源码,体积很小。sing-box 的 native 核心(libbox.aar /
Libbox.xcframework)不会打进包里,而是在构建 / 配置时从 GitHub Release 下载,所以包本身可以
正常发布到 pub.dev,安装方式就是普通的 flutter pub add vpn_plugin。
2. 为什么 iOS 不能在模拟器里跑? #
因为 VPN 扩展依赖 Apple 的 NetworkExtension 和真实设备的系统能力,模拟器不满足这套运行条件。
3. 我可以用自己的完整 sing-box 配置吗? #
可以。你可以把任何可用的 sing-box JSON 配置传给 start(configJson)。
4. 我需要自己手写 sing-box JSON 吗? #
不一定。只要你已经有一个代理分享链接,通常可以直接用 parseShareLink() 和 startOutbound(),插件会帮你生成配置。
许可证 #
这个包使用 GPL-3.0 许可证。
这意味着:
- 你可以在符合 GPL 条款的前提下使用它
- 如果你把它集成到自己的应用里,应用的源码也需要满足相应的开源要求
- 这不是一个闭源商业包的使用方式
详细内容请查看 LICENSE。
额外说明 #
这个插件的设计思路是:
- 把底层原生 VPN 能力封装起来
- 给 Flutter 开发者提供一套稳定、可复用的接口
- 尽量减少开发者在 Android 和 iOS 上分别实现 VPN 逻辑的成本
如果你要把它集成进自己的应用,建议先把示例工程跑通,再在你的业务里按自己的代理来源和路由策略去扩展。