flutter_netbird 1.0.2
flutter_netbird: ^1.0.2 copied to clipboard
A Flutter FFI plugin for NetBird mesh VPN, providing secure peer-to-peer connectivity, DNS resolution, and HTTP proxy across Android, iOS, macOS, Windows, and Linux.
flutter_netbird #
A Flutter FFI plugin for NetBird, providing secure mesh VPN connectivity for Flutter applications across Android, iOS, macOS, Windows, and Linux.
Features #
- 🌐 Cross-Platform: Android, iOS, macOS, Windows, and Linux support
- 🔒 Secure Mesh VPN: Peer-to-peer encrypted connections using WireGuard
- 📱 Userspace Networking: No root/admin privileges required on mobile
- 🎯 Type-Safe API: Strongly typed Dart models for all operations
- 📊 Real-time Status: Stream-based event and log monitoring
- 🔧 Flexible Configuration: Comprehensive configuration options
- 🌍 HTTP Proxy with DNS: HTTP requests through NetBird tunnel with in-process DNS resolution for Custom Zone domains
- 🔗 Native Proxy & WebSockets: Built-in HTTP CONNECT proxy supports native
dart:ioandWebSockettransparent tunneling
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
flutter_netbird:
path: ../flutter_netbird # Adjust path as needed
Quick Start #
import 'package:flutter_netbird/flutter_netbird.dart';
import 'package:path_provider/path_provider.dart';
// 1. Get the SDK instance
final sdk = NetbirdSDK();
// 2. Set up event listeners
sdk.events.listen((event) {
print('NetBird Event: ${event.type} - ${event.data}');
});
sdk.logs.listen((log) {
print('${log.levelName}: ${log.message}');
});
// 3. Initialize with configuration
final docDir = await getApplicationDocumentsDirectory();
final config = NetbirdConfig(
configPath: "${docDir.path}/netbird_config.json",
statePath: "${docDir.path}/netbird_state.json",
managementURL: "https://api.netbird.io",
deviceName: "my-flutter-device",
logLevel: "info",
);
sdk.initialize(config);
// 4. Connect with credentials
final auth = NetbirdAuth(setupKey: "YOUR-SETUP-KEY");
sdk.up(auth: auth);
// 5. Monitor status
Timer.periodic(Duration(seconds: 2), (timer) {
final status = sdk.getFullStatus();
print('Status: ${status.status}, IP: ${status.ip}');
});
// 6. Start Native Proxy (Optional: for WebSocket & dart:io support)
final proxyPort = await sdk.startProxy();
if (proxyPort > 0) {
HttpOverrides.global = NetbirdHttpOverrides(proxyPort);
// Now standard `WebSocketChannel` and `http.get` will securely route through NetBird!
}
API Reference #
NetbirdSDK #
The main SDK class providing all NetBird functionality.
Methods
initialize(NetbirdConfig config) → int
Initializes the NetBird SDK with configuration. Must be called before up().
Returns: 0 on success, non-zero on error.
final config = NetbirdConfig(
configPath: "/path/to/config.json",
statePath: "/path/to/state.json",
managementURL: "https://api.netbird.io",
deviceName: "my-device",
logLevel: "info",
setupKey: "optional-setup-key", // Can be provided here or in up()
);
final result = sdk.initialize(config);
if (result != 0) {
print('Initialization failed: $result');
}
up({NetbirdAuth? auth}) → int
Starts the NetBird connection.
Returns:
0on success1on error2if already running
final auth = NetbirdAuth(setupKey: "YOUR-SETUP-KEY");
final result = sdk.up(auth: auth);
down() → int
Stops the NetBird connection.
Returns: 0 on success, non-zero on error.
sdk.down();
getStatus() → String
Returns a simple status string.
Possible values: "Stopped", "Connecting", "Connected", "Disconnected", "Error"
final status = sdk.getStatus();
print('Current status: $status');
getFullStatus() → NetbirdFullStatus
Returns detailed status information as a typed object.
final status = sdk.getFullStatus();
print('Status: ${status.status}');
print('IP: ${status.ip}');
print('Peers: ${status.peersCount}');
for (var peer in status.peers) {
print('Peer: ${peer.fqdn} (${peer.ip}) - ${peer.direct ? "Direct" : "Relayed"}');
}
setLogLevel(String level) → int
Changes the log level at runtime.
Valid levels: "trace", "debug", "info", "warn", "error"
sdk.setLogLevel("debug");
cleanup() → void
Cleans up all resources. Call this when shutting down the app.
@override
void dispose() {
sdk.cleanup();
super.dispose();
}
Properties
events → Stream<NetbirdEvent>
Stream of NetBird events (state changes, errors, etc.).
sdk.events.listen((event) {
print('Event type: ${event.type}');
print('Event data: ${event.data}');
// Parse as JSON if needed
final json = event.dataAsJson;
if (json?['error'] != null) {
print('Error occurred: ${json!['error']}');
}
});
logs → Stream<NetbirdLog>
Stream of NetBird log messages.
sdk.logs.listen((log) {
print('[${log.levelName}] ${log.message}');
});
isInitialized → bool
Whether the SDK has been initialized.
if (sdk.isInitialized) {
// Safe to call up()
}
Configuration Classes #
NetbirdConfig
Configuration for initializing NetBird.
NetbirdConfig({
String? deviceName, // Device identifier in the network
String? managementURL, // Management server URL
String? configPath, // Path to config file (for persistence)
String? statePath, // Path to state file
String logLevel = 'info', // Log level
String? setupKey, // Setup key (can be provided in up() instead)
String? jwtToken, // JWT token (alternative to setupKey)
String? privateKey, // Private key (alternative to setupKey)
String? preSharedKey, // WireGuard pre-shared key
bool disableClientRoutes = false, // Disable client routes
bool blockInbound = false, // Block inbound connections
int? wireguardPort, // WireGuard port (null = random)
})
Important: configPath is highly recommended for mobile apps to persist the device identity across restarts.
NetbirdAuth
Authentication credentials for connecting.
NetbirdAuth({
String? setupKey, // Setup key from NetBird management portal
String? jwtToken, // JWT token
String? privateKey, // Private key
})
Note: Only one authentication method should be provided.
Status Classes #
NetbirdFullStatus
Comprehensive status information.
Properties:
String status- Connection statusString? error- Error message if anyMap<String, dynamic>? managementState- Management server stateMap<String, dynamic>? signalState- Signal server stateNetbirdPeerInfo? localPeer- Local peer informationint peersCount- Number of connected peersList<NetbirdPeerInfo> peers- List of connected peersint? forwardingRules- Number of forwarding rulesString? ip- Local NetBird IP addressString? publicKey- Public keyString? fqdn- Fully qualified domain name
NetbirdPeerInfo
Information about a peer.
Properties:
String? ip- Peer IP addressString? fqdn- Peer FQDNString? connectionType- Connection typebool? direct- Whether connection is direct (not relayed)String? latency- Connection latencyint? bytesRx- Bytes receivedint? bytesTx- Bytes transmitted
Memory Management #
Critical: Callback Memory Safety ⚠️ #
This plugin has been designed with careful attention to memory management:
Callbacks (Events and Logs):
- ✅ Safe: The Go side automatically frees memory after callbacks return
- ✅ No action needed: Dart code should NOT call
FreeStringon callback data - ✅ Just read: Simply call
toDartString()to copy the data to Dart
Return Values (Status Methods):
- ⚠️ Dart must free: Strings returned from
getStatus()andgetFullStatus() - ✅ Handled internally: The SDK automatically calls
FreeString- you don't need to worry about it
// ✅ CORRECT: Events are auto-freed
sdk.events.listen((event) {
final data = event.data; // Safe, memory auto-freed
});
// ✅ CORRECT: Status is auto-freed
final status = sdk.getFullStatus(); // Safe, SDK handles cleanup
Platform-Specific Notes #
Android #
- Add the following to
android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
iOS #
- Add the following to
ios/Runner/Info.plist:
<key>NSLocalNetworkUsageDescription</key>
<string>NetBird needs access to local network for VPN connections</string>
macOS #
- Enable network entitlements in
macos/Runner/DebugProfile.entitlementsandRelease.entitlements:
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
Building Native Libraries #
The native NetBird libraries are built from the netbird_core Go package:
cd ../netbird_core
./build_all.sh
This generates platform-specific binaries:
- Android:
libnetbird.so - iOS/macOS:
libnetbird.xcframework/libnetbird.dylib - Windows:
libnetbird.dll - Linux:
libnetbird.so
Place these in the appropriate directories as specified in the plugin structure.
Example App #
See the example/ directory for a complete Flutter application demonstrating:
- ✅ Connection management
- ✅ Real-time status monitoring
- ✅ Peer list display
- ✅ Log viewer
- ✅ Settings configuration
Run the example:
cd example
flutter run
Troubleshooting #
"Failed to load dynamic library" #
Ensure the native library is properly included in your build:
- Android: Check
android/app/src/main/jniLibs/ - iOS: Check Xcode framework embedding
- macOS: Check that the library is in the bundle
DNS Resolution Fails ("server misbehaving") #
If HTTP requests to custom domains fail with server misbehaving but IP access works:
- Verify the domain is configured as a DNS Zone (not Nameserver Group) in NetBird management
- Ensure the zone is Active and the A record is correctly configured
- The plugin resolves custom domains in-process from the management server's SyncResponse, bypassing netstack UDP DNS
Connection Fails #
- Check your setup key is valid
- Verify the management URL is accessible
- Check logs for specific errors:
sdk.logs.listen((log) {
if (log.level <= 2) { // ERROR or FATAL
print('ERROR: ${log.message}');
}
});
Device Not Persisting #
Make sure configPath is set to a writable location:
final docDir = await getApplicationDocumentsDirectory();
final config = NetbirdConfig(
configPath: "${docDir.path}/netbird_config.json", // Important!
// ...
);
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is part of the NetBird ecosystem. See the main NetBird repository for licensing information.
Credits #
Built on top of NetBird - Open-source mesh VPN platform.