GithubHelp home page GithubHelp logo

defguard / wireguard-rs Goto Github PK

View Code? Open in Web Editor NEW
106.0 106.0 7.0 180 KB

Rust library providing unified WireGuard interface to native/kernel and userspace implementations

Home Page: https://github.com/defguard/defguard/

License: Other

Rust 100.00%
crate crates library linux networking openvpn rust rust-lang vpn wireguard wireguard-server wireguard-vpn

wireguard-rs's Introduction

defguard

The only open-source solution with real WireGuard MFA/2FA & integrated OpenID Connect SSO

GitHub commits since latest release

Website | Getting Started | Features | Roadmap | Support ❤

  • SSO, VPN, and hardware security key management combined, which provides:
    • significant cost saving, simplifying deployment and maintenance
    • enabling features unavailable to VPN platforms relying upon 3rd party SSO integration
  • Real WireGuard® MFA (not 2FA to "access application" like most solutions)
  • Secure and robust architecture, featuring components and micro-services seamlessly deployable in diverse network setups (eg. utilizing network segments like Demilitarized Zones, Intranet with no external access, etc), ensuring a secure environment.
  • Enterprise ready (multiple Locations/Gateways/Kubernetes deployment, etc..)
  • Build on WireGuard® protocol which is faster than IPSec, and significantly faster than OpenVPN
  • Build with Rust for speed and security

See below full list of features

Control plane management

Better quality video can be found here to download

Desktop Client with Multi-Factor Authentication

defguard WireGuard MFA

Desktop client supports:

  • Secure and remote user enrollment - setting up password, automatically configuring the client for all VPN Locations/Networks
  • Onboarding - displaying custom onboarding messages, with templates, links ...
  • Ability to route predefined VPN traffic or all traffic (server needs to have NAT configured - in gateway example)
  • Live & real-time network charts
  • In development: Multi-Factor Authentication for VPN, live logs, dark theme, settings, and more!

Roadmap

defguard WireGuard® MFA

Quick start

The easiest way to run your own defguard instance is to use Docker and our one-line install script.

Just run the command below in your shell and follow the prompts:

curl --proto '=https' --tlsv1.2 -sSf -L https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/setup.sh -O && bash setup.sh

To learn more about the script and available options please see the documentation.

Setup a VPN server under 5min!?

Just follow this tutorial

Manual deployment examples

Roadmap & Development

A detailed product roadmap and development status can be found here.

⛑️ Want to help? ⛑️

Here is a dedicated view for good first bugs

Why?

The story and motivation behind defguard can be found here: https://teonite.com/blog/defguard/

Features

  • OpenID Connect provider - with unique features:
    • Secure remote (over the internet) user enrollment
    • User onboarding after enrollment
    • LDAP (tested on OpenLDAP) synchronization
    • forward auth for reverse proxies (tested with Traefik and Caddy)
    • nice UI to manage users
    • Users self-service (besides typical data management, users can revoke access to granted apps, MFA, WireGuard®, etc.)
    • Multi-Factor/2FA Authentication:
    • Time-based One-Time Password Algorithm (TOTP - e.g. Google Authenticator)
    • WebAuthn / FIDO2 - for hardware key authentication support (eg. YubiKey, FaceID, TouchID, ...)
    • Web3 - authentication with crypto software and hardware wallets using Metamask, Ledger Extension
  • WireGuard® VPN management with:
    • Multi-Factor Authentication with TOTP/Email & Pre-Shared Session Keys
    • multiple VPN Locations (networks/sites) - with defined access (all users or only Admin group)
    • multiple Gateways for each VPN Location (high availability/failover) - supported on a cluster of routers/firewalls for Linux, FreeBSD/PFSense/OPNSense
    • import your current WireGuard® server configuration (with a wizard!)
    • most beautiful Desktop Client! (in our opinion ;-))
    • automatic IP allocation
    • kernel (Linux, FreeBSD/OPNSense/PFSense) & userspace WireGuard® support with our Rust library
    • dashboard and statistics overview of connected users/devices for admins
    • defguard is not an official WireGuard® project, and WireGuard is a registered trademark of Jason A. Donenfeld.
  • SSH & GPG public key management in user profile - with SSH keys authentication for servers
  • Yubikey hardware keys provisioning for users by one click
  • Email/SMTP support for notifications, remote enrollment and onboarding
  • Easy support with sending debug/support information
  • Webhooks & REST API
  • Build with Rust for portability, security, and speed
  • UI Library - our beautiful React/TypeScript UI is a collection of React components:
    • a set of custom and beautiful components for the layout
    • Responsive Web Design (supporting mobile phones, tablets, etc..)
    • iOS Web App
  • Checked by professional security researchers (see comprehensive security report)
  • End2End tests

