From 97d0676301f4b447bf57cbb12a8e9316731e9588 Mon Sep 17 00:00:00 2001 From: Himbeer Date: Wed, 4 Sep 2024 11:25:18 +0200 Subject: Enable NPT for internal VPN-to-GUA traffic Previously it was impossible to access local services using their GUAs through the VPNs. This commit enables NPT for any outbound packets with a destination address in the 2000::/3 (GUA) range as well as for any inbound packets to VPN prefixes. --- src/main.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 5d660f9..22c6f81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ use rustables::{ }; use signal_hook::{consts::SIGUSR1, iterator::Signals}; +const GUA: Ipv6Addr = Ipv6Addr::new(0x2000, 0, 0, 0, 0, 0, 0, 0); const ULA: Ipv6Addr = Ipv6Addr::new(0xfd0b, 0x9272, 0x534e, 0, 0, 0, 0, 0); const VPN_ULA: Ipv6Addr = Ipv6Addr::new(0xfd0b, 0x9272, 0x534e, 6, 0, 0, 0, 0); const EXPOSED_VPN_ULA: Ipv6Addr = Ipv6Addr::new(0xfd0b, 0x9272, 0x534e, 7, 0, 0, 0, 0); @@ -414,6 +415,7 @@ fn filter() -> Result<()> { } fn enable_npt(prefix: Ipv6Addr) -> Result { + let gua_net = IpNetwork::V6(Ipv6Network::new(GUA, 3).unwrap()); let vpn_net = IpNetwork::V6(Ipv6Network::new(VPN_ULA, 64).unwrap()); let exposed_vpn_net: IpNetwork = IpNetwork::V6(Ipv6Network::new(EXPOSED_VPN_ULA, 64).unwrap()); @@ -450,8 +452,8 @@ fn enable_npt(prefix: Ipv6Addr) -> Result { batch.add(&postrouting, MsgType::Add); let map_vpn_to_gua = Rule::new(&postrouting)? - .oface("ppp0")? .snetwork(vpn_net)? + .dnetwork(gua_net)? .with_expr( HighLevelPayload::Network(NetworkHeaderField::IPv6(IPv6HeaderField::Saddr)).build(), ) @@ -466,8 +468,8 @@ fn enable_npt(prefix: Ipv6Addr) -> Result { batch.add(&map_vpn_to_gua, MsgType::Add); let map_exposed_vpn_to_gua = Rule::new(&postrouting)? - .oface("ppp0")? .snetwork(exposed_vpn_net)? + .dnetwork(gua_net)? .with_expr( HighLevelPayload::Network(NetworkHeaderField::IPv6(IPv6HeaderField::Saddr)).build(), ) @@ -497,7 +499,6 @@ fn enable_npt(prefix: Ipv6Addr) -> Result { batch.add(&prerouting, MsgType::Add); let map_gua_to_vpn = Rule::new(&prerouting)? - .iface("ppp0")? .dnetwork(vpn_subnet)? .with_expr( HighLevelPayload::Network(NetworkHeaderField::IPv6(IPv6HeaderField::Daddr)).build(), @@ -513,7 +514,6 @@ fn enable_npt(prefix: Ipv6Addr) -> Result { batch.add(&map_gua_to_vpn, MsgType::Add); let map_gua_to_exposed_vpn = Rule::new(&prerouting)? - .iface("ppp0")? .dnetwork(exposed_vpn_subnet)? .with_expr( HighLevelPayload::Network(NetworkHeaderField::IPv6(IPv6HeaderField::Daddr)).build(), @@ -540,6 +540,7 @@ fn enable_npt(prefix: Ipv6Addr) -> Result { } fn update_npt(npt: &mut Npt, prefix: Ipv6Addr) -> Result<()> { + let gua_net = IpNetwork::V6(Ipv6Network::new(GUA, 3).unwrap()); let vpn_net = IpNetwork::V6(Ipv6Network::new(VPN_ULA, 64).unwrap()); let exposed_vpn_net: IpNetwork = IpNetwork::V6(Ipv6Network::new(EXPOSED_VPN_ULA, 64).unwrap()); @@ -570,8 +571,8 @@ fn update_npt(npt: &mut Npt, prefix: Ipv6Addr) -> Result<()> { // +-------------------+ npt.map_vpn_to_gua = Rule::new(&npt.postrouting)? - .oface("ppp0")? .snetwork(vpn_net)? + .dnetwork(gua_net)? .with_expr( HighLevelPayload::Network(NetworkHeaderField::IPv6(IPv6HeaderField::Saddr)).build(), ) @@ -586,8 +587,8 @@ fn update_npt(npt: &mut Npt, prefix: Ipv6Addr) -> Result<()> { batch.add(&npt.map_vpn_to_gua, MsgType::Add); npt.map_exposed_vpn_to_gua = Rule::new(&npt.postrouting)? - .oface("ppp0")? .snetwork(exposed_vpn_net)? + .dnetwork(gua_net)? .with_expr( HighLevelPayload::Network(NetworkHeaderField::IPv6(IPv6HeaderField::Saddr)).build(), ) @@ -609,7 +610,6 @@ fn update_npt(npt: &mut Npt, prefix: Ipv6Addr) -> Result<()> { // +------------------+ npt.map_gua_to_vpn = Rule::new(&npt.prerouting)? - .iface("ppp0")? .dnetwork(vpn_subnet)? .with_expr( HighLevelPayload::Network(NetworkHeaderField::IPv6(IPv6HeaderField::Daddr)).build(), @@ -625,7 +625,6 @@ fn update_npt(npt: &mut Npt, prefix: Ipv6Addr) -> Result<()> { batch.add(&npt.map_gua_to_vpn, MsgType::Add); npt.map_gua_to_exposed_vpn = Rule::new(&npt.prerouting)? - .iface("ppp0")? .dnetwork(exposed_vpn_subnet)? .with_expr( HighLevelPayload::Network(NetworkHeaderField::IPv6(IPv6HeaderField::Daddr)).build(), -- cgit v1.2.3