diff --git a/Cargo.lock b/Cargo.lock index 6fa9c26..b63117e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,9 +34,9 @@ checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -122,9 +122,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.148" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "log" @@ -241,9 +241,9 @@ checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -309,9 +309,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.37" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", diff --git a/examples/server.rs b/examples/server.rs index 2c99327..ab9f1cc 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -6,7 +6,7 @@ use defguard_wireguard_rs::{ use x25519_dalek::{EphemeralSecret, PublicKey}; fn main() -> Result<(), Box> { - // Create new api object for interface + // Create new api object for interface management let ifname: String = if cfg!(target_os = "linux") || cfg!(target_os = "freebsd") { "wg0".into() } else { @@ -14,22 +14,25 @@ fn main() -> Result<(), Box> { }; let wgapi = WGApi::new(ifname.clone(), false)?; - // create interface + // create host interface wgapi.create_interface()?; - // read current interface data + // read current interface status let host = wgapi.read_interface_data()?; - println!("WireGuard interface: {host:#?}"); + println!("WireGuard interface before configuration: {host:#?}"); - // prepare peer configuration + // store peer keys to remove peers later + let mut peer_keys = Vec::new(); + + // prepare initial WireGuard interface configuration with one client 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.30.40/24").unwrap(); + peer_keys.push(peer_key.clone()); + let mut peer = Peer::new(peer_key); + let addr = IpAddrMask::from_str("10.20.30.2/32").unwrap(); peer.allowed_ips.push(addr); - // Configure host interface let interface_config = InterfaceConfiguration { name: ifname.clone(), prvkey: "AAECAwQFBgcICQoLDA0OD/Dh0sO0pZaHeGlaSzwtHg8=".to_string(), @@ -37,20 +40,39 @@ fn main() -> Result<(), Box> { port: 12345, peers: vec![peer], }; + + // apply initial interface configuration wgapi.configure_interface(&interface_config)?; - // Create peers - for _ in 0..32 { + // read current interface status + let host = wgapi.read_interface_data()?; + println!("WireGuard interface initial config: {host:#?}"); + + // add more WireGuard clients + for peer_id in 3..13 { let secret = EphemeralSecret::random(); let key = PublicKey::from(&secret); - let peer = Peer::new(key.as_ref().try_into().unwrap()); + 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); + // add peer to WireGuard interface wgapi.configure_peer(&peer)?; - wgapi.remove_peer(&peer.public_key)?; } - // read current interface data + // read current interface status + let host = wgapi.read_interface_data()?; + println!("WireGuard interface with peers: {host:#?}"); + + // remove all peers + for peer_key in peer_keys { + wgapi.remove_peer(&peer_key)?; + } + + // read current interface status let host = wgapi.read_interface_data()?; - println!("WireGuard interface: {host:#?}"); + println!("WireGuard interface without peers: {host:#?}"); // remove interface wgapi.remove_interface()?; diff --git a/src/host.rs b/src/host.rs index b59bfb2..4827303 100644 --- a/src/host.rs +++ b/src/host.rs @@ -158,7 +158,7 @@ impl Peer { } /// WireGuard host representation. -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct Host { pub listen_port: u16, pub private_key: Option, diff --git a/src/wgapi_freebsd.rs b/src/wgapi_freebsd.rs index 479ded0..0e6e0a0 100644 --- a/src/wgapi_freebsd.rs +++ b/src/wgapi_freebsd.rs @@ -7,6 +7,7 @@ use std::{process::Command, str::FromStr}; /// Manages interfaces created with FreeBSD kernel WireGuard module. /// /// Requires FreeBSD version 14+. +#[derive(Clone)] pub struct WireguardApiFreebsd { ifname: String, } diff --git a/src/wgapi_linux.rs b/src/wgapi_linux.rs index 43f8490..7db7ee3 100644 --- a/src/wgapi_linux.rs +++ b/src/wgapi_linux.rs @@ -8,6 +8,7 @@ use std::str::FromStr; /// /// Communicates with kernel module using `Netlink` IPC protocol. /// Requires Linux kernel version 5.6+. +#[derive(Clone)] pub struct WireguardApiLinux { ifname: String, } diff --git a/src/wgapi_userspace.rs b/src/wgapi_userspace.rs index f9ea601..f1c144a 100644 --- a/src/wgapi_userspace.rs +++ b/src/wgapi_userspace.rs @@ -18,6 +18,7 @@ const USERSPACE_EXECUTABLE: &str = "wireguard-go"; /// /// We assume that `wireguard-go` executable is managed externally and available in `PATH`. /// Currently works on Unix platforms. +#[derive(Clone)] pub struct WireguardApiUserspace { ifname: String, }