Desktop Client

Desktop client supports:

  • Secure and remote user enrollment - setting up password, automatically configuring the client for all VPN Locations/Networks
  • Onboarding - displaying custom onboarding messages, with templates, links ...
  • Ability to route predefined VPN traffic or all traffic (server needs to have NAT configured - in gateway example)
  • Live & real-time network charts
  • In development: Multi-Factor Authentication for VPN, live logs, dark theme, settings, and more!

Documentation

See the documentation for more information.

Community and Support

Find us on Matrix: #defguard:teonite.com

Contribution

Please review the Contributing guide for information on how to get started contributing to the project. You might also find our environment setup guide handy.

Built and sponsored by

build by teonite

Legal

WireGuard® is registered trademarks of Jason A. Donenfeld.

wireguard-rs's People

Contributors

blazej-teonite avatar dzania avatar j-chmielewski avatar moubctez avatar teon avatar wojcik91 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

wireguard-rs's Issues

OS Error 19 with defguard_wireguard_rs 0.2.0 from crates.io for the server example

Hey @wojcik91 and @teon ,

For context,

I'm running a Debian 12.1.0 with Cargo 1.72.0 and rustc 1.72.0

Following steps :

I created a new project with :

cargo init rnwireguardrs 

Inside the Cargo.toml :

[dependencies] 
defguard_wireguard_rs = "0.2.0"
x25519-dalek = { version = "2.0", features = [
"get random", 
"static_secrets", 
] } 
base64 = "0.21"
log = "0.4"

I have only one file in /src which is the main.rs.

I did a copy/paste of the wireguard-rs/examples/server.rs Inside the main.rs

No compilation error from the IDE neither from the rust compilator.

At the run time, I got the Following error :

Error : NetlinkError("Netlink payload error: No such device (os error 19)")

At first glance, it could be a problem from the Netlink librairie that can't create the interface and therefore it's impossible to do operations on this interface.

I must clarify that i'm executing with

sudo cargo run

Moreover, the previous version of the library is working fine, I can create the interface and interact correctly.

Do you need more specific informations ?

Best Regards,
Ange

Wireguard-rs on crates.io

Hi,

Would it possible to maintain Wireguard-rs on crates.io and doc.rs so it's accessible directly as a pull in the cargo.toml instead of git cloning the entire repository and manually adding cloned folder's path?

Whether it's already on crates.io or not, would it be possible to provide a link in the github to the crate when it's ready ?

Thanks,
Ange

Presharedkey support

Hi,

I couldn't see any code related to the presharedkey for the server (nor the client)

Is it supported ?

If so, would it be possible to provide a example with presharedkey support ?

If it's supported by the library but not implemented yet (macros, public function...), do you think it's possible to provide an example of how to create the presharedkey with dalek and write to the api ?

Thanks,
Ange

Provide Example for presharedkey implementation

Hi,

