I work for a company that is replacing their current endpoint security product that uses an NKE implementation for something that will work in future macOS versions. We need to capture various metadata about connections (ip/port, etc.) and also to possibly divert web traffic to a remediation/capture page for dangerous or unwanted (in the IT sense) browser traffic.Since the content filter APIs won't divert traffic (from what I've read), I have started looking into the Transparent Proxy APIs. I have taken the SimpleFirewall example and replaced the content filtering calls with transparent proxy calls. At this point, my goal is to prove I can get notified of new flows, get metadata about those flows, and eventually see data from those flows.This is how I am creating the AppProxyProvider:override func startProxy(options: [String : Any]? = nil, completionHandler: @escaping (Error?) -> Void) {
let includeRule = NENetworkRule(destinationHost: NWHostEndpoint(hostname: "sophostest.com", port: "80"), protocol: .TCP)
let proxySettings = NETransparentProxyNetworkSettings(tunnelRemoteAddress: "127.0.0.1")
proxySettings.includedNetworkRules = [includeRule]
setTunnelNetworkSettings(proxySettings) { error in
if let applyError = error {
os_log("Failed to apply proxy settings: %{public}@", log:.networkExtension, applyError.localizedDescription)
}
completionHandler(error)
}
}To make things simple, I am just looking at one sites traffic on one port, as to not overwhelm the logging/developer. 🙂 My main area of concern with this code is the creation of the NETransparentProxyNetworkSettings object. If I don't supply a tunnelRemoteAddress or if I try to supply a port, it doesn't "connect" and I get this error in the consoleFailed to apply proxy settings: Missing NETunnelNetworkSettings tunnelRemoteAddressAt this point, I am not trying to proxy the data at all. I am assuming that the app would be able to view the traffic before deciding if it was going to proxy it.For some reason I have to go into the network control panel to enable the connection (like a VPN). I'm not sure why this needs to happen, and it is something I will need to automate eventually. I can't rely on the user to do this.My handleNewFlow looks like this override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
if let tcpflow = flow as? NEAppProxyTCPFlow
{
os_log("tcpflow handled - %{public}@",log:.networkExtension, tcpflow.metaData.debugDescription)
}
else if let udpflow = flow as? NEAppProxyUDPFlow
{
os_log("udpflow handled - %{public}@", log:.networkExtension, udpflow.metaData.debugDescription)
}
else
{
os_log("flow handled - %{public}@",log:.networkExtension, flow.metaData.debugDescription)
}
return false
}As you can see if this method is called, something should be sent to os_log. When I browse to sophostest.com with the transparent proxy started and connected (via the network control panel), I get an "operation not permitted" page in safari (understandable) and no os_log messages at all.
Post
Replies
Boosts
Views
Activity
I've been working with the Transparent Proxy portion of the Network Extensions / System Extensions in Catalina. When I try to proxy port 80, and go to a http site, Safari gives me an error "The operation could not be completed. Operation not permitted (NSPOSIXErrorDomain:1)". Other browsers (Firefox, Brave) seem to work fine. Data flows to and from both browsers and I see the metadata about those connections. Safari on the other hand, stops the communications altogether. When I turn the Proxy off, Safari works as usual. As you might imagine, https works fine, but I am not running a transparent proxy for port 443, just 80.ThanksChris Parker
I am looking at the Transparent Proxy NE APIs to replace a kext in our current endpoint security offering. Right now, we can "get out of the way" pretty early in the process. We don't really want/need to handle traffic from non-browsers. It appears that the only way to filter network traffic for this API is by NENetworkRules which don't allow you to filter by app or pid.There also doesn't seem a way to tell the API you don't want to handle the flow after you have been notified of it. There is the return value for handleNewFlow() that tells the API that your app isn't going to handle the flow, but the APIs response is to terminate the flow.Is there another way of "getting out of the way"? Is there a better API I should be looking at for this?Thanks
I want to make sure I understand the implications of some of the answers in the Network Entitlement FAQ post -> https://forums.developer.apple.com/thread/67613My current commercial enterprise-focused app uses the NKE APIs to protect the user from network threats. It is installed, updated and controlled by a management system built for the administration of the product. If we use the newly provided APIs from the Network Extensions, then it must be distributed by the Mac App Store? If we use these APIs we no longer control the installation/update of (at least) that portion of the product?Is this correct?
I have been tasked to "try out" the instructions in the Jan 14 response from this post, and figure out how to integrate it into our development process. I thought I had done it correctly, but when I build I get this error :error: No certificate for team 'TeamName (Company)' matching 'Developer ID Application: TeamName' found:
Select a different signing certificate for CODE_SIGN_IDENTITY, a team that matches your selected certificate,
or switch to automatic provisioning. (in target 'AppName-macOS' from project 'AppName')The only explanation I have for this error is that when I created the provisioning profile, I chose may have chose the production certificate, which I do not have on my machine. I couldn't tell which certificate was which, they were all named similarly, so I chose the one whose date was furtherest out.Follow up question, is there any documentation on how to carry out this task via command line (codesign) tool? Production signing happens on a different machine on a different network, so we have a development certificate for everyday tasks and signing. This signing happens via command line.Thanks!
It seems that there are limitations in IPC between network system extensions and other apps in our product. The network extension is signed to use Developer ID.The network extension is NOT sandboxed. Nor are any other components.None of the components use App Groups. I tried the network extension with and without an app group with no luck.I have specified an NEMachServiceName and left it blank as well. Neither worked.At this point, it seems that it is being flat out denied by then system, but I don't can't find any documentation that suggests this is how it should be. The closest thing I have seen is that App Groups allow for sandboxed apps to talk (though XPC wasn't explicitly listed) and sandboxed to unsandboxed apps to talk. I do not want to put any of our apps in the sandbox, nor do I want to put all of our apps into an App Group either.Thanks!