Post

Replies

Boosts

Views

Activity

`NEProxySettings.matchDomains` / `exceptionList` not working as expected in `NEPacketTunnelProvider` (domain-scoped proxy not applied, and exceptions not bypassed)
I’m working on an iOS Network Extension where a NEPacketTunnelProviderconfigures a local HTTP/HTTPS proxy usingNEPacketTunnelNetworkSettings.proxySettings. Per NEProxySettings.exceptionList docs: If the destination host name of an HTTP connection matches one of these patterns then the proxy settings will not be used for the connection. However, I’m seeing two distinct issues: Issue A (exception bypass not working): HTTPS traffic to a host that matches exceptionList still reaches the proxy. Issue B (domain-scoped proxy not applied): When matchDomains is set to match a specific domain (example: ["googlevideo.com"]), I still observe its traffic in some apps is not proxied. If I remove the domain from matchDomains, the same traffic is proxied. Environment OS: iOS (reproduced with 26.4 and other versions) Devices: Reproduced with several iPhones (likely iPads as well) Xcode: 26.3 Extension: NEPacketTunnelProvider Minimal Repro (code) This is the minimal configuration. Toggle between CONFIG A / CONFIG B to reproduce each issue. import NetworkExtension final class PacketTunnelProvider: NEPacketTunnelProvider { override func startTunnel( options: [String : NSObject]? = nil, completionHandler: @escaping (Error?) -> Void ) { let proxyPort = 12345 // proxy listening port let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "8.8.8.8") let proxySettings = NEProxySettings() proxySettings.httpEnabled = true proxySettings.httpsEnabled = true proxySettings.httpServer = NEProxyServer(address: "1.2.3.4", port: proxyPort) // proxy listening address proxySettings.httpsServer = NEProxyServer(address: "1.2.3.4", port: proxyPort) // proxy listening address // CONFIG A: proxy all domains, but exclude some domains // proxySettings.matchDomains can be set to match all domains // proxySettings.exceptionList = ["*.cdninstagram.com", "cdninstagram.com"] // CONFIG B: proxy only a specific domain // proxySettings.matchDomains = ["googlevideo.com"] settings.proxySettings = proxySettings setTunnelNetworkSettings(settings) { error in completionHandler(error) } } } Repro steps Issue A (exceptionList bypass not working) Enable the VPN configuration and start the tunnel with CONFIG A (exceptionList = ["*.cdninstagram.com", "cdninstagram.com"]). Open the Instagram app to trigger HTTPS connections to *.cdninstagram.com Inspect proxy logs: cdninstagram.com traffic is still received by the proxy. Safari comparison: If I access URLs that trigger the same *.cdninstagram.com hosts from Safari, it can behave as expected. When the traffic is triggered from the Instagram app, the excluded host still reaches the proxy as CONNECT, which is unexpected. Issue B (matchDomains not applied for YouTube traffic) Start the tunnel with CONFIG B (matchDomains = ["googlevideo.com"]). Open the YouTube app and start playing a video (traffic typically targets *.googlevideo.com). Inspect proxy logs: googlevideo.com traffic is not received by the proxy. Remove the host from matchDomains and observe that googlevideo.com traffic is received by the proxy. Safari comparison: If I access a googlevideo.com host from Safari while matchDomains = ["googlevideo.com"], it behaves as expected (proxied). In contrast, the YouTube app’s googlevideo.com traffic is not proxied unless I match all domains. Expected Issue A Connections to *.cdninstagram.com in the Instagram app should not use the proxy and should not reach the local proxy server. Issue B With matchDomains = ["googlevideo.com"], traffic to *.googlevideo.com (YouTube video traffic) should be proxied and therefore reach the local proxy. Actual Issue A The local proxy still receives the request as: CONNECT scontent-mad1-1.cdninstagram.com:443 HTTP/1.1 So the bypass does not happen. Issue B With matchDomains = ["googlevideo.com"], I still observe googlevideo.com traffic in the YouTube app that is not delivered to the proxy. When all traffic is proxied, the same traffic is delivered to the proxy.
1
1
197
Apr ’26
`NEProxySettings.matchDomains` / `exceptionList` not working as expected in `NEPacketTunnelProvider` (domain-scoped proxy not applied, and exceptions not bypassed)
I’m working on an iOS Network Extension where a NEPacketTunnelProviderconfigures a local HTTP/HTTPS proxy usingNEPacketTunnelNetworkSettings.proxySettings. Per NEProxySettings.exceptionList docs: If the destination host name of an HTTP connection matches one of these patterns then the proxy settings will not be used for the connection. However, I’m seeing two distinct issues: Issue A (exception bypass not working): HTTPS traffic to a host that matches exceptionList still reaches the proxy. Issue B (domain-scoped proxy not applied): When matchDomains is set to match a specific domain (example: ["googlevideo.com"]), I still observe its traffic in some apps is not proxied. If I remove the domain from matchDomains, the same traffic is proxied. Environment OS: iOS (reproduced with 26.4 and other versions) Devices: Reproduced with several iPhones (likely iPads as well) Xcode: 26.3 Extension: NEPacketTunnelProvider Minimal Repro (code) This is the minimal configuration. Toggle between CONFIG A / CONFIG B to reproduce each issue. import NetworkExtension final class PacketTunnelProvider: NEPacketTunnelProvider { override func startTunnel( options: [String : NSObject]? = nil, completionHandler: @escaping (Error?) -> Void ) { let proxyPort = 12345 // proxy listening port let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "8.8.8.8") let proxySettings = NEProxySettings() proxySettings.httpEnabled = true proxySettings.httpsEnabled = true proxySettings.httpServer = NEProxyServer(address: "1.2.3.4", port: proxyPort) // proxy listening address proxySettings.httpsServer = NEProxyServer(address: "1.2.3.4", port: proxyPort) // proxy listening address // CONFIG A: proxy all domains, but exclude some domains // proxySettings.matchDomains can be set to match all domains // proxySettings.exceptionList = ["*.cdninstagram.com", "cdninstagram.com"] // CONFIG B: proxy only a specific domain // proxySettings.matchDomains = ["googlevideo.com"] settings.proxySettings = proxySettings setTunnelNetworkSettings(settings) { error in completionHandler(error) } } } Repro steps Issue A (exceptionList bypass not working) Enable the VPN configuration and start the tunnel with CONFIG A (exceptionList = ["*.cdninstagram.com", "cdninstagram.com"]). Open the Instagram app to trigger HTTPS connections to *.cdninstagram.com Inspect proxy logs: cdninstagram.com traffic is still received by the proxy. Safari comparison: If I access URLs that trigger the same *.cdninstagram.com hosts from Safari, it can behave as expected. When the traffic is triggered from the Instagram app, the excluded host still reaches the proxy as CONNECT, which is unexpected. Issue B (matchDomains not applied for YouTube traffic) Start the tunnel with CONFIG B (matchDomains = ["googlevideo.com"]). Open the YouTube app and start playing a video (traffic typically targets *.googlevideo.com). Inspect proxy logs: googlevideo.com traffic is not received by the proxy. Remove the host from matchDomains and observe that googlevideo.com traffic is received by the proxy. Safari comparison: If I access a googlevideo.com host from Safari while matchDomains = ["googlevideo.com"], it behaves as expected (proxied). In contrast, the YouTube app’s googlevideo.com traffic is not proxied unless I match all domains. Expected Issue A Connections to *.cdninstagram.com in the Instagram app should not use the proxy and should not reach the local proxy server. Issue B With matchDomains = ["googlevideo.com"], traffic to *.googlevideo.com (YouTube video traffic) should be proxied and therefore reach the local proxy. Actual Issue A The local proxy still receives the request as: CONNECT scontent-mad1-1.cdninstagram.com:443 HTTP/1.1 So the bypass does not happen. Issue B With matchDomains = ["googlevideo.com"], I still observe googlevideo.com traffic in the YouTube app that is not delivered to the proxy. When all traffic is proxied, the same traffic is delivered to the proxy.
Replies
1
Boosts
1
Views
197
Activity
Apr ’26