The issue with the presharedkey seems to have been fixed (#11). Currently, there is no example (server, userspace or client) to provide a presharedkey.

In the following snippet of code from server.rs file you created 10 peers, you sat them up and you configured them :

for peer_id in 3..13 {
    let secret = EphemeralSecret::random();
    let key = PublicKey::from(&secret);
    let peer_key: Key = key.as_ref().try_into().unwrap();
    peer_keys.push(peer_key.clone());
    let mut peer = Peer::new(peer_key)
    let addr = IpAddrMask::from_str(&format!("10.20.30.{peer_id}/32")).unwrap();
    peer.allowed_ips.push(addr);
    wgapi.configure_peer(&peer)?;
}

Would it be possible to have an example on how to create the presharedkey from your library and set it to a peer?

I didn't see any setter for the presharedkey in the Peer implementation. Is it somewhere else ?

would something like this be sufficient ?

let presharedkeysecret = EphemeralSecret::random();
peer.presharedkey.push(presharedkeysecret);

Thanks,
Ange

Mandatory steps for configuring the peer ?

Hey,

is it mandatory to insert the peer in the host since the host can take the values from the api by reading it ?

I've witnessed that even by reading the api, if you don't "insert" the peer in the host, you don't have the peer inside the host by printing it, even after reading api and affecting the returned value to the host.

Also, If I want to remove a peer to update it, it's not updated in the api, so do I have to remove the peer first and then add the "updated new peer" ? it's like actually doing a -1 +1 with the same peer informations, only the publickey that is changed during the update...

Someone ever got the issue ?

Mutiple allowed ips not working in peer (wg show)

Hey @wojcik91,

In addition to my last message in #18 , I tried to attribute multiple allowed ips addresses to peers, it seems like only the last one is able to display in the wg show

Here is a little test protocol I did to see it there was some trouble and here are the result and the conclusion i'm lead to :

(Still working on a debian linux 12.0.1)

Step 1 : Delete the wg0 interface

Using the command sudo ip link delete wg0 Interface successfully deleted

Step 2 : Adapt the code to test the following hypothesis : pushing multiple allowed_ips inside a peer should be working and explicitly displayed using the command sudo wg show.

I am still using the server.rs file and modified to have less peers.

use std::str::FromStr;

use defguard_wireguard_rs::{
    host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi,
};
use x25519_dalek::{EphemeralSecret, PublicKey};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create new api object for interface
    let ifname: String = if cfg!(target_os = "linux") || cfg!(target_os = "freebsd") {
        "wg0".into()
    } else {
        "utun3".into()
    };
    let wgapi = WGApi::new(ifname.clone(), false)?;

    // create interface
    wgapi.create_interface()?;

    // read current interface data
    let host = wgapi.read_interface_data()?;
    println!("WireGuard interface: {host:#?}");

    // prepare peer configuration
    let secret = EphemeralSecret::random();
    let key = PublicKey::from(&secret);
    let peer_key: Key = key.as_ref().try_into().unwrap();
    let mut peer = Peer::new(peer_key.clone());
/*     let addr = IpAddrMask::from_str("10.20.20.40/24").unwrap();
    peer.allowed_ips.push(addr); */

    println!("WireGuard interface: {host:#?}");

    // Configure host interface
    let interface_config = InterfaceConfiguration {
        name: ifname.clone(),
        prvkey: "AAECAwQFBgcICQoLDA0OD/Dh0sO0pZaHeGlaSzwtHg8=".to_string(),
        address: "10.6.0.30".to_string(),
        port: 12345,
        peers: vec![peer],
    };
    wgapi.configure_interface(&interface_config)?;

    // Create peers
    for _ in 0..3 {
        
        let secret = EphemeralSecret::random();
        let key = PublicKey::from(&secret);
        let mut peer = Peer::new(key.as_ref().try_into().unwrap());

        let addr1 = IpAddrMask::from_str("10.20.20.40/24").unwrap();
/*         let addr2 = IpAddrMask::from_str("10.20.30.40/24").unwrap(); */
        peer.allowed_ips.push(addr1);
   /*      peer.allowed_ips.push(addr2); */
        
        wgapi.configure_peer(&peer)?

        /* wgapi.remove_peer(&peer.public_key)?; */
        
    }

    // read current interface data
    let host = wgapi.read_interface_data()?;
    println!("WireGuard interface: {host:#?}");

    // remove interface
    //wgapi.remove_interface()?;

    Ok(())
}

