I am working with @richard_wang on this.
@meaton
The most common cause of issues like this is both proxy's trying to handle the same flow and failing. For example, are you trying to handle UDP flows in both of your providers?
If I'm not mistaken an App Proxy can't handle DNS flows and only a DNS Proxy can, so I don't see how this could be the problem. We will confirm this.
I would try setting up your NEAppProxyProvider to only handle TCP flows and see if this makes a difference.
We have tried this and still no luck.
We will keep trying to solve this and if you have any clues please let us know. Thanks.
Post
Replies
Boosts
Views
Activity
@meaton I have done that. I eagerly await a response.
Thanks for your assistance but I am still having issues and will continue to investigate with SIP enabled as you suggested. In the meantime this is what I have.
ViewController.swift
import Cocoa
import os
import NetworkExtension
import SystemExtensions
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
os_log("DNSFILTER: viewDidLoad")
installSystemExtension()
configureProxy()
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
var manager: NEDNSProxyManager?
private func installSystemExtension() {
os_log("DNSFILTER: installing system extension")
let request = OSSystemExtensionRequest.activationRequest(
forExtensionWithIdentifier: "com.blob.macappproxy.dns",
queue: .main
)
request.delegate = self
OSSystemExtensionManager.shared.submitRequest(request)
}
private func configureProxy() {
os_log("DNSFILTER: configuring proxy")
guard let dnsManager = manager else { return }
dnsManager.loadFromPreferences { error in
precondition(Thread.isMainThread)
if let nsError = error as NSError? {
os_log("DNSFILTER: Failed to load the filter configuration: %@", nsError.localizedDescription)
return
}
let proto = NEDNSProxyProviderProtocol()
proto.serverAddress = "localhost" /* Just for testing purposes */
proto.providerBundleIdentifier = "com.blob.macappproxy.dns"
dnsManager.providerProtocol = proto
dnsManager.isEnabled = true
dnsManager.localizedDescription = "Testing DNS Proxy"
dnsManager.saveToPreferences { saveError in
if let nsError = saveError as NSError? {
os_log("DNSFILTER: Failed to disable the filter configuration: %@", nsError.localizedDescription)
return
}
/* Handle Success Case */
os_log("DNSFILTER: dns proxy configured")
}
}
}
}
extension ViewController: OSSystemExtensionRequestDelegate {
func request(_ request: OSSystemExtensionRequest, actionForReplacingExtension existing: OSSystemExtensionProperties, withExtension ext: OSSystemExtensionProperties) - OSSystemExtensionRequest.ReplacementAction {
os_log("DNSFILTER: Replacing extension %@ version %@ with version %@", request.identifier, existing.bundleShortVersion, ext.bundleShortVersion)
return .replace
}
func requestNeedsUserApproval(_ request: OSSystemExtensionRequest) {
os_log("DNSFILTER: Extension %@ requires user approval", request.identifier)
}
func request(_ request: OSSystemExtensionRequest, didFailWithError error: Error) {
os_log("DNSFILTER: System extension request failed: %@", error.localizedDescription)
}
/* Other delegate methods here */
func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result) {
switch result {
case .completed:
manager = NEDNSProxyManager.shared()
case .willCompleteAfterReboot:
os_log("DNSFILTER: willCompleteAfterReboot")
@unknown default:
os_log("DNSFILTER: default")
}
}
}
2021-03-18 17:09:27.676100+1100 macappproxy[1142:14431] DNSFILTER: viewDidLoad
2021-03-18 17:09:27.676187+1100 macappproxy[1142:14431] DNSFILTER: installing system extension
2021-03-18 17:09:27.678794+1100 macappproxy[1142:14431] DNSFILTER: configuring proxy
2021-03-18 17:09:27.922090+1100 macappproxy[1142:14431] DNSFILTER: System extension request failed: The operation couldn’t be completed. (OSSystemExtensionErrorDomain error 1.)
When configureProxy() is invoked it doesn't get past line 36 in ViewController.swift, which I guess is understandable if the extension hasn't started.
My DNSProxyProvider.swift is barebones:
import NetworkExtension
import os
class DNSProxyProvider: NEAppProxyProvider {
override func startProxy(options: [String : Any]?, completionHandler: @escaping (Error?) - Void) {
// Add code here to start the process of connecting the tunnel.
os_log("DNSFILTER: provider started")
completionHandler(nil)
}
override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () - Void) {
// Add code here to start the process of stopping the tunnel.
completionHandler()
}
override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) - Void)?) {
// Add code here to handle the message.
if let handler = completionHandler {
handler(messageData)
}
}
override func sleep(completionHandler: @escaping () - Void) {
// Add code here to get ready to sleep.
completionHandler()
}
override func wake() {
// Add code here to wake up.
}
override func handleNewFlow(_ flow: NEAppProxyFlow) - Bool {
// Add code here to handle the incoming flow.
return false
}
}
Let me know if anything looks awry. Thanks. I will continue to trawl through the console logs for any clues.
Thanks meaton. Unfortunately I have made little progress.
After I call OSSystemExtensionManager.shared.submitRequest(activationRequest) I get System extension request failed: Invalid code signature or missing entitlements from:
func request(_ request: OSSystemExtensionRequest, didFailWithError error: Error) {
os_log("System extension request failed: %@", error.localizedDescription)
status = .stopped
}
I am not sure why/if the code signature is invalid. I have looked through my Mac App's entitlements and can't see anything missing. FYI I have SIP disabled.
I have used this sample code as a reference for my project which is currently barebones as it is in a proof of concept stage:
https://developer.apple.com/documentation/networkextension/filtering_network_traffic
Here is where I am trying to submit the activation request:
@IBAction func startFilter(_ sender: Any) {
status = .indeterminate
guard !NEFilterManager.shared().isEnabled else {
registerWithProvider()
return
}
guard let extensionIdentifier = extensionBundle.bundleIdentifier else {
self.status = .stopped
return
}
// Start by activating the system extension
let activationRequest = OSSystemExtensionRequest.activationRequest(forExtensionWithIdentifier: extensionIdentifier, queue: .main)
// NSLog("bundleIdentifier: " + extensionIdentifier)
activationRequest.delegate = self
OSSystemExtensionManager.shared.submitRequest(activationRequest)
self.update {
self.manager.localizedDescription = "DNS Proxy"
let proto = NEDNSProxyProviderProtocol()
// proto.providerConfiguration = +++
let data: [String: Any] = [
"key1": "example value 1",
"key2": "example value 2",
"items": []
]
proto.providerConfiguration = data
proto.providerBundleIdentifier = extensionIdentifier
self.manager.providerProtocol = proto
self.manager.isEnabled = true
}
}
Any ideas?
I am getting the same errors as you jeffreyc.
Does anyone know what might be causing this or have sample code of a functional DNS Proxy using NEDNSProxyProvider?
Any help would be appreciated!