Hi everyone! I'm trying to get acquainted with NETrasparentProxy abilities. What I want to achieve is to log which process initiated outbound flow. So, I have configured provisioning profiles to build and run the test app on my machine. The system extension installs and activates successfully, also I can see the network profile in Network Settings. However, I don't see a log inside override of startProxy(). I have added additional logs in main.swift of the NE and inside init() of AppProxyProvider class that inherits NETransparentProxy. Surprisingly, I do not see any logs from there. Can anyone suggest what is a possible root of the problem.
Here is the source code
class TransparentProxyService {
private let logger = Logger()
public func start() {
logger.debug("loading proxy managers from preferences")
NETransparentProxyManager.loadAllFromPreferences { transparentProxyManagers, error in
// precondition(Thread.isMainThread, "TransparentProxyService::start called not from main thread")
if let error = error {
self.logger.error("Unable to load transparent proxy managers from prefernces. Error: \(error.localizedDescription)")
return
}
self.logger.debug("successfully loaded managers")
let proxyManagers = transparentProxyManagers ?? []
let firstProxyManager = proxyManagers.first(where: { manager in
guard let protocolConfiguration = manager.protocolConfiguration, let tunnelConfiguration = protocolConfiguration as? NETunnelProviderProtocol else {
self.logger.debug("Unable to cast protocol configuration to NETunnelProviderProtocol")
return false
}
return tunnelConfiguration.providerBundleIdentifier == "network extension bundle id"
})
self.logger.debug("Passed the first proxy manager search")
let mainProxyManager = firstProxyManager ?? NETransparentProxyManager()
self.logger.debug("Initialize config")
self.configureWorkplaceProtocol(for: mainProxyManager)
self.logger.debug("Config initialized. Saving to preferences")
mainProxyManager.saveToPreferences { error in
if let error = error {
self.logger.error("TransparentProxy::start. Unable to save transparent proxy manager to preferences. Error: \(error.localizedDescription)")
return
}
self.logger.debug("loading from preferences anew")
mainProxyManager.loadFromPreferences { error in
if let error = error {
self.logger.error("TransparentProxy::start. Unable to save transparent proxy manager to preferences. Error: \(error.localizedDescription)")
return
}
self.logger.debug("TransparentProxy::start")
do {
try mainProxyManager.connection.startVPNTunnel()
} catch (let error) {
self.logger.error("Unable to start transparent proxy connection: \(error.localizedDescription)")
}
}
}
}
}
private func configureWorkplaceProtocol(for proxyManager: NETransparentProxyManager) {
let configurationProtocol = (proxyManager.protocolConfiguration as? NETunnelProviderProtocol) ?? NETunnelProviderProtocol()
configurationProtocol.serverAddress = "localhost"
configurationProtocol.providerBundleIdentifier = "network extension bundle id"
proxyManager.isEnabled = true
proxyManager.protocolConfiguration = configurationProtocol
proxyManager.localizedDescription = "Proxy"
}
Can you, please, suggest what am I doing wrong here? I do not see any faults in a Console regarding the extension launch. At the same time network profile of the proxy stuck in Network Settings with "connecting" status. It seems logical, because the serverAddress of configuration is a localhost. Can I set up serverAddress like this if I only want to track outgoing Internet traffic? And the startProxy looks like this:
class AppProxyProvider: NETransparentProxyProvider {
private let logger = Logger()
let containerStorage = [1, 2, 3]
override init() {
logger.info("Entered init for AppProxyProvider")
super.init()
logger.info("Exited init for AppProxyProvider")
}
override func startProxy(options: [String : Any]?, completionHandler: @escaping (Error?) -> Void) {
logger.info("Started proxy")
}
}
I don’t see you calling the completion handler that’s passed to startProxy(options:completionHandler:)
. Without that the system doesn’t know that the provider has finished starting, and so it stays stuck in the ‘connecting’ state.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"