Executing this code return this :

WireGuard interface: Host {
    listen_port: 37798,
    private_key: None,
    fwmark: Some(
        0,
    ),
    peers: {},
}
WireGuard interface: Host {
    listen_port: 37798,
    private_key: None,
    fwmark: Some(
        0,
    ),
    peers: {},
}
WireGuard interface: Host {
    listen_port: 12345,
    private_key: Some(
        000102030405060708090a0b0c0d0e0ff0e1d2c3b4a5968778695a4b3c2d1e4f,
    ),
    fwmark: Some(
        0,
    ),
    peers: {
        5c0ac8f3dcd46c687304447e831df6ae925fd396118ccc28ff73abc7c4b87a6e: Peer {
            public_key: 5c0ac8f3dcd46c687304447e831df6ae925fd396118ccc28ff73abc7c4b87a6e,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [],
        },
        d5ef523d212cead7708030d21858a20ad116f77ca98cbf0551c5dda54086422c: Peer {
            public_key: d5ef523d212cead7708030d21858a20ad116f77ca98cbf0551c5dda54086422c,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [],
        },
        c0d4f1ac5acd8476b0ab2594e144f2382a2d685a3ef19d19100ac26464aa844c: Peer {
            public_key: c0d4f1ac5acd8476b0ab2594e144f2382a2d685a3ef19d19100ac26464aa844c,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [],
        },
        efc90328d3f018dbe6f7c371ef6659955439e5b895ca8644bc77b825b1d56212: Peer {
            public_key: efc90328d3f018dbe6f7c371ef6659955439e5b895ca8644bc77b825b1d56212,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [
                IpAddrMask {
                    ip: 10.20.20.0,
                    cidr: 24,
                },
            ],
        },
    },
}

As you can see the allowed ips aren't filled for the previous, only for the last one.

Also with sudo wg show:

interface: wg0
  public key: dk5wF6ddw4IolWSxtwhIrghD753KdQRmg0m+DwkFgDo=
  private key: (hidden)
  listening port: 12345

peer: 1e9SPSEs6tdwgDDSGFiiCtEW93ypjL8FUcXdpUCGQiw=
  allowed ips: (none)

peer: XArI89zUbGhzBER+gx32rpJf05YRjMwo/3Orx8S4em4=
  allowed ips: (none)

peer: wNTxrFrNhHawqyWU4UTyOCotaFo+8Z0ZEArCZGSqhEw=
  allowed ips: (none)

peer: 78kDKNPwGNvm98Nx72ZZlVQ55biVyoZEvHe4JbHVYhI=
  allowed ips: 10.20.20.0/24

Step 3 : Modifying Code blocks to test the allowed ips :

I then updated the "prepare peer configuration" to match the following :

    // prepare peer configuration
  let secret = EphemeralSecret::random();
  let key = PublicKey::from(&secret);
  let peer_key: Key = key.as_ref().try_into().unwrap();
  let mut peer = Peer::new(peer_key.clone());
  let addr = IpAddrMask::from_str("10.20.20.40/24").unwrap();
  peer.allowed_ips.push(addr); 

Same result.

The only difference is now, the "allowed ip address" is on the 3rd generated peer. :

