From 170c8267bff7da60234b5669b4f02fff493a9c36 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Tue, 11 May 2021 19:31:47 +0200 Subject: [PATCH] client, server: make adding routes optional (#71) --- client/src/main.rs | 43 +++++++++++++++++++++++++++++++++++-------- server/src/main.rs | 18 ++++++++++++++---- shared/src/types.rs | 8 ++++++++ shared/src/wg.rs | 5 ++++- 4 files changed, 61 insertions(+), 13 deletions(-) diff --git a/client/src/main.rs b/client/src/main.rs index 78e4cc1..fffebf5 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -5,7 +5,8 @@ use indoc::printdoc; use shared::{ interface_config::InterfaceConfig, prompts, AddAssociationOpts, AddCidrOpts, AddPeerOpts, Association, AssociationContents, Cidr, CidrTree, EndpointContents, InstallOpts, Interface, - IoErrorContext, Peer, RedeemContents, State, CLIENT_CONFIG_PATH, REDEEM_TRANSITION_WAIT, + IoErrorContext, Peer, RedeemContents, RoutingOpt, State, CLIENT_CONFIG_PATH, + REDEEM_TRANSITION_WAIT, }; use std::{ fmt, @@ -72,6 +73,9 @@ enum Command { #[structopt(flatten)] opts: InstallOpts, + + #[structopt(flatten)] + routing: RoutingOpt, }, /// Enumerate all innernet connections. @@ -103,6 +107,9 @@ enum Command { #[structopt(flatten)] hosts: HostsOpt, + #[structopt(flatten)] + routing: RoutingOpt, + interface: Interface, }, @@ -112,12 +119,15 @@ enum Command { #[structopt(flatten)] hosts: HostsOpt, + + #[structopt(flatten)] + routing: RoutingOpt, }, /// Uninstall an innernet network. Uninstall { interface: Interface }, - /// Bring down the interface (equivalent to "wg-quick down [interface]") + /// Bring down the interface (equivalent to "wg-quick down ") Down { interface: Interface }, /// Add a new peer. @@ -219,7 +229,12 @@ fn update_hosts_file( Ok(()) } -fn install(invite: &Path, hosts_file: Option, opts: InstallOpts) -> Result<(), Error> { +fn install( + invite: &Path, + hosts_file: Option, + opts: InstallOpts, + routing: RoutingOpt, +) -> Result<(), Error> { shared::ensure_dirs_exist(&[*CLIENT_CONFIG_PATH])?; let config = InterfaceConfig::from_file(invite)?; @@ -240,7 +255,7 @@ fn install(invite: &Path, hosts_file: Option, opts: InstallOpts) -> Res } let iface = iface.parse()?; - redeem_invite(&iface, config, target_conf).map_err(|e| { + redeem_invite(&iface, config, target_conf, routing).map_err(|e| { println!("{} bringing down the interface.", "[*]".dimmed()); if let Err(e) = wg::down(&iface) { println!("{} failed to bring down interface: {}.", "[*]".yellow(), e.to_string()); @@ -251,7 +266,7 @@ fn install(invite: &Path, hosts_file: Option, opts: InstallOpts) -> Res let mut fetch_success = false; for _ in 0..3 { - if fetch(&iface, false, hosts_file.clone()).is_ok() { + if fetch(&iface, false, hosts_file.clone(), routing).is_ok() { fetch_success = true; break; } @@ -305,6 +320,7 @@ fn redeem_invite( iface: &InterfaceName, mut config: InterfaceConfig, target_conf: PathBuf, + routing: RoutingOpt, ) -> Result<(), Error> { println!("{} bringing up the interface.", "[*]".dimmed()); let resolved_endpoint = config.server.external_endpoint.resolve()?; @@ -318,6 +334,7 @@ fn redeem_invite( config.server.internal_endpoint.ip(), resolved_endpoint, )), + !routing.no_routing, )?; println!("{} Generating new keypair.", "[*]".dimmed()); @@ -360,9 +377,10 @@ fn up( interface: &InterfaceName, loop_interval: Option, hosts_path: Option, + routing: RoutingOpt, ) -> Result<(), Error> { loop { - fetch(interface, true, hosts_path.clone())?; + fetch(interface, true, hosts_path.clone(), routing)?; match loop_interval { Some(interval) => thread::sleep(interval), None => break, @@ -376,6 +394,7 @@ fn fetch( interface: &InterfaceName, bring_up_interface: bool, hosts_path: Option, + routing: RoutingOpt, ) -> Result<(), Error> { let config = InterfaceConfig::from_interface(interface)?; let interface_up = if let Ok(interfaces) = DeviceInfo::enumerate() { @@ -405,6 +424,7 @@ fn fetch( config.server.internal_endpoint.ip(), resolved_endpoint, )), + !routing.no_routing, )? } @@ -910,22 +930,29 @@ fn run(opt: Opts) -> Result<(), Error> { invite, hosts, opts, - } => install(&invite, hosts.into(), opts)?, + routing, + } => install(&invite, hosts.into(), opts, routing)?, Command::Show { short, tree, interface, } => show(short, tree, interface)?, - Command::Fetch { interface, hosts } => fetch(&interface, false, hosts.into())?, + Command::Fetch { + interface, + hosts, + routing, + } => fetch(&interface, false, hosts.into(), routing)?, Command::Up { interface, daemon, hosts, + routing, interval, } => up( &interface, daemon.then(|| Duration::from_secs(interval)), hosts.into(), + routing, )?, Command::Down { interface } => wg::down(&interface)?, Command::Uninstall { interface } => uninstall(&interface)?, diff --git a/server/src/main.rs b/server/src/main.rs index 1cf382d..d6a1fd0 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -6,7 +6,7 @@ use ipnetwork::IpNetwork; use parking_lot::{Mutex, RwLock}; use rusqlite::Connection; use serde::{Deserialize, Serialize}; -use shared::{AddCidrOpts, AddPeerOpts, IoErrorContext, INNERNET_PUBKEY_HEADER}; +use shared::{AddCidrOpts, AddPeerOpts, IoErrorContext, RoutingOpt, INNERNET_PUBKEY_HEADER}; use std::{ collections::{HashMap, VecDeque}, convert::TryInto, @@ -60,7 +60,12 @@ enum Command { Uninstall { interface: Interface }, /// Serve the coordinating server for an existing network. - Serve { interface: Interface }, + Serve { + interface: Interface, + + #[structopt(flatten)] + routing: RoutingOpt, + }, /// Add a peer to an existing network. AddPeer { @@ -206,7 +211,7 @@ async fn main() -> Result<(), Box> { } } Command::Uninstall { interface } => uninstall(&interface, &conf)?, - Command::Serve { interface } => serve(*interface, &conf).await?, + Command::Serve { interface, routing } => serve(*interface, &conf, routing).await?, Command::AddPeer { interface, args } => add_peer(&interface, &conf, args)?, Command::AddCidr { interface, args } => add_cidr(&interface, &conf, args)?, } @@ -370,7 +375,11 @@ fn spawn_expired_invite_sweeper(db: Db) { }); } -async fn serve(interface: InterfaceName, conf: &ServerConfig) -> Result<(), Error> { +async fn serve( + interface: InterfaceName, + conf: &ServerConfig, + routing: RoutingOpt, +) -> Result<(), Error> { let config = ConfigFile::from_file(conf.config_path(&interface))?; let conn = open_database_connection(&interface, conf)?; @@ -387,6 +396,7 @@ async fn serve(interface: InterfaceName, conf: &ServerConfig) -> Result<(), Erro IpNetwork::new(config.address, config.network_cidr_prefix)?, Some(config.listen_port), None, + !routing.no_routing, )?; DeviceConfigBuilder::new() diff --git a/shared/src/types.rs b/shared/src/types.rs index 84ac6c1..51ac87a 100644 --- a/shared/src/types.rs +++ b/shared/src/types.rs @@ -346,6 +346,14 @@ pub struct AddAssociationOpts { pub cidr2: Option, } +#[derive(Debug, Clone, Copy, StructOpt)] +pub struct RoutingOpt { + #[structopt(long)] + /// Whether the routing should be done by innernet or is done by an + /// external tool like e.g. babeld. + pub no_routing: bool, +} + #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] pub struct PeerContents { pub name: Hostname, diff --git a/shared/src/wg.rs b/shared/src/wg.rs index 8143d0f..4db8978 100644 --- a/shared/src/wg.rs +++ b/shared/src/wg.rs @@ -67,6 +67,7 @@ pub fn up( address: IpNetwork, listen_port: Option, peer: Option<(&str, IpAddr, SocketAddr)>, + do_routing: bool, ) -> Result<(), Error> { let mut device = DeviceConfigBuilder::new(); if let Some((public_key, address, endpoint)) = peer { @@ -83,7 +84,9 @@ pub fn up( .set_private_key(wgctrl::Key::from_base64(&private_key).unwrap()) .apply(interface)?; set_addr(interface, address)?; - add_route(interface, address)?; + if do_routing { + add_route(interface, address)?; + } Ok(()) }