Git Product home page Git Product logo

flutter_wireguard_vpn's Introduction

wireguard_vpn

A Flutter plugin that enables the activation and deactivation of VPN connections using WireGuard.

Setup

  • Modify the file /android/app/build.gradle and set the minSdkVersion to 21:
android {                    
   defaultConfig {
      minSdkVersion 21
  }                                
}
  • To run the application in release mode, you must add a file named proguard-rules.pro with the following content to the ./android/app/ directory:
-keep class app.wachu.wireguard_vpn.** {*;}
-keep class com.beust.klaxon.** {*;}
  • Another option is to add the following to the ./android/app/build.gradle file under the buildtypes release:
shrinkResources false
minifyEnabled false

I'd like to thank the user ByteSizedMarius for their contribution regarding the execution in release mode of the package. Thank you.

Usage

To use this plugin, you must first add it to your pubspec.yaml file:

dependencies:
  wireguard_vpn: ^0.0.2 

Then, import the package in your .dart file:

import 'package:wireguard_vpn/wireguard_vpn.dart';

Activate and Deactivate VPN

To activate or deactivate the VPN connection, use the changeStateParams method of the WireguardFlutterPlugin class. This method takes a SetStateParams object as a parameter, which includes information about the VPN tunnel.

bool vpnActivate = false;
String initName = "MyWireguardVPN";
String initAddress = "192.168.1.1/24";
String initDnsServer = "8.8.8.8";
String initPort = "51820";
String initAllowedIp = "0.0.0.0/0";
String initEndpoint = "vpn.example.com:51820";
String initPublicKey = "PUBLIC_KEY";
String initPrivateKey = "PRIVATE_KEY";
String presharedKey = "PRESHARED_KEY";

final _wireguardFlutterPlugin = WireguardFlutterPlugin();

void _activateVpn(bool value) async {
  final results = await _wireguardFlutterPlugin.changeStateParams(SetStateParams(
    state: !vpnActivate,
    tunnel: Tunnel(
        name: initName,
        address: initAddress,
        dnsServer: initDnsServer,
        listenPort: initPort,
        peerAllowedIp: initAllowedIp,
        peerEndpoint: initEndpoint,
        peerPublicKey: initPublicKey,
        privateKey: initPrivateKey,
        peerPresharedKey: presharedKey),
  ));
  setState(() {
    vpnActivate = results ?? false;
  });
}

Obtain connection statistics

To obtain statistics of the VPN connection, use the tunnelGetStats method of the WireguardFlutterPlugin class. This method takes the name of the VPN tunnel as a parameter.

String initName = "MyWireguardVPN";

final _wireguardFlutterPlugin = WireguardFlutterPlugin();

void _obtainStats() {
  Timer.periodic(const Duration(seconds: 1), (timer) async {
    final results = await _wireguardFlutterPlugin.tunnelGetStats(initName);
    setState(() {
      stats = results ?? Stats(totalDownload: 0, totalUpload: 0);
    });
  });
}

Complete example

Here's an example of how to use this plugin to activate and deactivate the VPN connection and obtain connection statistics:

import 'dart:async';

import 'package:flutter/material.dart';

import 'package:wireguard_vpn/wireguard_vpn.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _wireguardFlutterPlugin = WireguardVpn();
  bool vpnActivate = false;
  Stats stats = Stats(totalDownload: 0, totalUpload: 0);
  final String initName = 'MyWireguardVPN';
  final String initAddress = "10.7.0.2/24";
  final String initPort = "51820";
  final String initDnsServer = "8.8.8.8, 8.8.4.4";
  final String initPrivateKey = "PRIVATE_KEY";
  final String initAllowedIp = "0.0.0.0/0, ::/0";
  final String initPublicKey = "PUBLIC_KEY";
  final String initEndpoint = "vpn.example.com:51820";
  final String presharedKey = 'PRESHARED_KEY';

  @override
  void initState() {
    super.initState();
    vpnActivate ? _obtainStats() : null;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: const Text('Wireguard-VPN Example'),
          ),
          body: Column(
            children: [
              Text(
                  'Active VPN: ${stats.totalDownload} D -- ${stats.totalUpload} U'),
              SwitchListTile(
                value: vpnActivate,
                onChanged: _activateVpn,
                title: Text(initName),
                subtitle: Text(initEndpoint),
              ),
            ],
          )),
    );
  }

  void _obtainStats() {
    Timer.periodic(const Duration(seconds: 1), (timer) async {
      final results = await _wireguardFlutterPlugin.tunnelGetStats(initName);
      setState(() {
        stats = results ?? Stats(totalDownload: 0, totalUpload: 0);
      });
    });
  }

  void _activateVpn(bool value) async {
    final results =
        await _wireguardFlutterPlugin.changeStateParams(SetStateParams(
      state: !vpnActivate,
      tunnel: Tunnel(
          name: initName,
          address: initAddress,
          dnsServer: initDnsServer,
          listenPort: initPort,
          peerAllowedIp: initAllowedIp,
          peerEndpoint: initEndpoint,
          peerPublicKey: initPublicKey,
          privateKey: initPrivateKey,
          peerPresharedKey: presharedKey),
    ));
    setState(() {
      vpnActivate = results ?? false;
      vpnActivate ? _obtainStats() : null;
    });
  }
}

For more information, you can check the example tab or the GitHub repository.

Generate WireGuard VPN configurations

To obtain WireGuard VPN configurations for testing, you can visit the PotonVPN website, register, and generate a configuration under the downloads section. You can also follow the guide on the official WireGuard VPN website.

Contributions

Contributions are welcome. If you find a bug or want to add a new feature, please open a new issue or send a pull request.

