Post

Replies

Boosts

Views

Activity

Reply to NETrasparentProxy::startProxy never gets called
Yep, I see logs from the main.swift That is what I have added func main() -> Never {     let logger = OSLog(subsystem: "proxy.main", category: "provider")     os_log(.debug, log: logger, "will start system extension mode")     autoreleasepool {         NEProvider.startSystemExtensionMode()     }     os_log(.debug, log: logger, "will dispatch main")     dispatchMain() } main()
Aug ’22
Reply to Steps to create, build and run Network System Extension on device
Thank you a lot for a clear explanation! I have managed to build and test my project following the steps you have provided! However, let's consider a situation when the Xcode can not generate a profile automatically, and a developer has to contact an Apple account admin to get a proper provisioning profile. Is there any way to test a system extension without getting the profile from the admin? For instance, would it work "normally" if the SIP is disabled?
Aug ’22
Reply to notarytool: No Keychain password item found for profile
We have changed a stored profile name, checked whether it is presented in the Keychain, and pushed CD pipelines several times with successful result. However, after some time it failed and continued delivering the same results with mentioned error. So, I make an assumption that notarytool has not enough rights to read something from the Keychain. Should we run it as a root process, or set an owner to root? The pipeline is running in the same user session as store-credentials executed.
Jul ’22
Reply to notarytool: No Keychain password item found for profile
Hi @eskimo! Thank you, for your response and suggestions. I ran an additional step in CD pipeline with two commands security find-generic-password -l '<profile-name>' and security find-generic-password -a ' com.apple.gke.notary.tool.com.saved-creds.<profile-name>'. The first one successfully found the entry in the keychain, however, the second one failed. On which result should I rely on?
Jul ’22
Reply to Split tunnelling with Network Extension
One more question. Currently I have tried to log number of packets received by the tunnel provider using readPackets(). I have wrote the next code to achieve that swift override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) - Void)  {         os_log(.default, "Tunnel is starting...")         self.pendingCompletion = completionHandler         self.startPacketHandling()  }    Where startPacketHandling() is a private method which configure settings with IP and mask of my local machine: swift  private func startPacketHandling()  {         os_log(.default, "Start packet handling")         let settings = NEPacketTunnelNetworkSettings()         settings.ipv4Settings = NEIPv4Settings(addresses: ["ip of machine"], subnetMasks: ["255.255.255.0"] )         settings.ipv4Settings?.includedRoutes = [defaultIPv4Route]         setTunnelNetworkSettings(settings)         { error in             self.pendingCompletion?(nil)             self.pendingCompletion = nil             self.readPackets();         }     } In readPackets() I try to perform logging: swift private func readPackets() {         os_log(.default, "Package reading started")         self.packetFlow.readPackets         {  packets, protocols in             os_log("Packets received from tun interface: %@", packets.count)             self.readPackets() // making a recursive call to be able to continue reading the packets         }  } And now when I start the app with the extension I could see only logs till "Package reading started". But no messages about number of received packets. Hence self.packetFlow.readPackets() don't work. And I don't understand what am I doing wrong. Could I use NEIPv4Settings() configurations of the machine in my local network?
Mar ’21
Reply to Split tunnelling with Network Extension
Thank you for reply, @meaton! I have created container app for extension and currently it provide two prompts for user: first one to allow the system extension installation and second to allow access to VPN configuration. But let's return to my first question about creating a split tunnel using NEPacketTunnelProvider. Besides WWDC session about Network Extension - https://developer.apple.com/videos/play/wwdc2019/714 I have watched also Session 717: What’s New in NetworkExtension and VPN - https://developer.apple.com/videos/play/wwdc2015/717/. In documentation I found that includeRoutes method from NEIPvSettings class may help me. As I understood, when outgoing ipv4 packets' destination adress matches with list that has been used with includeRoutes then they pass to TUN interface and to NEPacketTunnelProvider which redirects them to tunnel server. So the flow of outgoing packets could be described as: When the packet destination matches with list item - redirect to TUN interface - redirect to NEPacketTunnelProvider - redirect to tunnel server. Otherwise packets simply going to original destination without passing to TUN interface. Do I understand the packets flow in case of NEPacketTunnelProvider right?
Mar ’21
Reply to Split tunnelling with Network Extension
@meaton Thank you for quick response and detailed explanation! Currently I am also struggled with launching extension that use Packet Tunnel Provider. I have been trying to make an app without GUI that just launch the extension. To check that tunnel started I want to log some message from startTunnel() and see it in Console: swift override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) - Void) {         os_log(.default, "Tunnel started successfuly")         let settings = NETunnelNetworkSettings(tunnelRemoteAddress: "some address")         setTunnelNetworkSettings(settings) { error in             completionHandler(error)         } } Currently when I launch the app, dialog appears with message which says that application trying to install system extension. After opening "Security and Privacy" option in System Preferences and allowing installation I can found in systemextensionctl list that the extension has status "activated enabled". But there is no messages in Console about tunnel start. To achieve 'no GUI' goal I removed ViewController from project and modified AppDelegate::applicationDidFinishLaunching(): swift func applicationDidFinishLaunching(_ aNotification: Notification)  {   guard let extensionIdentifier = self.extensionBundle.bundleIdentifier else   {           os_log(.default, "Problems with extension bundle ID")             return   } os_log(.default, "SE activation request") let activationRequest = OSSystemExtensionRequest.activationRequest(forExtensionWithIdentifier: extensionIdentifier, queue: .main)   activationRequest.delegate = self OSSystemExtensionManager.shared.submitRequest(activationRequest) } To handle activation request result I have also added next thing: swift extension AppDelegate: OSSystemExtensionRequestDelegate {     func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result)     {         guard result == .completed else         {             os_log(.default, "Unexpected result for SystemExtension activation request: %@", result.rawValue)             return         }   enableTunnelConfiguration()     } } enableTunnelConfiguration: swift func enableTunnelConfiguration() {         NETunnelProviderManager.loadAllFromPreferences { managers, error in             if let loadError = error             {                 os_log("Error while loading from preferences: %@", loadError.localizedDescription)             }             let managersList = managers ?? []             if managersList.count 0             {                 self.tunnelManager = managersList.first!             }             else             {                 self.tunnelManager = self.makeManager()             }             self.tunnelManager.saveToPreferences { error in                if let saveError = error                {                    os_log("Error while saving to prefs: %@", saveError.localizedDescription)                    return                }                os_log("Successfuly saved")            }         }         do         {             try self.tunnelManager.connection.startVPNTunnel()         }         catch         {             os_log("Failed to start tunnel")         } } and makeManager(): swift  private func makeManager() - NETunnelProviderManager {         let manager = NETunnelProviderManager()         manager.localizedDescription = "CustomVPN"         let proto = NETunnelProviderProtocol()         proto.providerBundleIdentifier = "extension bundle id"         proto.serverAddress = "same as address in startTunnel()"         proto.providerConfiguration = [:]         manager.protocolConfiguration = proto         manager.isEnabled = true         return manager     } Also I'm getting log "Failed to start tunnel" after startVPNTunnel() call. Should I call this method to start tunnel and see desired message. Or extension is always launch automatically when app starts. Could it be issue with entitlements or code signing? Is it mandatory to use NETunnelManagerProvider to successfully launch extension? I save only one configuration in app, so managers list will contain only one element always? Would be glad if you provide explanation one more time. Sorry if my questions sounds dumb
Mar ’21
Reply to Implement web filter in macOS with NetworkExtension API
Hello I have been trying to do similar thing - filter outbound HTTP requests from Safari by URL. I am also using SimpleFirewall app provided as a sample for  WWDC19 session about Network Extension. But when I try to get url of the flow originated from Safari always getting nil of string with address. I have modified only handleNewFlow And here it is: swift     override func handleNewFlow(_ flow: NEFilterFlow) - NEFilterNewFlowVerdict {         guard let socketFlow = flow as? NEFilterSocketFlow,             let remoteEndpoint = socketFlow.remoteEndpoint as? NWHostEndpoint,             let localEndpoint = socketFlow.localEndpoint as? NWHostEndpoint else {                 return .allow()             }         let blacklisted = "www.example.com"         os_log("Flow %@", flow)         if socketFlow.direction != .outbound       {             os_log("Allow non-outbound connections")             return .allow()         }         if  socketFlow.url != nil         {             os_log("Host %@", socketFlow.url?.host as! CVarArg)             if blacklisted == socketFlow.url?.host             {                 return .drop()             }         }         else         {             os_log("URL is nil")         }         os_log("Endpoint hostname %@", remoteEndpoint.hostname)        os_log("New flow with local endpoint %@, remote endpoint %@", localEndpoint, remoteEndpoint)         let flowInfo = [             FlowInfoKey.localPort.rawValue: localEndpoint.port,             FlowInfoKey.remoteAddress.rawValue: remoteEndpoint.hostname         ]         let prompted = IPCConnection.shared.promptUser(aboutFlow: flowInfo) { allow in             let userVerdict: NEFilterNewFlowVerdict = allow ? .allow() : .drop()             self.resumeFlow(flow, with: userVerdict)         }         guard prompted else {             return .allow()         }         return .pause()     } When I run a firewall and check log in console I always see "URL is nil" message when I try to open websites from Safari Could you help to understand what am I doing wrong?
Mar ’21