VPN Proxy bypassed after TCP connection is closed

Hey guys, I have a question regarding iOS 15 beta and proxy bypass.

We've noticed that if the proxy is automatically set via a VPN and the TCP connection is closed, the system bypasses the proxy and connects to the server directly. However, that's not the case if the proxy is set manually in settings or a GHP profile is used.

We haven't observed such behavior in previous versions so I wanted to ask: is this expected behavior in iOS 15? If so, is there any way how to disable the bypass?

Configuration:

  • VPN:

    • URL with PAC file added via proxyAutoConfigurationURL
    • device is proxying, however, the proxy is bypassed on TCP connection close
  • GHP:

    • tested both manual or auto configurations (in case of auto configuration we've used the same PAC file)
    • device is proxying and the proxy is never bypassed
    • VPN wasn't installed in this case
  • Settings:

    • proxy server and port are defined in WiFi settings
    • again, the same proxy server has been used as in previous test cases
    • proxy is never bypassed
    • VPN wasn't installed in this case

We've noticed that if the proxy is automatically set via a VPN and the TCP connection is closed, the system bypasses the proxy and connects to the server directly.

I generally do not recommend doing this in the context of a NEPacketTunnelProvider at all, but I did see some issues in iOS 14 with the proxy being recognized in this context. If this did previously work for you and now it does not then that is the definition of something that should be recorded as a bug report.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hi Matt,

I've observed similar issues when using a Global HTTP Proxy profile on a supervised iOS device. We rely on iOS's proxy capability to block adult material on managed devices so that we don't have to force users to use a 3rd party browser app and disable Safari.

The above note from Rachel illustrates that developers/vendors have rolled their own strategies for blocking content from loading via a proxy server. Now it seems a change in Safari in iOS 15 has broken or otherwise compromised at least some of those strategies.

Rather than trying to reverse-engineer the iOS network stack and WebKit, could you shine some light on how Apple engineering expects proxy servers to block traffic? AFAIK there isn't a well adopted RFC defining this behavior, however the server-side strategy of opening the TCP socket, accepting the initial HTTP request (e.g. GET/CONNECT), then sending a RST in response (if the content is to be blocked) seems to be a well adopted and accepted method across many enterprise proxies and firewalls.

Of course in iOS 15 the new behavior in Safari is to detect that the TLS handshake was interrupted pre-maturely for HTTPS connections, and force a direct connection attempt around the proxy server. This obviously renders the content filter worthless...

Anything you can share I'm sure would be vey helpful to me and the broader Apple enterprise ecosystem.

traffic? AFAIK there isn't a well adopted RFC defining this behavior,

If you are running in a managed environment and are expected to perform allow / deny actions on URLs being opened from Safari, I would use one of the Content Filter Providers APIs such as NEFilterDataProvider or NEFilterControlProvider.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
VPN Proxy bypassed after TCP connection is closed
 
 
Q