如何在 iOS VPN 中实现 VpnService 的保护?

How to achieve VpnService's protect in an iOS VPN?

我正在将 Android 设备的 VPN 应用移植到 iOS(使用 NEPacketTunnelProvider)。

Android 为某些 tcp/udp 连接提供绕过 VPN 的机制,使用以下 API:

class VpnService {

  // ...
  
  public boolean protect(int socket) { /* ... */ }

我在 iOS 中没有看到等效的 API。我如何实现 iOS 的等价物?

来自 Android 并且对 Apple API 一无所知(Swift 和 ObjC++ 语言除外),我将尝试指出普通开发人员想知道的内容。


一个 iOS 应用程序的生命在视图关闭的那一刻结束,因此永久 VPN 服务只能在扩展中使用,这与您的视图完全不同(因为 iOS没有服务概念)。

除了上述知识外,了解以下事实:从您的扩展中创建的任何连接(又名套接字)都被神奇地排除(又名保护)通过 packetFlow(又名隧道),无论它是否C/C++ 或 OOP-Wrapped class in Swift5.

制作的原始套接字

令人惊讶的是,实际上让您的扩展程序的套接字通过隧道要困难得多,
你需要使用 NEPacketTunnelProvider class 的方法:

- createTCPConnectionThroughTunnelToEndpoint:enableTLS:TLSParameters:delegate:

- createUDPSessionThroughTunnelToEndpoint:fromEndpoint:

Note that above are instance methods, which is what minus sign in ObjC means,
so only available in extension context (but there is no escaping from the tunnel for App-targets anyway).

See also: https://developer.apple.com/forums/thread/94430