WireGuard interface: Host {
  listen_port: 57736,
  private_key: None,
  fwmark: Some(
      0,
  ),
  peers: {},
}
WireGuard interface: Host {
  listen_port: 57736,
  private_key: None,
  fwmark: Some(
      0,
  ),
  peers: {},
}
WireGuard interface: Host {
  listen_port: 12345,
  private_key: Some(
      000102030405060708090a0b0c0d0e0ff0e1d2c3b4a5968778695a4b3c2d1e4f,
  ),
  fwmark: Some(
      0,
  ),
  peers: {
      82b0673da03cee60079e4b2b777d828a17044b28d2b70870215906cc6c4e0f72: Peer {
          public_key: 82b0673da03cee60079e4b2b777d828a17044b28d2b70870215906cc6c4e0f72,
          preshared_key: Some(
              0000000000000000000000000000000000000000000000000000000000000000,
          ),
          protocol_version: None,
          endpoint: None,
          last_handshake: Some(
              SystemTime {
                  tv_sec: 0,
                  tv_nsec: 0,
              },
          ),
          tx_bytes: 0,
          rx_bytes: 0,
          persistent_keepalive_interval: Some(
              0,
          ),
          allowed_ips: [],
      },
      e091ed6f0f3a9b870b515af94beffae7d6f82dcd7ae4416afc3d2842aa5db52d: Peer {
          public_key: e091ed6f0f3a9b870b515af94beffae7d6f82dcd7ae4416afc3d2842aa5db52d,
          preshared_key: Some(
              0000000000000000000000000000000000000000000000000000000000000000,
          ),
          protocol_version: None,
          endpoint: None,
          last_handshake: Some(
              SystemTime {
                  tv_sec: 0,
                  tv_nsec: 0,
              },
          ),
          tx_bytes: 0,
          rx_bytes: 0,
          persistent_keepalive_interval: Some(
              0,
          ),
          allowed_ips: [],
      },
      52a3acb08995aeb79f324377cde1c89154ce4f0cd47969ded94267ff519cf83a: Peer {
          public_key: 52a3acb08995aeb79f324377cde1c89154ce4f0cd47969ded94267ff519cf83a,
          preshared_key: Some(
              0000000000000000000000000000000000000000000000000000000000000000,
          ),
          protocol_version: None,
          endpoint: None,
          last_handshake: Some(
              SystemTime {
                  tv_sec: 0,
                  tv_nsec: 0,
              },
          ),
          tx_bytes: 0,
          rx_bytes: 0,
          persistent_keepalive_interval: Some(
              0,
          ),
          allowed_ips: [
              IpAddrMask {
                  ip: 10.20.20.0,
                  cidr: 24,
              },
          ],
      },
      38da9b5ff3d74e7fdf1098b7c197c4a4429bf94d1ad1858a760aeadfeb4f915f: Peer {
          public_key: 38da9b5ff3d74e7fdf1098b7c197c4a4429bf94d1ad1858a760aeadfeb4f915f,
          preshared_key: Some(
              0000000000000000000000000000000000000000000000000000000000000000,
          ),
          protocol_version: None,
          endpoint: None,
          last_handshake: Some(
              SystemTime {
                  tv_sec: 0,
                  tv_nsec: 0,
              },
          ),
          tx_bytes: 0,
          rx_bytes: 0,
          persistent_keepalive_interval: Some(
              0,
          ),
          allowed_ips: [],
      },
  },
}

(I still never catched why it is mandatory to have a peer that is unused, just to create the interface and initialize the vec[peer] ... It should be done another way to avoid having an empty peer...)

Step 4 : Modify the for Loop :

I modified the for loop with :

    for _ in 0..3 {
        
        let secret = EphemeralSecret::random();
        let key = PublicKey::from(&secret);
        let mut peer = Peer::new(key.as_ref().try_into().unwrap());

        let addr1 = IpAddrMask::from_str("10.20.20.40/24").unwrap();
         let addr2 = IpAddrMask::from_str("10.20.30.40/24").unwrap(); 
        peer.allowed_ips.push(addr1);
        peer.allowed_ips.push(addr2); 
        
        wgapi.configure_peer(&peer)?

        /* wgapi.remove_peer(&peer.public_key)?; */
        
    }

