Packets not being sent out after writing to utun interface

I am developing an application on macOS using NEPacketTunnelProvider.

Both our client and "VPN Server" are their own separate macOS application that uses NEPacketTunnelProvider.

On the server side, I have this as my configuration

Code Block
let tunnelSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "127.0.0.1")
let ipv4Settings = NEIPv4Settings(addresses: ["100.64.0.77"], subnetMasks: ["255.255.255.0"])
let includedRoute = NEIPv4Route(destinationAddress: "192.168.1.0", subnetMask: "255.255.255.0")
ipv4Settings.includedRoutes = [includedRoute]
tunnelSettings.ipv4Settings = ipv4Settings
//call setTunnelSettings to apply settings

The client is able to create and start the tunnel through System Preferences->Network successfully.

When the client receives packets through the virtual utun[x] interface, it forwards them to the the VPN Server.

When the VPN Server receives these packets (ex: SYN), it rewrites the source and destination IP addresses and injects them into its own utun[x] interface on the server's machine. In this case, it rewrites the source destination to 100.64.0.77 and the destination address to 192.168.1.95 (a web server).

Essentially what I want to happen is for the client to be able to communicate with a web server through the VPN server. What I expected was for the web server to receive this packet and respond appropriately with a SYN/ACK, which could then be used to read from the utun[x] interface and send back to the client. However, the web server does not receive any packets. Why is this the case and how can I get these packets to arrive at their destination?

Below I have attached my routing table on the server's side using netstat -nr:


Code Block
Routing tables
Internet:
Destination Gateway Flags Netif Expire
default 192.168.1.254 UGSc en0
default link#10 UCSI utun2
100.64.0.77 100.64.0.77 UH utun2
127 127.0.0.1 UCS lo0
127.0.0.1 127.0.0.1 UH lo0
169.254 link#7 UCS en0 !
192.168.1 link#7 UCS en0 !
192.168.1 link#10 UCSI utun2
192.168.1.92/32 link#7 UCS en0 !
192.168.1.99 8c:a9:82:2e:d6:2e UHLWI en0 986
192.168.1.254/32 link#7 UCS en0 !
192.168.1.254 70:f1:96:86:e6:a0 UHLWIir en0 1196
224.0.0/4 link#7 UmCS en0 !
224.0.0/4 link#10 UmCSI utun2
224.0.0.251 1:0:5e:0:0:fb UHmLWI en0
255.255.255.255/32 link#7 UCS en0 !
255.255.255.255/32 link#10 UCSI utun2

Let me make sure I understand here; you are wanting to setup a point to point VPN and then have your VPN traffic from your client access a web server sitting behind the VPN server? If that is the case, the 10,000 foot answer here is that I suspect you have a routing issue in getting your packets from the utun interface on the server to route to the routing table that your web server has accessible to it. Basically utun2 -> to one of your other Netif's on the system that your webserver has accessible to it.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Let me make sure I understand here; you are wanting to setup a point to point VPN and then have your VPN traffic from your client access a web server sitting behind the VPN server?

That is correct

If that is the case, the 10,000 foot answer here is that I suspect you have a routing issue in getting your packets from the utun interface on the server to route to the routing table that your web server has accessible to it

This seems like a likely case in my opinion too. What do I need to add / edit in the routing table to get these packets to arrive at their destination (ie: the webserver)?

If I open a browser and visit the webserver on the machine that the VPN Server is running, I see that traffic is generated on the en0 interface and that the webpage is being served if that is of any help

Update, I now have traffic (the SYN/ACK) being generated on the en0 interface on the VPN Server. The webserer can see the SYN packet and responds with a SYN/ACK accordingly.
I was able to do this by having IP forwarding enabled using this command: sudo sysctl -w net.inet.ip.forwarding=1

Since the SYN/ACK is going to the en0 interface, my application is not able to grab it. How can I get the packet to go to the utun[x] interface that I created so that I can read from the interface and send the packet to the client?
Packets not being sent out after writing to utun interface
 
 
Q