I initiate a network request through URLSesssion in PacketTunnelProvider, but PacketTunnelProvider cannot intercept it. I see on the Internet that PacketTunnelProvider does not intercept its own request by default. How should I modify the configuration?
About PacketTunnelProvider unable to intercept its own request
This is my PacketTunnelNetworkSetting configurationg
networkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "127.0.0.1")
guard let networkSettings = networkSettings else {
return
}
networkSettings.mtu = 1500
let proxySettings = NEProxySettings()
proxySettings.httpServer = NEProxyServer(address: "127.0.0.1", port: 8888)
proxySettings.httpEnabled = true
proxySettings.httpsServer = NEProxyServer(address: "127.0.0.1", port: 8888)
proxySettings.httpsEnabled = true
proxySettings.matchDomains = [""]
proxySettings.autoProxyConfigurationEnabled = false
networkSettings.proxySettings = proxySettings
let ipv4Settings = NEIPv4Settings(addresses: ["192.169.89.1"], subnetMasks: ["255.255.255.0"])
ipv4Settings.excludedRoutes = []
ipv4Settings.includedRoutes = [
NEIPv4Route.default(),
NEIPv4Route(destinationAddress: "127.0.0.1", subnetMask: "255.255.255.255")
]
Apple platforms have a sophisticated subsystem for managing network interface access control [1]. We use this for many purposes but in this case we use it to prevent VPN loops. By default an outgoing network connection from a VPN provider will not go through the VPN interface.
For a vanilla TCP connection you can override this by creating the connection using the createTCPConnection(to:enableTLS:tlsParameters:delegate:)
method. However, this only gives you a TCP connection. URLSession
does not support this sort of thing, so if you need HTTP then you’ll have to build your own HTTP stack on top of your TCP connection.
Most folks don’t hit this problem because their packet tunnel provider actually implements a packet-based VPN. You wrote:
proxySettings.httpServer = NEProxyServer(address: "127.0.0.1", port: 8888)
…
proxySettings.httpsServer = NEProxyServer(address: "127.0.0.1", port: 8888)
This suggests that you’re trying to use a packet tunnel provider to implement some sort of proxy service. This generally doesn’t end well. For more on that topic, see TN3120 Expected use cases for Network Extension packet tunnel providers.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] In the system log you’ll see this referred to as NECP, or Network Extension Control Protocol.
How does a VPN provider determine whether the network is self-initiated or an external request? Whether the request initiated by the VPN provider through CFNetwork will go through the VPN interface.
How does a VPN provider determine whether the network is self-initiated or an external request?
I don’t understand this.
Whether the request initiated by the VPN provider through CFNetwork will go through the VPN interface.
NSURLSession
does not apply any specific parameters to the connections it makes [1], so NECP uses the default policy for the originating process. In the case of the process running your NE tunnel provider, the default policy explicitly excludes the connection from running over the tunnel interface associated with the provider. Thus, a connection to the wider Internet goes via the default hardware interface, not via the tunnel interface, even if the tunnel interface has become the default route.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] By default. You can actually apply constraints, using properties like allowsExpensiveNetworkAccess
, but none of those are directly relevant to this issue.
Whether the request initiated by the VPN provider through CFNetwork will go through the VPN interface.
I ask this question because when I use the software Surge to configure the script timer and the CFNetwork request information contained in the intercepted request UA header information. The specific information is as follows: User-Agent: Surge-Extension/2235 CFNetwork/1333.0.4Darwin/21.5.0
So I think the request through URLSession will be ignored by PacketTunnelProvider, but the request through CFNetwork can be intercepted
proxySettings.httpServer = NEProxyServer(address: "127.0.0.1", port: 8888) proxySettings.httpEnabled = true proxySettings.httpsServer = NEProxyServer(address: "127.0.0.1", port: 8888) proxySettings.httpsEnabled = true
Can I understand that the above setup will not intercept locally initiated HTTP requests, but will intercept TCP requests
For those following along at home, note that I’ll be helping CheYongzi in a different context.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"