License

This package is available under the terms of the BSD 3-clause license. Please refer to the LICENSE file for more information.

flutter_wireguard_vpn's People

Contributors

wachu985 avatar

Stargazers

denuitt avatar 白树呐 avatar  avatar pythonwood avatar  avatar  avatar Adarsha Krishna avatar Alex Ibraimov avatar Khánh Tô avatar  avatar Yorlandis Garcia avatar Fidel Alejandro Cepero Salazar avatar Jungwuk Ryu avatar Marius avatar  avatar Jesse Visser avatar Kevin Jablonski avatar Pyae Hein avatar PedramKTB avatar  avatar

Watchers

 avatar  avatar Yorlandis Garcia avatar

flutter_wireguard_vpn's Issues

Not working on rooted BlueStacks5

log:

D/WireGuard/SharedLibraryLoader(16484): Extracting apk:/lib/x86_64/libwg-quick.so to /data/user/0/.../code_cache/bin/wg-quick.tmp
D/WireGuard/ToolsInstaller(16484): Tools are now extracted into our private binary dir
V/WireGuard/RootShell(16484): executing: wg show interfaces
V/WireGuard/RootShell(16484): exit: 0
I/WireGuard/WgQuickBackend(16484): Bringing tunnel freeTier UP
V/WireGuard/RootShell(16484): executing: cat /sys/module/wireguard/version && wg-quick up '/data/user/0/.../cache/tmp/freeTier.conf'
V/WireGuard/RootShell(16484): stderr: cat: /sys/module/wireguard/version: No such file or directory
V/WireGuard/RootShell(16484): exit: 1
E/MainActivity(16484): handleSetState - BackendException - ERROR - WG_QUICK_CONFIG_ERROR_CODE
E/flutter (16484): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Instance of 'ConnectionException'
E/flutter (16484): #0      MethodChannelWireguardVpn.changeStateParams (package:wireguard_vpn/wireguard_vpn_method_channel.dart:24:7)
E/flutter (16484): <asynchronous suspension>
E/flutter (16484): #1      _MyHomePageState._activateVpn (package:kvpn/main.dart:48:21)
E/flutter (16484): <asynchronous suspension>
E/flutter (16484): #2      _MyHomePageState.build.<anonymous closure> (package:kvpn/main.dart:113:19)
E/flutter (16484): <asynchronous suspension>
E/flutter (16484): 

Hi. I found some problems. The app works on Android Emulator but doesn't work on rooted BlueStacks5.
Version of BlueStacks5 : 5.11.41.1005 P64 (rooted)

Thank you.

Release version not working (Android)

First of all Thanks for such an wonderful work.
There is an issue arise in release mode the app is not working but it is working in debug mode.

Possible cause: Wireguard packages might be removed due to pro-guard while creating release apk.

Looking for your response.
Thank you.

Release mode not working

Release mode not working , when i click to toggle switch i get errors in release mode. Works fine for debug mode.
And are there any plans for IOS support?

IOS version?

Thanks for the great work - has anyone go the ios working?

[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: Instance of 'ConnectionException'
#0 MethodChannelWireguardVpn.changeStateParams (package:wireguard_vpn/wireguard_vpn_method_channel.dart:24:7)

#1 _MyAppState._activateVpn (package:my_flutter_app/main.dart:82:9)

Wireguard Config

Thank You for the plugin , I'm new to vpn environment. I dont know where to get the configs for the wireguard.
Can you guide me how to obtain the a ddress, Port , DnsServer, PrivateKey, PublicKey, Endpoint ,presharedKey etc.
It would be nice if you include this in readme.md.

"Ghost" Tunnels

Hello, I've found a small problem and will propose a fix here, but since I am not comfortable with Kotlin, I'm opening this issue instead of a PR.

Basically, when a tunnel is running and the app is closed (swipe up, close), the tunnel will remain active in the background, as the app is not fully stopped (this is reproducible with the example app on api 34). Opening the app again, the WG backend has, to my knowledge, no way of retrieving the running tunnel from the old backend (statistics and getRunningTunnelNames return nothing). Reconnecting doesn't work either in my case, because the old tunnel is still active. The only solution I've found (other than changing the code), is force-stopping the app from the android settings, which closes the tunnel completely.

What I've done to remedy this, is to add a for-loop in onDetachedFromEngine, that closes currently running tunnels. This seems to prevent the issue at hand, as the method seems to be called whenever the app is closed in the way described.

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
    scope.launch(Dispatchers.IO) {
        try {
            // get running tunnels
            val runningTunnels = futureBackend.await().runningTunnelNames
            // stop all tunnels
            runningTunnels.forEach {
                futureBackend.await().setState(tunnel(it), Tunnel.State.DOWN, null)
                Log.i(TAG, "Stopped tunnel $it")
            }
        } catch (e: Throwable) {
            Log.e(TAG, Log.getStackTraceString(e))
        }
    }


    channel.setMethodCallHandler(null)
}

Not sure if this is the correct place to do this (maybe kotlin offers a better native solution I am not aware of), but generally, I believe the tunnels should be shut down when the app closes to prevent active tunnels to become out of our control.

Thanks for your work on this, it's greatly appreciated.

Only one device is working on 1 config.

Hey bro I used 3xui panel to create server but when I try to run multiple users with one config it blockes the other users and works only in one device . How to solve this issue?

Windows Desktop App

@Wachu985 Excellent job for this library. I got it working on android for wireguard server hosted on GCP. Have you tried this for Windows Desktop App?

Failed resolution of: Ljava/time/Instant

When i try to connect this error appears:
Can't set tunnel state: java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/Instant;, java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/Instant;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.