It gives me this output :

    WireGuard interface: Host {
    listen_port: 36653,
    private_key: None,
    fwmark: Some(
        0,
    ),
    peers: {},
}
WireGuard interface: Host {
    listen_port: 36653,
    private_key: None,
    fwmark: Some(
        0,
    ),
    peers: {},
}
WireGuard interface: Host {
    listen_port: 12345,
    private_key: Some(
        000102030405060708090a0b0c0d0e0ff0e1d2c3b4a5968778695a4b3c2d1e4f,
    ),
    fwmark: Some(
        0,
    ),
    peers: {
        ea1b9b3ed9d23f9fb3bff998af3e81b905ec880588666fbbae6535d1f2b17a58: Peer {
            public_key: ea1b9b3ed9d23f9fb3bff998af3e81b905ec880588666fbbae6535d1f2b17a58,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [],
        },
        181665df12282198a39e4029e312368f93df0fb2cbec69335cafe2b89ed9e744: Peer {
            public_key: 181665df12282198a39e4029e312368f93df0fb2cbec69335cafe2b89ed9e744,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [],
        },
        ffe797105a2e9e5d48a9912e9bad7aec00fa5c6e4fdc57ad2952e461618cd172: Peer {
            public_key: ffe797105a2e9e5d48a9912e9bad7aec00fa5c6e4fdc57ad2952e461618cd172,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [
                IpAddrMask {
                    ip: 10.20.20.0,
                    cidr: 24,
                },
                IpAddrMask {
                    ip: 10.20.30.0,
                    cidr: 24,
                },
            ],
        },
        112bce748e8f559dfbfb216e49b015ff0470fda514bb0ad40d39db68bdd5b866: Peer {
            public_key: 112bce748e8f559dfbfb216e49b015ff0470fda514bb0ad40d39db68bdd5b866,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [],
        },
    },
}

And with the sudo wg show :

interface: wg0
  public key: dk5wF6ddw4IolWSxtwhIrghD753KdQRmg0m+DwkFgDo=
  private key: (hidden)
  listening port: 12345

peer: ESvOdI6PVZ37+yFuSbAV/wRw/aUUuwrUDTnbaL3VuGY=
  allowed ips: (none)

peer: GBZl3xIoIZijnkAp4xI2j5PfD7LL7GkzXK/iuJ7Z50Q=
  allowed ips: (none)

peer: 6hubPtnSP5+zv/mYrz6BuQXsiAWIZm+7rmU10fKxelg=
  allowed ips: (none)

peer: /+eXEFounl1IqZEum6167AD6XG5P3FetKVLkYWGM0XI=
  allowed ips: 10.20.20.0/24, 10.20.30.0/24

