rework: fix incorrect tunnel configuration causing confusion + switch to explicit CIDR format + remove swapping logic restricted to fakeIP - #23
Conversation
…ade tun iface ip /32
… to explicit CIDR format coz subnet mask allows invalids like 255.255.255.251 which are preventable using CIDR prefixes /32, /24 etc.
… and info.plist properly so one can reconfigure without touching pbxproj again for codesigning or info.plist updates.
…stering and doesn't cause any harm anyways
|
some background on things: NW basics:
Tunnel Basics: let ifaceIPv4 = NEIPv4Settings(addresses: [ifaceEndpoint.ip], subnetMasks: [ifaceEndpoint.subnetMask])
let tunnelDestinationIPv4Routes = [
// actual destination routes of this VPN tunnel
NEIPv4Route(destinationAddress: peerEndpoint.ip, subnetMask: peerEndpoint.subnetMask)
]
How it connects to SideStore:
|
|
discussed with team and seems /32 is fine ie point to point and we wanted to still keep to reserved private range 10.x.x.x. so choosing 23, ie: just for reference we used to have wireguard config in SideStore.conf as below which was /32 target anyways. |
…point2point) preserving backward compatibility.
|
thank you |
The tunnel was incorrectly configured where source and dest were same tunnel iface ip.
swapping was strictly restricted to fake IP addr only but we used fakeIP as 10.7.0.1/24, which when AND'd with subnet /24 gives 10.7.0.0/24 so when we restricted the swapping to just 10.7.0.1 it would never work basically. But wireguard & EMProxy used to work coz EMProxy didn't restrict itself to specific IPs and let tunnel config be authoritative. so we needed to remove the restriction too to make anything meaningful out of this tunnel for other local development real use cases and even for sidestore's auto-discovery or any kind of auto-discovery that checks routing table in kernel, to work.
our fake ip which when AND with subnet /24 will give 10.7.0.0/24 meaning kernel was storing the base address but then the deviceIP too was 10.7.0.0/24 causing severe confusion in client/app side as if kernel was reporting incorrect ips.
But it was the tunnel config ips we chose that were bad. so updated default tunnel configs as TunnelIP(ifaceIP) = 10.7.0.0/24 and DeviceIP(PeerIP) = 11.7.0.0/24
Implemented CIDR validator which performs validation of inputs and flags incorrect configuration properly.
Due to same, switched to full CIDR based IP addressing format coz subnet mask allows invalids like 255.255.255.251 which are preventable using CIDR prefixes /32, /24 etc that restricts to 2^x subnet masks only.
added some validations etc in UI so that it flags and restricts from accepting invalid CIDR IP configs.
added "allow intermediate addresses" flag which is opt-in to allow non canonical ips such as 10.7.0.1/24 or 11.3.0.2/30 which would usually resolve (when AND'd with mask) to 10.7.0.0/24 [range (2^32 - 2^24 = 2^8 ie 256 addrs) = subnet 10.7.0.0 <-> 10.7.0.255] and 11.3.0.0/24 [range (2^32 - 2^30 = 2^2 ie 4 addrs) = subnet 11.3.0.0 <-> 11.3.0.3]. ie we now show warning if user explicitly enabled non canonical ip subnets and if "allow intermediate addresses" was ON, otherwise if OFF, we just show as ERROR ie not allowed.
again most of the validations are for destination mostly coz multiple IPs assigned to iface isn't much of a problem coz kernel can decide which ip on the iface to stamp as source IP for outbound traffic, so the main concern is always destination Routes of the tunnel.
a p2p destination IP that has subnet /32 is best choice to connect to target ip directly, but we do allow subnet addrs.
Decoupled iface subnetMask from destinationRoute IP's subnetmask, coz hey we can have 1 iface IP and multiple destination routes with different subnets! and CIDR already helps with it anway now since we embed subnet mask into ip itself using CIDR prefix notation.
I think that is all that was covered by this fix.
for future readers, the following is simple config of a VPN routing (which is already in this PR)
// tunnel iface configuration let ifaceIPv4 = NEIPv4Settings(addresses: [ifaceEndpoint.ip], subnetMasks: [ifaceEndpoint.subnetMask]) let tunnelDestinationIPv4Routes = [ // actual destination routes of this VPN tunnel NEIPv4Route(destinationAddress: peerEndpoint.ip, subnetMask: peerEndpoint.subnetMask) ] ifaceIPv4.includedRoutes = tunnelDestinationIPv4Routes ifaceIPv4.excludedRoutes = [.default()] // Tunneling config let settings = NEPacketTunnelNetworkSettings( // NOTE: 'tunnelRemoteAddress' is just for UI concerns and is not involved in routing tunnelRemoteAddress: peerEndpoint.ip ) settings.ipv4Settings = ifaceIPv4 tunnelLog("Calling setTunnelNetworkSettings...") setTunnelNetworkSettings(settings) { error in if let error = error { tunnelLog("Failed to set settings: \(error.localizedDescription)") return completionHandler(error) } tunnelLog("Tunnel network settings set successfully. Starting packet loops.") self.setPackets() completionHandler(nil) }