diff options
author | Himbeer <himbeer@disroot.org> | 2025-03-18 11:18:29 +0100 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2025-03-18 11:18:29 +0100 |
commit | 44cb6d656fb5a17cd7e0ac94a7e643076d8e1ea6 (patch) | |
tree | 6d84bdd232be830c92fe69115cc9c0ad3fa5d8f9 | |
parent | 3ac21a93b90f29dbbd63fc204228f766e3f070d6 (diff) |
Bring up and configure the links after (re)creation
-rw-r--r-- | Cargo.lock | 392 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 47 |
3 files changed, 428 insertions, 12 deletions
@@ -3,6 +3,21 @@ version = 3 [[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] name = "anyhow" version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -15,6 +30,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] name = "base64" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -27,6 +57,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + +[[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -86,6 +122,95 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] name = "getrandom" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -97,6 +222,12 @@ dependencies = [ ] [[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -115,6 +246,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] name = "memoffset" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -124,6 +261,26 @@ dependencies = [ ] [[package]] +name = "miniz_oxide" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] name = "netlink-packet-core" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -153,7 +310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66" dependencies = [ "anyhow", - "bitflags", + "bitflags 1.3.2", "byteorder", "libc", "netlink-packet-core", @@ -161,6 +318,20 @@ dependencies = [ ] [[package]] +name = "netlink-packet-route" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74c171cd77b4ee8c7708da746ce392440cb7bcf618d122ec9ecc607b12938bf4" +dependencies = [ + "anyhow", + "byteorder", + "libc", + "log", + "netlink-packet-core", + "netlink-packet-utils", +] + +[[package]] name = "netlink-packet-utils" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -169,7 +340,7 @@ dependencies = [ "anyhow", "byteorder", "paste", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -187,6 +358,20 @@ dependencies = [ ] [[package]] +name = "netlink-proto" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72452e012c2f8d612410d89eea01e2d9b56205274abb35d53f60200b2ec41d60" +dependencies = [ + "bytes", + "futures", + "log", + "netlink-packet-core", + "netlink-sys", + "thiserror 2.0.12", +] + +[[package]] name = "netlink-request" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -194,10 +379,10 @@ checksum = "890da3a441eac11fbc621eaf5da8186032dbd047c37e5cf2f49b80319b381a2f" dependencies = [ "netlink-packet-core", "netlink-packet-generic", - "netlink-packet-route", + "netlink-packet-route 0.17.1", "netlink-packet-utils", "netlink-sys", - "nix", + "nix 0.25.1", "once_cell", ] @@ -208,8 +393,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16c903aa70590cb93691bf97a767c8d1d6122d2cc9070433deb3bbf36ce8bd23" dependencies = [ "bytes", + "futures", "libc", "log", + "tokio", ] [[package]] @@ -219,7 +406,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ "autocfg", - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "memoffset", @@ -227,6 +414,26 @@ dependencies = [ ] [[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.9.0", + "cfg-if", + "libc", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] name = "once_cell" version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -239,6 +446,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] name = "pin-utils" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -272,13 +485,52 @@ dependencies = [ ] [[package]] +name = "rsdsl_netlinklib" +version = "0.5.0" +source = "git+https://github.com/rsdsl/netlinklib.git#7fae1fc884ecfe234e96b96f0a60d469905272ba" +dependencies = [ + "futures", + "libc", + "netlink-packet-route 0.19.0", + "netlink-proto", + "rtnetlink", + "thiserror 1.0.69", + "tokio", +] + +[[package]] name = "rsdsl_wg" version = "0.1.0" dependencies = [ + "rsdsl_netlinklib", "wireguard-control", ] [[package]] +name = "rtnetlink" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b684475344d8df1859ddb2d395dd3dac4f8f3422a1aa0725993cb375fc5caba5" +dependencies = [ + "futures", + "log", + "netlink-packet-core", + "netlink-packet-route 0.19.0", + "netlink-packet-utils", + "netlink-proto", + "netlink-sys", + "nix 0.27.1", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -314,6 +566,25 @@ dependencies = [ ] [[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] name = "subtle" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -336,7 +607,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", ] [[package]] @@ -351,6 +631,31 @@ dependencies = [ ] [[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio" +version = "1.44.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +dependencies = [ + "backtrace", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys", +] + +[[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -363,6 +668,79 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] name = "wireguard-control" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -374,7 +752,7 @@ dependencies = [ "log", "netlink-packet-core", "netlink-packet-generic", - "netlink-packet-route", + "netlink-packet-route 0.17.1", "netlink-packet-utils", "netlink-packet-wireguard", "netlink-request", @@ -6,4 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +rsdsl_netlinklib = { git = "https://github.com/rsdsl/netlinklib.git", features = ["blocking"] } wireguard-control = "1.6.1" diff --git a/src/main.rs b/src/main.rs index 5faa52b..0f110a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use std::fs::File; use std::io; use std::net::{IpAddr, SocketAddr}; +use rsdsl_netlinklib::blocking as nl; use wireguard_control::backends::kernel as wg; const CONFIG_PATH: &str = "/data/wg.peers"; @@ -91,6 +92,7 @@ impl std::error::Error for ConfigError {} enum SetupError { InvalidInterfaceName(String, wireguard_control::InvalidInterfaceName), Io(io::Error), + Netlinklib(rsdsl_netlinklib::Error), } impl fmt::Display for SetupError { @@ -102,6 +104,7 @@ impl fmt::Display for SetupError { write!(f, "invalid interface name {}: {}", name, e) } Self::Io(e) => write!(f, "io: {}", e), + Self::Netlinklib(e) => write!(f, "rsdsl_netlinklib: {}", e), } } } @@ -112,6 +115,12 @@ impl From<io::Error> for SetupError { } } +impl From<rsdsl_netlinklib::Error> for SetupError { + fn from(e: rsdsl_netlinklib::Error) -> SetupError { + SetupError::Netlinklib(e) + } +} + impl std::error::Error for SetupError {} #[derive(Debug)] @@ -144,13 +153,18 @@ impl From<SetupError> for Error { impl std::error::Error for Error {} #[derive(Debug)] +struct IpConfig { + addresses: Vec<(IpAddr, u8)>, + allowed_ips: Vec<wireguard_control::AllowedIp>, +} + +#[derive(Debug)] struct Link { endpoint: SocketAddr, private_key: wireguard_control::Key, public_key: wireguard_control::Key, preshared_key: wireguard_control::Key, - addresses: Vec<(IpAddr, u8)>, - allowed_ips: Vec<wireguard_control::AllowedIp>, + ip_config: IpConfig, keepalive_seconds: u16, } @@ -282,8 +296,10 @@ impl LinkConfig { private_key, public_key, preshared_key, - addresses, - allowed_ips, + ip_config: IpConfig { + addresses, + allowed_ips, + }, keepalive_seconds, }), }) @@ -355,6 +371,7 @@ fn run() -> Result<(), Error> { fn configure(name: String, link: Link) -> Result<(), SetupError> { let addresses_pretty = link + .ip_config .addresses .iter() .map(|(addr, cidr)| format!("{}/{}", addr, cidr)) @@ -362,6 +379,7 @@ fn configure(name: String, link: Link) -> Result<(), SetupError> { .unwrap_or_default(); let allowed_ips_pretty = link + .ip_config .allowed_ips .iter() .map(|net| format!("{}/{}", net.address, net.cidr)) @@ -390,7 +408,7 @@ fn configure(name: String, link: Link) -> Result<(), SetupError> { .set_endpoint(link.endpoint) .set_preshared_key(link.preshared_key) .replace_allowed_ips() - .add_allowed_ips(&link.allowed_ips); + .add_allowed_ips(&link.ip_config.allowed_ips); if link.keepalive_seconds != 0 { peer = peer.set_persistent_keepalive_interval(link.keepalive_seconds); @@ -403,6 +421,25 @@ fn configure(name: String, link: Link) -> Result<(), SetupError> { .add_peer(peer) .apply(&iface, wireguard_control::Backend::Kernel)?; + configure_netlink(name, link.ip_config) +} + +fn configure_netlink(name: String, ip_config: IpConfig) -> Result<(), SetupError> { + let conn = nl::Connection::new()?; + + conn.link_set(name.clone(), true)?; + + for (addr, prefix_length) in ip_config.addresses { + conn.address_add(name.clone(), addr, prefix_length)?; + } + + for wireguard_control::AllowedIp { address, cidr } in ip_config.allowed_ips { + match address { + IpAddr::V4(address) => conn.route_add4(address, cidr, None, name.clone()), + IpAddr::V6(address) => conn.route_add6(address, cidr, None, name.clone()), + }?; + } + Ok(()) } |