用于网络嗅探的VPN连接建立失败,请求技术协助
VPN连接异常排查方案
问题描述
尝试建立VPN连接用于监控网络活动,当前可获取请求URL但无法正常联网。VPN启动后显示已连接,但一段时间后会自动断开。
连接建立代码
private func connect(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) { let settings: NEPacketTunnelNetworkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: proxyServerAddress) /* proxy settings */ let proxySettings: NEProxySettings = NEProxySettings() proxySettings.httpServer = NEProxyServer( address: proxyServerAddress, port: Int(proxyServerPort) ) proxySettings.httpsServer = NEProxyServer( address: proxyServerAddress, port: Int(proxyServerPort) ) proxySettings.autoProxyConfigurationEnabled = false proxySettings.httpEnabled = true proxySettings.httpsEnabled = true proxySettings.excludeSimpleHostnames = true proxySettings.exceptionList = [ "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12", "127.0.0.1", "localhost", "*.local" ] settings.proxySettings = proxySettings /* ipv4 settings */ let ipv4Settings: NEIPv4Settings = NEIPv4Settings( addresses: [settings.tunnelRemoteAddress], subnetMasks: ["255.255.255.255"] ) ipv4Settings.includedRoutes = [NEIPv4Route.default()] ipv4Settings.excludedRoutes = [ NEIPv4Route(destinationAddress: "192.168.0.0", subnetMask: "255.255.0.0"), NEIPv4Route(destinationAddress: "10.0.0.0", subnetMask: "255.0.0.0"), NEIPv4Route(destinationAddress: "172.16.0.0", subnetMask: "255.240.0.0") ] settings.ipv4Settings = ipv4Settings let dnsSettings = NEDNSSettings(servers: ["8.8.8.8", "1.1.1.1"]) settings.dnsSettings = dnsSettings /* MTU */ settings.mtu = 1500 RawSocketFactory.TunnelProvider = self self.setTunnelNetworkSettings(settings, completionHandler: { error in guard error == nil else { completionHandler(error) return } let newProxyServer = GCDHTTPProxyServer(address: IPAddress(fromString: self.proxyServerAddress), port: Port(port: self.proxyServerPort)) self.proxyServer = newProxyServer do { completionHandler(nil) } catch let proxyError { completionHandler(proxyError) } }) completionHandler(nil) }
连接过程日志
2023-10-16T16:00:28+0530 info com.apple.nio-connect-proxy.ConnectHandler : channel=ObjectIdentifier(0x0000000103e0c570) localAddress=Optional([IPv4]127.0.0.1/127.0.0.1:8080) remoteAddress=Optional([IPv4]127.0.0.1/127.0.0.1:52889) [VPN] CONNECT gateway.icloud.com:443 HTTP/1.1 2023-10-16T16:00:28+0530 info com.apple.nio-connect-proxy.ConnectHandler : channel=ObjectIdentifier(0x0000000103e0c570) localAddress=Optional([IPv4]127.0.0.1/127.0.0.1:8080) remoteAddress=Optional([IPv4]127.0.0.1/127.0.0.1:52889) [VPN] Connecting to gateway.icloud.com:443 2023-10-16T16:00:30+0530 info com.apple.nio-connect-proxy.ConnectHandler : channel=ObjectIdentifier(0x0000000101a0bea0) localAddress=Optional([IPv4]127.0.0.1/127.0.0.1:8080) remoteAddress=Optional([IPv4]127.0.0.1/127.0.0.1:52890) [VPN] CONNECT cl3.apple.com:443 HTTP/1.1 2023-10-16T16:00:30+0530 info com.apple.nio-connect-proxy.ConnectHandler : channel=ObjectIdentifier(0x0000000101a0bea0) localAddress=Optional([IPv4]127.0.0.1/127.0.0.1:8080) remoteAddress=Optional([IPv4]127.0.0.1/127.0.0.1:52890) [VPN] Connecting to cl3.apple.com:443
连接失败日志
2023-10-16T16:02:21+0530 error com.apple.nio-connect-proxy.ConnectHandler : channel=ObjectIdentifier(0x000000010610d1e0) localAddress=Optional([IPv4]127.0.0.1/127.0.0.1:8080) remoteAddress=Optional([IPv4]127.0.0.1/127.0.0.1:52898) [VPN] Connect failed: connectTimeout(NIOCore.TimeAmount(nanoseconds: 10000000000)) 2023-10-16T16:02:28+0530 error com.apple.nio-connect-proxy.ConnectHandler : channel=ObjectIdentifier(0x000000010610a6f0) localAddress=Optional([IPv4]127.0.0.1/127.0.0.1:8080) remoteAddress=Optional([IPv4]127.0.0.1/127.0.0.1:52899) [VPN] Connect failed: connectTimeout(NIOCore.TimeAmount(nanoseconds: 10000000000))
核心问题与修复方案
- 代理服务未启动:代码中仅创建了
GCDHTTPProxyServer实例,但未调用start()方法启动服务,导致代理端口无进程监听,请求超时。需在do块内添加try newProxyServer.start()。 - 完成回调调用时机错误:在
setTunnelNetworkSettings的异步回调外提前调用completionHandler(nil),会让系统误以为VPN已就绪,但实际代理服务未初始化,引发后续连接异常。需删除外部的completionHandler(nil)调用。
修复后代码片段
self.setTunnelNetworkSettings(settings, completionHandler: { error in guard error == nil else { completionHandler(error) return } let newProxyServer = GCDHTTPProxyServer(address: IPAddress(fromString: self.proxyServerAddress), port: Port(port: self.proxyServerPort)) self.proxyServer = newProxyServer do { try newProxyServer.start() // 新增启动逻辑 completionHandler(nil) } catch let proxyError { completionHandler(proxyError) } }) // 删除此处的completionHandler(nil)
- 额外检查项:确认
proxyServerAddress配置为127.0.0.1(与日志中本地监听地址一致),避免路由规则导致流量无法正确转发到本地代理。
内容的提问来源于stack exchange,提问作者Saurabh Pathak
相关产品推荐
相关产品推荐

