Network Extension

RSS for tag

Customize and extend the core networking features of iOS, iPad OS, and macOS using Network Extension.

Network Extension Documentation

Pinned Posts

Posts under Network Extension tag

410 Posts
Sort by:
Post not yet marked as solved
0 Replies
12 Views
Is it possible to mock the behavior of NWPathMonitor for a specific app? The scenario I want to support I've created an app called RocketSim, a developer tool for Xcode's Simulator. I've already created Airplane mode, which disables networking calls from URLSession from a specific bundle identifier app installed on the Simulator. Now, I want to support blocking NWPathMonitor as well. I believe the Simulator uses macOS's NWPathMonitor and does not use any specific HTTP request or similar to determine the reachability state. Is there a way I can make NWPathMonitor return unsatisfied when my 'airplane mode' is turned on? Potentially using a Network Extension?
Posted
by AvdLee.
Last updated
.
Post not yet marked as solved
4 Replies
162 Views
I got an error message in Xcode related to provisioning profiles and entitlements. Specifically, it appears Xcode encountered an issue with the provisioning profile I'm trying to use. The error message states that the provisioning profile named "iOS Team Provisioning Profile" doesn't include the entitlement com.apple.developer.networking.HotspotHelper.
Posted Last updated
.
Post not yet marked as solved
12 Replies
1.8k Views
Hi guys,I'm developing a custom VPN client with NEPacketTunnelProvider which tunnels all device traffic. All is going well so far but I've noticed that iOS battery statistics (Settings -> Battery) is claiming that our client has consumed a significant amount of energy (10%~30%). I though it was true for a while, but then I conducted some basic testing which suggested this is more likely a statistical issue.I set up my device (rebooted with clean battery cosumption statistics) with ~80% battery capacity and started to watch "NASA Live" channel in Youtube app with 1080p60 quality, for 3 hours, and taking notes every hour. I cross referenced the data of the same scenario (same device as well) collected with our custom VPN provider enabled and disabled. I made sure when the VPN client is enabled, I can actually see the Youtube traffic tunneled. Actually the video feed can generate ~1GiB traffic per hour pretty stably. I can provide detailed numbers if necessary, but generally, after 3 hours, both scenarios showed an overal of ~50% battery consumption (from the battery indicator on the status bar on top of the phone screen), there was no significant difference in the battery consumption. However when I looked at the statistics in Settings -> Battery, the scenario without our VPN client was showing 100% battery consumption from Youtube app (which is expected), and the scenario with VPN was showing 68% for Youtube, and 32% for our VPN client app!32% battery consumption in statistics is scaring. But what confuses me is that the actual device battery consumption didn't increase. My theory is that without the VPN client, individual apps are sending out their traffic on their own so the battery consumption are calculated on their head. But now with our VPN client, we are actually sending out traffic for every applications so iOS will blame us for that part of energy consumption. I'm not sure if the theory is true but it certainly explains the behavior.I'm wondering if Apple can look at the issue at if proved to be a statistical issue then fix it. Because 10%+ battery consumption on our app would be enough to scare away our customers. We can explain to them there is no actual extra energy consumption but customers will be suspicious. Whenever they feel their phone's having a shortened battery life they'll come to see the list and they will blame us.Thanks in advance!
Posted
by QAZ123436.
Last updated
.
Post not yet marked as solved
8 Replies
177 Views
We have a test scenario where we install our app package on a Mac setup using MDM (Jamf). Below are the test steps and observation: This installation is done on this Mac with no user logged in. Installation is completed successfully. Now when an user log in on this mac machine, the expectation is that the app bundle will be started by the launchd (RunAtLoad). But the app is not started. When I check console logs I could see few logs around the app but from those logs I couldn't figure out why the app didn't start. I rebooted my test machine but that also didnt start my app. My app is not listed in 'launchctl list' command. My App bundle contains container app and a packet tunnel extension. Below is how my plist file looks like in '/Library/LaunchAgents/com.****.***ui.plist': { KeepAlive = 1; Label = "com.*****.client.****ui"; LimitLoadToSessionType = ( Aqua ); ProgramArguments = ( "/Applications/*********.app/Contents/MacOS/****Module" ); RunAtLoad = 1; SuccessfulExit = 1; Version = "110.200.0.100"; } In Console below are the last set of log which I could find related to my app: support_log.txt In above logs below statement mentions the extn which is related to my app bundle: 2024-03-19 15:48:55.256020+0530 0x462 Default 0x0 206 0 symptomsd: (SymptomEvaluator) [com.apple.symptomsd:analytics] [Skipping first 85 of 95 entries] 2024-03-19 15:48:55.256051+0530 0x462 Default 0x0 206 0 symptomsd: (SymptomEvaluator) [com.apple.symptomsd:analytics] entry: Thu Feb 8 20:48:26 2024 NetworkExtension.com.*****.client.*****-Client.*****ui.*****pkttunnel.104.2.12.191.104.2.12 (bundle) 0 0 0 0 0 0 Can someone please help me in understanding what could be wrong here, why would 'RunAtLoad' key word wont work here to start my app on user login or reboot? Note: Everything work fine when my app is installed with an user logged in to the test machine. Also App starts successfully if I run command 'lauchctl bootstrap gui/ /Library/LaunchAgents/com.****.****ui.plist' in the above mentioned test scenario where app didnt auto start by launchd: 'RunAtLoad'.
Posted
by macnd.
Last updated
.
Post not yet marked as solved
5 Replies
146 Views
Hello! I am part of a research team who need advice on how to track and intercept network requests from a device. More specifically, we are interested in collecting the websites the research participants have tried to access. We want something like what YouGov does with their Pulse App. Also, is it possible to implement this without having to rely on an external server that acts as a intermediary? How do we achieve this? We'd appreciate a detailed response with helpful links to how to implement it. Thank you very much for your time.
Posted
by stilakid.
Last updated
.
Post not yet marked as solved
4 Replies
244 Views
Hello, We would like to track the open sockets on the machine. we don't want to use a constantly running thread that polls the open sockets (such as by using sysctlbyname) since it sometimes will miss short-lived sockets. After some research we decided to implement a content filter (NEFilterDataProvider) that pass-through every socket flow. However, as we see and read in the forum, all previously opened sockets are disconnected once the filter is applied, which is an undesired thing for users using a VPN that will disconnect as well. We would like to know if there is a better way to track all sockets, preferably in an event-driven way, or, to prevent the existing sockets from disconnecting if we use the filter or other network extension.
Posted
by BoazH.
Last updated
.
Post not yet marked as solved
0 Replies
211 Views
I found my mac automatically connects to the Google server 8.8.8.8 and 8.8.4.4 that I haven't set in my mac. I figured out it seems to be set via /Library/Preferences/com.apple.networkextension.control.plist as follows: { CriticalDomains = ( "cheeserolling.apple.com", "woolyjumper.sd.apple.com", "basejumper.apple.com", "basejumper-vip.sd.apple.com", "basejumper.sd.apple.com", "locksmith.apple.com", "gdmf-staging-int.apple.com", "pallas-uat.rno.apple.com", "pr2-pallas-staging-int-prz.apple.com", "livability-api.swe.apple.com" ); } I cannot find any info about those domains online. I am wondering if it is possible like for apple staffs to set those CriticalDomains to control the connections to servers.
Posted
by Ce_123.
Last updated
.
Post marked as solved
1 Replies
237 Views
hi,all readBytes: An NSData object containing the data to filter. For non-UDP/TCP flows, since the data may optionally include the IP header, readBytes includes a 4-byte NEFilterDataAttribute field preceding the user data. Your handler must examine the NEFilterDataAttribute field and handle the data accordingly. the param above in method handleInboundDataFromFlow:readBytesStartOffset:readBytes: i assume it contains a 4-byte NEFilterDataAttribute field preceding the user data all the time, is it normal that i get a NEFilterDataAttribute: 1099782776645(and some other very big number) const NEFilterDataAttribute* dataAttr = readBytes.bytes; NSLog(@"NEFilterDataAttribute: %ld",*dataAttr); and after the initial 4 bytes, if the offset param is 0, can i assume that UDP/TCP or IP packet headers can be extracted from the data?
Posted
by MeLawSS.
Last updated
.
Post not yet marked as solved
2 Replies
128 Views
We have a network content-filter consisting of a main target/GUI, a FilterDataProvider extension and a FilterControlprovider extension. The app is installed via MDMs and works without issues the vast majority of times, but during testing of TestFlight builds we've found that intermittently the device fails to install the network extensions and blocks internet access. The GUI is working fine though. From the logs we can see that when this happens the device tries to start the network extensions repeatedly. The issue is solved by restarting the device. Has anyone experienced similar issues or have some ideas of what might cause this behaviour? These are some of the logs we see in Console: neagent [u E6D696F2-62FB-4262-A97C-B2006EC528C5:m (null)] [<private>(<private>)] Hub connection error: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named <BundleID>.FilterDataProvider" ugDescription=connection to service named <BundleID>.FilterDataProvider}code-block Failed to start the data extension <BundleID>.FilterDataProvider: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named <BundleID>.FilterDataProvider" ugDescription=connection to service named <BundleID>.FilterDataProvider} nehelper Denying connection from nesessionmanager (264) because it is missing the com.apple.private.network.socket-delegate entitlement nesessionmanager <BundleID>[inactive]: starting launchd Service could not initialize: posix_spawn(/private/var/containers/Bundle/Application/F84E2325-05A6-4DC2-8DD6-20C97EF43E8D/<AppName>.app/PlugIns/FilterDataProvider.appex/FilterDataProvider) failed, error 0x2 - No such file or directory nesessionmanager NEFilterPlugin(<BundleID>[inactive]): Sending start command nesessionmanager <BundleID>[inactive]: starting neagent Looking for a data extension with identifier <BundleID>.FilterDataProvider neagent [d <private>] <PKHost:0x718915550> Query: { NSExtensionIdentifier = "<BundleID>.FilterDataProvider"; NSExtensionPointName = "com.apple.networkextension.filter-data"; } neagent Found 1 data extension(s) with identifier <BundleID>.FilterDataProvider neagent Looking for a control extension with identifier <BundleID>.FilterControlProvider neagent [d <private>] <PKHost:0x718915550> Query: { NSExtensionIdentifier = "<BundleID>.FilterControlProvider"; NSExtensionPointName = "com.apple.networkextension.filter-control"; } neagent Found 1 control extension(s) with identifier <BundleID>.FilterControlProvider neagent Beginning data extension request with extension <BundleID>.FilterDataProvider neagent [u C743CE7B-9E19-4A41-BF46-91AEFB24169D:m (null)] [<private>(<private>)] Failed to start plugin; pkd returned an error: Error Domain=PlugInKit Code=4 .<AppName>.FilterDataProvider(C743CE7B-9E19-4A41-BF46-91AEFB24169D): Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch ErrorDomain Code=2 "No such file or directory" UserInfo={NSLocalizedDescription=Launchd job spawn failed}}}" UserInfo={NSLocalizedDescription=RBSLaunchRequest error trying to launch 7B-9E19-4A41-BF46-91AEFB24169D): Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., NSUnderlyingError=0xdb88df3d0 {Error UserInfo={NSLocalizedDescription=Launchd job spawn failed}}}} neagent Extension request with data extension <BundleID>.FilterDataProvider started with identifier (null) neagent Failed to start the data extension <BundleID>.FilterDataProvider: Error Domain=PlugInKit Code=4 "RBSLaunchRequest error trying to launch vider(C743CE7B-9E19-4A41-BF46-91AEFB24169D): Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., SIXErrorDomain Code=2 "No such file or directory" UserInfo={NSLocalizedDescription=Launchd job spawn failed}}}" UserInfo={NSLocalizedDescription=RBSLaunchRequest error trying to DataProvider(C743CE7B-9E19-4A41-BF46-91AEFB24169D): Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., SIXErrorDomain Code=2 "No such file or directory" UserInfo={NSLocalizedDescription=Launchd job spawn failed}}}} nesessionmanager NESMFilterSession[FilterDataProvider:0C4C9E40-5005-47A5-8C60-F7C8630F29DF] in state NESMFilterSessionStateStarting: plugin NEFilterPlugin(e with error: 1 nesessionmanager <BundleID>[266]: disposing neagent Initializing the delegate neagent App <BundleID> is not installed or is not valid neagent App <BundleID> is not installed or is not valid neagent Failed to find a com.apple.networkextension.filter-data extension inside of app <BundleID> neagent NEAgentSession: failed to create the delegate nesessionmanager <BundleID>[259]: Tearing down XPC connection due to setup error: Error Domain=NEAgentErrorDomain Code=2 "(null)" nesessionmanager <BundleID>[259]: XPC connection went away nesessionmanager NESMFilterSession[FilterDataProvider:0C4C9E40-5005-47A5-8C60-F7C8630F29DF]: Failed to start with error: Error Domain=NEAgentErrorDomain Code=2 "(null)"
Posted
by gmattl.
Last updated
.
Post not yet marked as solved
1 Replies
116 Views
Hi, Need some help figuring out the options and actions on following situations: When there are two or more enterprise VPNs installed on a device, one is currently active (some other brand tunnel packet provider). Then the user opens my app that triggers the opening of my network extension packet tunnel provider. Can that situation be identified so a notification be prompted to the user? Can my packet tunnel provider get / have priority over the current running packet tunnel provider? Please guid / direct to relevant document. Thanks in advance, ~r
Posted Last updated
.
Post not yet marked as solved
4 Replies
286 Views
I use NEHotspotNetwork.fetchCurrentWithCompletionHandle, but it gives me Nil for both SSID and BSSID #import "FPPHotspotNetworkInfoProvider.h" #import <NetworkExtension/NetworkExtension.h> @implementation FPPHotspotNetworkInfoProvider - (void)fetchNetworkInfoWithCompletionHandler: (void (^)(FPPNetworkInfo *network))completionHandler API_AVAILABLE(ios(14)) { [NEHotspotNetwork fetchCurrentWithCompletionHandler:^( NEHotspotNetwork *network) { dispatch_async(dispatch_get_main_queue(), ^{ if (network) { completionHandler([[FPPNetworkInfo alloc] initWithSSID:network.SSID BSSID:network.BSSID]); return; } completionHandler(nil); }); }]; } @end Do I need approval from Apple for this? If so, could you please provide guidance on how to obtain it? Thank you.
Posted Last updated
.
Post not yet marked as solved
3 Replies
119 Views
Hi, I am working on the app for some basic concept, I would like to intercept both DNS and IP connections. I succeeded in intercepting DNS using NEDNSProxyProvider, however I seem to have some troubles with IPConnections using NEFilterDataProvider. First thing, I have three targets in my app. For some reason, when I run DNS Proxy Extension target it doesn't ask me to choose the app for target run, and after the application if launched, it correctly intercepts DNS traffic and inits NEDNSProxyManager ps: all logs are correctly displayed for NEFilterDataProvider However, when I try to run Filter Data Extension target with Content Filter capability, it asks me to choose the app for run. Even tho I checked the Build Settings and those are identical to DNS Proxy Extension target. And finally, when I run main target it still inits NEDNSProxyManager properly and the NEFilterManager returns this warning -[NEFilterManager saveToPreferencesWithCompletionHandler:]_block_invoke_3: failed to save the new configuration: (null) I tried to log the configuration and compared to some code samples, but I can't identify the problem. I'd very grateful if somebody could suggest where the problems might be (targets builds difference & NEFilterManager config) I will attach a sample of code where I add configuration to my NEFilterManager // MARK: - FilterDataManager final class FilterDataManager: NSObject, ObservableObject { // MARK: - Properties private let manager = NEFilterManager.shared() private let filterName = "Data Filter" @Published private(set) var isEnabled: Bool? = nil // MARK: - Singleton static let shared = FilterDataManager() // Cancellables set private var subs: Set<AnyCancellable> = [] private override init() { super.init() enable() manager.isEnabledPublisher() .receive(on: DispatchQueue.main) .sink(receiveValue: { [weak self] isEnabled in self?.setIsEnabled(isEnabled) }) .store(in: &subs) } // MARK: - Filter Configurations func enable() { manager.updateConfiguration { [unowned self] manager in manager.localizedDescription = filterName manager.providerConfiguration = createFilterProviderConfiguration() manager.isEnabled = true } completion: { result in guard case let .failure(error) = result else { return } Log("Filter enable failed: \(error)", prefix: "[Filter]") } } private func createFilterProviderConfiguration() -> NEFilterProviderConfiguration { let configuration = NEFilterProviderConfiguration() configuration.organization = "***" configuration.filterBrowsers = true configuration.filterSockets = true return configuration } func disable() { Log("Will disable filter", prefix: "[Filter]") manager.updateConfiguration { manager in manager.isEnabled = false } completion: { result in guard case let .failure(error) = result else { return } Log("Filter enable failed: \(error)") } } private func setIsEnabled(_ isEnabled: Bool) { guard self.isEnabled != isEnabled else { return } self.isEnabled = isEnabled Log("Filter \(isEnabled ? "enabled" : "disabled")", prefix: "[Filter]") } } ```Swift extension NEFilterManager { // MARK: - NEFilterManager config update func updateConfiguration(_ body: @escaping (NEFilterManager) -> Void, completion: @escaping (Result<Void, Error>) -> Void) { loadFromPreferences { [unowned self] error in if let error, let filterError = FilterError(error) { completion(.failure(filterError)) return } body(self) saveToPreferences { (error) in if let error, let filterError = FilterError(error) { completion(.failure(filterError)) return } completion(.success(())) } } } // MARK: - Publisher enabling func isEnabledPublisher() -> AnyPublisher<Bool, Never> { NotificationCenter.default .publisher(for: NSNotification.Name.NEFilterConfigurationDidChange) .compactMap { [weak self] notification in guard let self else { return nil } return self.isEnabled } .eraseToAnyPublisher() } } // MARK: - FilterError @available(iOS 8.0, *) enum FilterError: Error { /// The Filter configuration is invalid case configurationInvalid /// The Filter configuration is not enabled. case configurationDisabled /// The Filter configuration needs to be loaded. case configurationStale /// The Filter configuration cannot be removed. case configurationCannotBeRemoved /// Permission denied to modify the configuration case configurationPermissionDenied /// Internal error occurred while managing the configuration case configurationInternalError case unknown init?(_ error: Error) { switch error { case let error as NSError: switch NEFilterManagerError(rawValue: error.code) { case .configurationInvalid: self = .configurationInvalid return case .configurationDisabled: self = .configurationDisabled return case .configurationStale: self = .configurationStale return case .configurationCannotBeRemoved: self = .configurationCannotBeRemoved return case .some(.configurationPermissionDenied): self = .configurationPermissionDenied return case .some(.configurationInternalError): self = .configurationInternalError return case .none: return nil @unknown default: break } default: break } assertionFailure("Invalid error \(error)") return nil } }
Posted Last updated
.
Post marked as solved
3 Replies
202 Views
Hello, I know that EndpointSecurity doesn't support network events, save for some events related to Unix pipes. In WWDC 2020 #10159 Apple says that: Those of you who have already worked with the EndpointSecurity framework have likely noticed that we do not provide events related to networking operations. This is intentional as these are better covered by the NetworkExtension framework. Could you please give me a short and high-level hint how I can use NetworkExtension to provide connect, disconnect events to a monitoring app, that tries to log those events in a database? I would like to receive the remote IP and remote port + local port. From what I've researched, In NetworkExtension documentation it's stated that it's possible to create a "content filter", which would probably be a good source of information; the problem is that because of the privacy requirements, the "content filter" can't send back any information about user data, because it's separated in a restrictive sandbox. So I'm not sure the "content filter" would even be possible to be used as a source of network events. Other types of categories inside NetworkExtension doesn't seem to be a good match for my use case. Is it possible to use NetworkExtension to get information about network events (connect/disconnect), like EndpointSecurity does for i.e. processes (process start/process end)?
Posted
by MistyFog.
Last updated
.
Post not yet marked as solved
2 Replies
151 Views
We are trying to configure split tunnel with tunnel routes with the below Tunnel Provider configuration tunnelProvider.protocolConfiguration.includeAllNetworks = NO; tunnelProvider.protocolConfiguration.excludeLocalNetworks = NO; tunnelProvider.protocolConfiguration.enforceRoutes = YES; We are adding some IPs in the excludeRoutes[10.168.10.182 and 192.168.10.65]. Please refer the below network settings for VPN IPv4Settings = { configMethod = manual addresses = ( 10.168.10.68, ) subnetMasks = ( 255.255.255.255, ) includedRoutes = ( { destinationAddress = 0.0.0.0 destinationSubnetMask = 0.0.0.0 }, ) excludedRoutes = ( { destinationAddress = 192.168.10.65 destinationSubnetMask = 255.255.255.255 }, { destinationAddress = 10.168.10.182 destinationSubnetMask = 255.255.255.255 }, ) overridePrimary = NO } Issue: when we are trying to access excludedRoute's IP [10.168.10.182 and 192.168.10.65] , it's getting tunneled. Expected Results : excludedRoutes IPs should go via physical interface.
Posted Last updated
.
Post not yet marked as solved
5 Replies
272 Views
Hello! I created a simple DNS filter application for iOS but the extension is not launching. I am getting this log message in the console. Failed to start extension edu.stanford.stilakid.testDnsFilter.DNSFiltering: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named edu.stanford.stilakid.testDnsFilter.DNSFiltering.apple-extension-service" UserInfo={NSDebugDescription=connection to service named edu.stanford.stilakid.testDnsFilter.DNSFiltering.apple-extension-service} For another project with the same code for dns filtering but different bundleID, I also got the following log message. Failed to start extension edu.stanford.sml.rdahlke.controlShift.DNSProxy: Error Domain=PlugInKit Code=4 "RBSLaunchRequest error trying to launch plugin edu.stanford.sml.rdahlke.controlShift.DNSProxy(D26CD63C-4656-4A30-99A0-7C867265DD75): Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., NSUnderlyingError=0xc62b8c0d0 {Error Domain=NSPOSIXErrorDomain Code=111 "Unknown error: 111" UserInfo={NSLocalizedDescription=Launchd job spawn failed}}}" UserInfo={NSLocalizedDescription=RBSLaunchRequest error trying to launch plugin edu.stanford.sml.rdahlke.controlShift.DNSProxy(D26CD63C-4656-4A30-99A0-7C867265DD75): Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., NSUnderlyingError=0xc62b8c0d0 {Error Domain=NSPOSIXErrorDomain Code=111 "Unknown error: 111" UserInfo={NSLocalizedDescription=Launchd job spawn failed}}}} Also, the log messages I have defined inside the constructor of the dns proxy extension is nowhere to be found in the logs, so I am pretty sure the extension is failing to launch. The debugger attached to the main target app shows no errors as well, so it is able to load and update dnsProtocol. Here is the code: // DNSProxyProvider.swift // DNSFiltering // // Created by Juben Rana on 2/20/24. // import NetworkExtension import os.log class DNSProxyProvider: NEDNSProxyProvider { // MARK: - Logger static let logger = Logger(subsystem: "edu.stanford.sml.rdahlke.controlShift", category: "dns-filter") override init() { Self.logger.log(level: .debug, "TestDns: dns proxy provider will init") self.logger = Self.logger super.init() } let logger: Logger override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) { // Add code here to start the DNS proxy. logger.log(level: .debug, "TestDns: proxy will start") completionHandler(nil) } override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { // Add code here to stop the DNS proxy. logger.log(level: .debug, "TestDns: proxy will stop") completionHandler() } 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. logger.log(level: .debug, "TestDns: proxy is handling flow") return false } } // ContentView.swift // testDnsFilter // // Created by Juben Rana on 2/20/24. // import SwiftUI struct ContentView: View { var body: some View { VStack { // LoginScreen() // .onOpenURL { url in // GIDSignIn.sharedInstance.handle(url) // } Spacer() #if os(macOS) Text("I'm running on macOS") #else Text("I'm running on iOS") #endif Spacer() Button("Activate") { #if os(macOS) ContentFilterMac.shared.activate() #elseif os(iOS) ContentFilter.shared.enable() #endif } Spacer() Button("Deactivate") { #if os(macOS) ContentFilterMac.shared.deactivate() #elseif os(iOS) ContentFilter.shared.disable() #endif } Spacer() Spacer() } .padding() } } #Preview { ContentView() } // // ContentFilter.swift // controlShift // // Created by Juben Rana on 9/28/23. // // This is only for macOS import Foundation import NetworkExtension import os.log // MARK: - Content Filter class ContentFilter { // MARK: - Set Up static let shared = ContentFilter() private init() { Self.logger.log(level: .debug, "content filter will init") self.logger = Self.logger } // MARK: - Logger static let logger = Logger(subsystem: "edu.stanford.stilakid.testDnsFilter", category: "content-filter") let logger: Logger // MARK: - DNS Filter private let manager = NEDNSProxyManager.shared() func enable() { loadAndUpdatePreferences { self.manager.localizedDescription = "DNSProxySample" let dnsProtocol = NEDNSProxyProviderProtocol() dnsProtocol.providerBundleIdentifier = "edu.stanford.stilakid.testDnsFilter.DNSFiltering" self.manager.providerProtocol = dnsProtocol self.manager.isEnabled = true } } func disable() { loadAndUpdatePreferences { self.manager.isEnabled = false } } private func loadAndUpdatePreferences(_ completion: @escaping () -> Void) { manager.loadFromPreferences { error in guard error == nil else { debugPrint("DNSProxySample.App: load error") return } completion() self.manager.saveToPreferences { (error) in guard error == nil else { debugPrint("DNSProxySample.App: save error") return } debugPrint("DNSProxySample.App: saved") } } } }
Posted
by stilakid.
Last updated
.
Post not yet marked as solved
8 Replies
254 Views
Hello! If I set only remote address, then packet tunnel provider does not intercept packets at all. Internet works. If I add ipv4Settings, then packet tunnel provider somewhat catch packets. If I try open something in web beforehand, and quickly start packet tunnel provider, it sees leftover packets. Internet does not work. If I set DNS settings, then tunnel starts receiving "apple.com", "icloud.com" DNS queries. I guess that's not right. Internet does not work. How do I set everything right? ============= My settings: let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: address) settings.ipv4Settings = NEIPv4Settings(addresses: ["172.16.200.10"], subnetMasks: ["255.255.255.255"]) settings.ipv4Settings?.includedRoutes = [NEIPv4Route.default()] settings.ipv4Settings?.excludedRoutes = [ NEIPv4Route(destinationAddress: "192.168.0.0", subnetMask: "255.255.0.0"), NEIPv4Route(destinationAddress: "10.0.0.0", subnetMask: "255.0.0.0"), NEIPv4Route(destinationAddress: "172.16.0.0", subnetMask: "255.240.0.0") ] settings.dnsSettings = NEDNSSettings(servers: ["8.8.8.8", "8.8.4.4"]) settings.dnsSettings?.matchDomains = [""] settings.mtu = 1400
Posted Last updated
.
Post not yet marked as solved
3 Replies
227 Views
Our VPN was implemented using the NEPacketTunnelProvider, in the case of back end permanent errors (e.g. permission denied), we would stop the VPN tunnel by calling the cancelTunnelVPNWithError method. This did stop the VPN, however the VPN would auto reconnect and enter an infinite loop of connecting and disconnecting due to the back end permanent error. The VPN was turned on from the VPN settings. To completely disable the VPN, we need to either delete the VPN configuration, or manually tap on the toggle to disable. Sample code: - (void)PPNService:(PPNService *)PPNService didStopWithError:(nullable NSError *)error { SUBSPPNStatusData *ppnStatusData = [[SUBSPPNStatusData alloc] init]; SUBSPPNToggleStatus *toggleStatus = [[SUBSPPNToggleStatus alloc] init]; toggleStatus.ppnToggleStatus = SUBSPPNToggleStatus_PPNToggleStatus_Off; if (error) { [_ppnSessionManager logSessionEnd]; [self cancelTunnelWithError:error]; ppnStatusData.ppnStatus = SUBSPPNStatusData_PPNStatus_StoppedWithError; PPNStatusDetails *details = error.userInfo[PPNStatusDetailsKey]; } Question: Why does the VPN auto reconnect after calling the cancel method? Any solutions to completely stop the VPN on permanent errors.
Posted
by jingyil.
Last updated
.
Post not yet marked as solved
1 Replies
193 Views
Issue Description: When VPN packet tunnel provider is configured as Full tunnel with Tunnel routes as below, tunnelProvider.protocolConfiguration.includeAllNetworks = YES; tunnelProvider.protocolConfiguration.excludeLocalNetworks = NO; tunnelProvider.protocolConfiguration.enforceRoutes = NO; and saved to NETunnelProviderManager preferences using “saveToPreferencesWithCompletionHandler” After saving the configuration to preferences and after receiving the NEVPNConfigurationChangeNotification we are starting the tunnel using “startVPNTunnelWithOptions”. Not able to connect to VPN only from iOS 17 and above devices and internet is getting blocked throughout the device after trying to the start tunnel. Once this issue is occurred, need to restart the device to get the internet connection back. On iOS 16 and Below: Able to successful connect and start VPN tunnel. On iOS 17 and Later: Not able to connect to VPN. VPN tunnel status is getting changed from connecting to disconnected. Internet on the device is getting blocked after VPN gets disconnected. Need to restart the device to get the internet connection back. We can see the below device console logs: After applying the above NETunnelProviderManager preferences and starting the tunnel, we can see that the VPN status is changed to connecting, 14:59:22.599515+0530 nesessionmanager NESMVPNSession[Primary Tunnel:SomeServerAddressXYZ:(null)]: status changed to connecting Later we can see the status is getting changed to Disconnected: 14:59:23.588634+0530 nesessionmanager NESMVPNSession[Primary Tunnel:SomeServerAddressXYZ:(null)]: status changed to disconnected, last stop reason None 14:59:23.589042+0530. nesessionmanager NESMVPNSession[Primary Tunnel:SomeServerAddressXYZ:(null)]: Updated network agent (inactive, compulsory, not-user-activiated, not-kernel-activated) After this receiving the NEVPNStatusChanged notification in our application and NEVPNStatus is changed to Disconnected. When checked the reason for disconnect using “fetchLastDisconnectErrorWithCompletionHandler” on NEVPNConnection, we can see below Error string : The VPN session failed because an internal error occurred Error code : 12 After sometime I see that the VPN status is again changed back to connecting, 14:59:24.615125+0530 nesessionmanager NESMVPNSession[Primary Tunnel:bng-pcs-gateway.pulsesecure.net/pulse:24711A15-54C6-44C7-987D-65B7BFF3F294:(null)]: status changed to connecting But by this time there is no internet connection across device. Steps to reproduce: Configure VPN packet tunnel provider as Full tunnel with Tunnel routes(as mentioned above) Save the configuration to NETunnelProviderManager preferences using “saveToPreferencesWithCompletionHandler” Try to connect to VPN From iOS 17 and above its observed that, not able to connect to VPN and internet connection in the device is getting blocked Queries: From the above observation my queries are, Why are we receiving the Disconnected state during connection? Why is this issue occurring only with iOS 17 and above device? What changes specifically done around tunnel from iOS 17 and above?
Posted
by BMDivya.
Last updated
.
Post not yet marked as solved
5 Replies
145 Views
Hi Team, In Sonoma, we have observed NIMLOC DNS queries originating from the utun interface with identical destination and source addresses, causing a loopback within utun. How should these DNS queries be handled? This issue does not occur in Ventura. Please refer to the attached screenshot.
Posted
by namdev20.
Last updated
.