As you can see, the last one is correctly filled (not the last one, but actually the 3rd generated which I don't know why this order in the peer vector.

And what is somewhat very shocking, is that I added at the end of the for loop a line to print the peers :

    for _ in 0..3 {
      
      let secret = EphemeralSecret::random();
      let key = PublicKey::from(&secret);
      let mut peer = Peer::new(key.as_ref().try_into().unwrap());

      let addr1 = IpAddrMask::from_str("10.20.20.40/24").unwrap();
       let addr2 = IpAddrMask::from_str("10.20.30.40/24").unwrap(); 
      peer.allowed_ips.push(addr1);
      peer.allowed_ips.push(addr2); 
      
      wgapi.configure_peer(&peer)?;

      println!("{:?}", peer)
      /* wgapi.remove_peer(&peer.public_key)?; */
      
  }

And the output of that is :

Peer { public_key: e7869bc726a2193df5432e2d4b77209c2e780b6815935a41e7bf6193dd66302c, preshared_key: None, protocol_version: None, endpoint: None, last_handshake: None, tx_bytes: 0, rx_bytes: 0, persistent_keepalive_interval: None, allowed_ips: [IpAddrMask { ip: 10.20.20.40, cidr: 24 }, IpAddrMask { ip: 10.20.30.40, cidr: 24 }] }

Peer { public_key: 72c6279b5f0079071c2fd54f1b02e275504a341ecb8396439b1fa450256d1b1f, preshared_key: None, protocol_version: None, endpoint: None, last_handshake: None, tx_bytes: 0, rx_bytes: 0, persistent_keepalive_interval: None, allowed_ips: [IpAddrMask { ip: 10.20.20.40, cidr: 24 }, IpAddrMask { ip: 10.20.30.40, cidr: 24 }] }

Peer { public_key: e26a6c4fa4f93f7c502a2eb9e97588741fb65a4b566faa495b2c2d4318885b7d, preshared_key: None, protocol_version: None, endpoint: None, last_handshake: None, tx_bytes: 0, rx_bytes: 0, persistent_keepalive_interval: None, allowed_ips: [IpAddrMask { ip: 10.20.20.40, cidr: 24 }, IpAddrMask { ip: 10.20.30.40, cidr: 24 }] }

Which means that both ip addresses are correctly inside the peer, but they don't appear inside the host.

Because the host still gives this output :

WireGuard interface: Host {
    listen_port: 12345,
    private_key: Some(
        000102030405060708090a0b0c0d0e0ff0e1d2c3b4a5968778695a4b3c2d1e4f,
    ),
    fwmark: Some(
        0,
    ),
    peers: {
        857d93bf1e2c5005294d7d22120dfaf03d931044351b68f810f2616b0c14917c: Peer {
            public_key: 857d93bf1e2c5005294d7d22120dfaf03d931044351b68f810f2616b0c14917c,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [],
        },
        72c6279b5f0079071c2fd54f1b02e275504a341ecb8396439b1fa450256d1b1f: Peer {
            public_key: 72c6279b5f0079071c2fd54f1b02e275504a341ecb8396439b1fa450256d1b1f,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [],
        },
        e7869bc726a2193df5432e2d4b77209c2e780b6815935a41e7bf6193dd66302c: Peer {
            public_key: e7869bc726a2193df5432e2d4b77209c2e780b6815935a41e7bf6193dd66302c,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [],
        },
        e26a6c4fa4f93f7c502a2eb9e97588741fb65a4b566faa495b2c2d4318885b7d: Peer {
            public_key: e26a6c4fa4f93f7c502a2eb9e97588741fb65a4b566faa495b2c2d4318885b7d,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [
                IpAddrMask {
                    ip: 10.20.20.0,
                    cidr: 24,
                },
                IpAddrMask {
                    ip: 10.20.30.0,
                    cidr: 24,
                },
            ],
        },
    },
}

Am I missing something in this regard ?

Best,
Ange

Clone trait for the WGApi ?

Hey,

Would it be possible to add the clone trait to this structure ?
The lifetime can't be extended because there is no copy trait.

best,
Ange

Sequence of creating peers and host blurry

Hey @wojcik91,

I'd like to have a better understanding of how you implement the host and peers.

 // prepare peer configuration
 let secret = EphemeralSecret::random();
 let key = PublicKey::from(&secret);
 let peer_key: Key = key.as_ref().try_into().unwrap();
 let mut peer = Peer::new(peer_key.clone());
 let addr = IpAddrMask::from_str("10.20.20.40/24").unwrap();
 peer.allowed_ips.push(addr);

 // Configure host interface
 let interface_config = InterfaceConfiguration {
     name: ifname.clone(),
     prvkey: "AAECAwQFBgcICQoLDA0OD/Dh0sO0pZaHeGlaSzwtHg8=".to_string(),
     address: "10.6.0.30".to_string(),
     port: 12345,
     peers: vec![peer],
 };
 wgapi.configure_interface(&interface_config)?;

 // Create peers
 for _ in 0..32 {
     let secret = EphemeralSecret::random();
     let key = PublicKey::from(&secret);
     let peer = Peer::new(key.as_ref().try_into().unwrap());
     wgapi.configure_peer(&peer)?;
     wgapi.remove_peer(&peer.public_key)?;
 }

In this code you "prepare" the peer configuration. Does this mean that the host is an actual peer and you configure this, or do you configure "all" the peers ??
If so, why in the example would you give an allowed_ip like 10.20.30.40 if the 40 digit is stripped and replaced by a 0 ? (Here is an example of a sudo cargo run with the 0.2.1 release and the last version of the server.rs :

WireGuard interface: Host {
    listen_port: 50729,
    private_key: None,
    fwmark: Some(
        0,
    ),
    peers: {},
}
WireGuard interface: Host {
    listen_port: 12345,
    private_key: Some(
        000102030405060708090a0b0c0d0e0ff0e1d2c3b4a5968778695a4b3c2d1e4f,
    ),
    fwmark: Some(
        0,
    ),
    peers: {
        2e38674171e7bc7c8eb8596382ad1fbde455a9edd3b559a31643cdadd3c34d33: Peer {
            public_key: 2e38674171e7bc7c8eb8596382ad1fbde455a9edd3b559a31643cdadd3c34d33,
            preshared_key: Some(
                0000000000000000000000000000000000000000000000000000000000000000,
            ),
            protocol_version: None,
            endpoint: None,
            last_handshake: Some(
                SystemTime {
                    tv_sec: 0,
                    tv_nsec: 0,
                },
            ),
            tx_bytes: 0,
            rx_bytes: 0,
            persistent_keepalive_interval: Some(
                0,
            ),
            allowed_ips: [
                IpAddrMask {
                    ip: 10.20.20.0,
                    cidr: 24,
                },
            ],
        },
    },
}

you can see that the ip is the allowed ip is clearly "ip: 10.20.20.0" which means that the 40 has been stripped.

Also, is it possible to push multiple addresses to have multiple allowed_ips ?

After, you configure the host interface, which is fine, no problem with that.

After that, you create some peers, but you don't initialize them with any ip address neither allowed ips. How so ?

Do you need to (or can you) manually give them addresses, is it managed already by the host ?

Could you please explain the sequence ?

for context, my goal is to make an API that generates Wireguard Configurations, and then be able to start them with the wireguard client (lot complexity that defguard doesn't manage because of my very personal use case).

And finally could you please explain why does the privatekey has to be initialized with a string, wouldn't it be easier to manage keys rather than the string ? Also for security purposes.

Best,
Ange

Can clone trait cause damage to host and WGApi ?

Hi,

I need to sequentially create peers using a web server using an API, which means I must create peers among the time,

If I want to pass the WGApi and Host to other function , but I can't because they don't implement the copy trait, because some of the declared object in the struct don't implement the copy trait.

So I implemented the Clone Trait myself and was wondering if it can concur with some problem to clone an instance of host and WGApi, if so what could be the problem ?

And moreover, if it's not a problem, would you mind implement it too in the official code so we can clone those struct ?

Best,
Ange

Route adding when creating the interface not working

Hey @wojcik91 ,

Since the 0.2.1 release, the library is not able to automatically add the route IP to the routing table.
I have to manually add the routing ip with :

sudo ip route add 10.0.0.0/24" dev wg0 (depending on the network...)

And this way it works.

Do you have some insights about this ? Maybe some things I have to add that are not present in the server.rs right now as example ? (it may also complete the #23 )

Best,
Ange

How work write and delete peer ?

Hi,

I need to rewrite peers without restarting the interface (i must not disconnect other peer to add or delete one from the interface)

Is it possible with the write_peer and delete_peer ?

If so, "updating" a peer sequence should Just be :

write_peer
delete_peer
write_peer

Is that correct ?

Best,
Ange

After disconnecting DNS rules are not removed

After disconnecting from VPN, DNS resolver entries are still active - thus nothing works (since VPN is not available and DNS from vpn is not availabe - so nothing is resolving).

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.