Hi, for me issue is resolved if I include only IPv4 traffic in transparent proxy. If I add IPv6 rule, issue is still present. For example:
let remoteIPv6Network = NWHostEndpoint(hostname: "2001:4860:4860::8888", port: "0")
let networkIPv6Rule = NENetworkRule(remoteNetwork: remoteIPv6Network,
remotePrefix: 0,
localNetwork: nil,
localPrefix: 0,
protocol: .any,
direction: .outbound)
Is there a way to fix this?
Post
Replies
Boosts
Views
Activity
Hi, I am experiencing issue with NETransparentProxyProvider. I use transparent proxy to bind some sockets to physical interface when VPN is active. It works fine for all apps, except Safari. With Safari I get errors when reading from the connection in inbound copier. I use following code snippet:
let reader: TCPFlowCopierControl.Reader = { completionHandler in
self.connection.receive(minimumIncompleteLength: 1, maximumLength: 2048) { (dataQ, _, isComplete, errorQ) in
switch (dataQ, isComplete, errorQ) {
case (_, true, _): completionHandler(.success(Data()))
case (let data?, _, _): completionHandler(.success(data))
case (_, _, let error?):
NSLog("TCP attempt 1: \(self.connection.currentPath?.localEndpoint) \(self.connection.endpoint)")
completionHandler(.failure(error))
default: assert(false) // No data, no EOF, and no error. Wha?
}
}
}
let writer: TCPFlowCopierControl.Writer = { data, completionHandler in
self.flow.write(for: self, data: data) { errorQ in
self.queue.async {
switch errorQ {
case nil: completionHandler(.success(()))
case let error?:
NSLog("TCP attempt 2: \(self.connection.currentPath?.localEndpoint)")
completionHandler(.failure(error))
}
}
}
}
return TCPFlowCopierControl(reader: reader, writer: writer, done: self.copierDone(errorQ:))
}
In "TCP attempt 1" log I can see that self.connection.currentPath?.localEndpoint is nil, even though it wasn't at the time .ready state was hit. Safari itself shows "No connection" messages. This issue happens only in safari, chrome and firefox work fine. I'm also not experiencing the issue if I use NEAppProxyProvider instead of NETransparentProxyProvider, but I need to use NETransparentProxyProvider because it doesn't drop excluded sockets. Do you have any idea why this would happen?
Yes, in handleInboundDataFromFlow and handleOutboundDataFromFlow I can see actual address. Thank you
Thanks for the suggestion.
I managed to retrieve all interfaces on the machine with their addresses using getifaddrs, but localEndpoint of a NEFilterSocketFlow usually has 0.0.0.0 hostname so I can not match it with any interface. Is there a way to get actual IP address of a localEndpoint?
Hello,is it possible to use third-party libraries in system extension? If I import any library using cocoapods, my system extension doesn't want to start, even if I don't reference the library in code at all.
I sent you an email with following subject:Apple Developer Forum - Get socket's file descriptor in NEFilterDataProvider callbacks
Thank you for the help.I implemented transparent proxy but I'm experiencing some issues.I'm getting new flows in handleNewFlow(_ flow: NEAppProxyFlow) callback, but I completely loose network connection every time I enable the proxy. Here is my NEAppProxyProvider implementation:override func startProxy(options: [String : Any]? = nil, completionHandler: @escaping (Error?) -> Void) { var includedRules = [NENetworkRule]() os_log("I have proxy start") let remoteNetwork = NWHostEndpoint(hostname: "8.8.8.8", port: "0") let networkRule = NENetworkRule(remoteNetwork: remoteNetwork, remotePrefix: 0, localNetwork: nil, localPrefix: 0, protocol: .any, direction: .outbound) includedRules.append(networkRule) let settings = NETransparentProxyNetworkSettings(tunnelRemoteAddress: "127.0.0.1") settings.includedNetworkRules = includedRules setTunnelNetworkSettings(settings) { error in if error != nil { os_log("I have proxy start error") } else { os_log("I have proxy start success") } completionHandler(error) } } override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool { os_log("I have proxy flow") flow.open(withLocalEndpoint: nil) { error in if error != nil { os_log("I have proxy open error") } else { //flow.networkInterface = nw_interface_create_with_name("en0") os_log("I have proxy open success") } flow.closeReadWithError(error) flow.closeWriteWithError(error) } return true }Do you maybe have some transparent proxy code samples so I could see what I'm doing wrong?