From 25e8b653948187f4dd5bdb81e117d8659067aa36 Mon Sep 17 00:00:00 2001 From: asonix Date: Thu, 18 Mar 2021 22:13:16 -0500 Subject: [PATCH] Enable optional NAT for tunnels --- config.toml | 3 +++ src/rules.rs | 58 +++++++++++++++++++++++++++++------------- src/startup/mod.rs | 12 ++++++++- src/startup/preload.rs | 11 ++++++++ 4 files changed, 65 insertions(+), 19 deletions(-) diff --git a/config.toml b/config.toml index adee8c7..0bb6cb3 100644 --- a/config.toml +++ b/config.toml @@ -9,6 +9,9 @@ tunnel = [ [network] shared-internal = true +nats = [ + "wg2" +] [server] debug = true diff --git a/src/rules.rs b/src/rules.rs index a4cf4dc..0a47cc8 100644 --- a/src/rules.rs +++ b/src/rules.rs @@ -121,15 +121,26 @@ pub(crate) async fn unset(interfaces: &Interfaces, rule: Rule) -> Result<(), any .await?; } for iface in &interfaces.tunnel { - iptables::delete_forward_postrouting( - rule.proto, - iface.ip, - iface.mask, - interfaces.external.ip, - rule.port, - dest_ip, - ) - .await?; + if interfaces + .nats + .iter() + .any(|nat_iface| *nat_iface == iface.interface) + { + iptables::delete_forward_prerouting( + rule.proto, iface.ip, iface.mask, rule.port, dest_ip, dest_port, + ) + .await?; + } else { + iptables::delete_forward_postrouting( + rule.proto, + iface.ip, + iface.mask, + interfaces.external.ip, + rule.port, + dest_ip, + ) + .await?; + } } } } @@ -193,15 +204,26 @@ pub(crate) async fn apply(interfaces: &Interfaces, rule: Rule) -> Result<(), any .await?; } for iface in &interfaces.tunnel { - iptables::forward_postrouting( - rule.proto, - iface.ip, - iface.mask, - interfaces.external.ip, - rule.port, - dest_ip, - ) - .await?; + if interfaces + .nats + .iter() + .any(|nat_iface| *nat_iface == iface.interface) + { + iptables::forward_prerouting( + rule.proto, iface.ip, iface.mask, rule.port, dest_ip, dest_port, + ) + .await?; + } else { + iptables::forward_postrouting( + rule.proto, + iface.ip, + iface.mask, + interfaces.external.ip, + rule.port, + dest_ip, + ) + .await?; + } } } } diff --git a/src/startup/mod.rs b/src/startup/mod.rs index da1324e..a6ba45c 100644 --- a/src/startup/mod.rs +++ b/src/startup/mod.rs @@ -26,6 +26,8 @@ struct InterfaceConfig { #[serde(rename_all = "kebab-case")] struct NetworkConfig { shared_internal: bool, + #[serde(default)] + nats: Vec, } #[derive(serde::Deserialize)] @@ -39,6 +41,7 @@ pub struct Interfaces { pub(crate) internal: Vec, pub(crate) tunnel: Vec, pub(crate) shared_internal: bool, + pub(crate) nats: Vec, } pub(crate) struct InterfaceInfo { @@ -95,11 +98,17 @@ impl Interfaces { }, InterfaceInfo { interface: String::from("wg1"), - ip: "192.168.4.0".parse()?, + ip: "10.42.6.0".parse()?, + mask: 24, + }, + InterfaceInfo { + interface: String::from("wg2"), + ip: "10.42.6.0".parse()?, mask: 24, }, ], shared_internal: false, + nats: Vec::new(), }); } @@ -137,6 +146,7 @@ impl Interfaces { internal, tunnel, shared_internal: config.network.shared_internal, + nats: config.network.nats.clone(), }) } diff --git a/src/startup/preload.rs b/src/startup/preload.rs index 39597a7..348bbef 100644 --- a/src/startup/preload.rs +++ b/src/startup/preload.rs @@ -272,6 +272,17 @@ fn nat(interfaces: &Interfaces) -> String { extif = interfaces.external.interface ); + for nat_iface in &interfaces.nats { + for internal in &interfaces.internal { + nat += &format!( + "-A POSTROUTING -s {intip}/{intmask} -o {natiface} -j MASQUERADE\n", + intip = internal.ip, + intmask = internal.mask, + natiface = nat_iface, + ); + } + } + nat += "COMMIT\n"; nat