Network Extension

RSS for tag

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

Posts under Network Extension tag

114 Posts

Post

Replies

Boosts

Views

Activity

Enhancing NEFilterPacketProvider with Process-Level Filtering
Our application currently uses NEFilterPacketProvider to filter network traffic based on Layer 4 rules (5-tuple: source IP, destination IP, source port, destination port, and protocol) on a packet-by-packet basis. We now want to extend this filtering to also consider the associated process—for example, allowing traffic from a specific source IP to a destination IP and port only if it's associated with a specific local process. That is, we’d like to make filtering decisions not just based on the 5-tuple, but also on the identity of the process either sending or receiving the traffic. We’ve looked into NEFilterSocketProvider, which does expose Layer 7 information such as process identifiers. However, it doesn’t seem to be tightly synchronized with the packet flow handled by NEFilterPacketProvider. As a result, there’s a risk that we might only get process information after the TCP handshake is complete, or before the socket is fully bound—at which point some of the 5-tuple fields (such as the local port) may still be unavailable. What we need is a way to correlate the 5-tuple with the relevant process name (either sender or receiver) at the time the first packet—e.g., a SYN packet—is about to be sent or received. Is there a recommended way to achieve this kind of early, process-aware filtering using NetworkExtension APIs?
1
0
114
Jun ’25
AdHoc IPA: "permission denied" when installing DNS Proxy NetworkExtension (all entitlements and profiles seem correct)
Hi all! I’m having trouble distributing an iOS app with a DNS Proxy NetworkExtension via AdHoc. The app and extension work perfectly with development profiles, but when I export and install the AdHoc IPA, I get a “permission denied” error when trying to install/enable the DNS Proxy extension. What I’ve done: Both the app and the DNS Proxy extension have their own App IDs in the Apple Developer portal. Both App IDs have the same App Group enabled: group.com.irakai.SafeLinkApp2. The extension App ID has the NetworkExtension capability with dns-proxy enabled. I created two AdHoc provisioning profiles (one for the app, one for the extension), both including the same devices and the correct entitlements. I assigned the correct AdHoc profiles to each target in Xcode and exported the IPA via Organizer. I install the IPA on a registered device using Apple Configurator. Entitlements (extracted from the signed binaries on device): App: <key>application-identifier</key><string>6PBG234246.com.irakai.SafeLinkApp2</string> <key>com.apple.developer.networking.networkextension</key><array> <string>packet-tunnel-provider</string> <string>dns-proxy</string> </array> <key>com.apple.developer.team-identifier</key><string>6PBG234246</string> <key>com.apple.security.application-groups</key><array> <string>group.com.irakai.SafeLinkApp2</string> </array> <key>get-task-allow</key><false/> DNSProxy Extension: <key>application-identifier</key><string>6PBG234246.com.irakai.SafeLinkApp2.DNSProxy</string> <key>com.apple.developer.networking.networkextension</key><array> <string>dns-proxy</string> </array> <key>com.apple.developer.team-identifier</key><string>6PBG234246</string> <key>com.apple.security.application-groups</key><array> <string>group.com.irakai.SafeLinkApp2</string> </array> <key>get-task-allow</key><false/> Error message (from my app’s logs): Error instalando DNS Proxy: permission denied Usuario: Roberto AppGroup: group.com.irakai.SafeLinkApp2 AppGroupPath: /private/var/mobile/Containers/Shared/AppGroup/D8AD2DED-AD96-4915-9B7A-648C9504679B Entitlements: BundleId: com.irakai.SafeLinkApp2 Debug info: Error Domain=NEDNSProxyErrorDomain Code=1 "permission denied" UserInfo={NSLocalizedDescription=permission denied} Other details: The device is included in both AdHoc profiles. The App Group is present and identical in both entitlements. The extension’s bundle identifier matches the App ID in the portal. The extension is signed with the correct AdHoc profile. I have tried rebooting the device and reinstalling the IPA. The error only occurs with AdHoc; development builds work fine. Questions: Is there anything else I should check regarding AdHoc provisioning for NetworkExtension DNS Proxy? Are there any known issues with AdHoc and NetworkExtension on recent iOS versions? Is there a way to get more detailed diagnostics from the system about why the permission is denied? Could this be a bug in iOS, or am I missing a subtle configuration step? Any help or suggestions would be greatly appreciated. Thank you!
1
0
145
Jun ’25
NEFilterDataProvider + NEFilterControlProvider not catching in-app requests
Goal : Block all outbound connections to a static list of hosts (both In-app requests and WKWebView/Safari). App & both extensions have Network Extension entitlement with content-filter-provider and filter-control-provider What’s working: Safari and WKWebView requests matching the block list are dropped. What’s broken: In-app traffic never reaches the Data Provider—those requests always succeed. Setup: • NEFilterProviderConfiguration with both Data & Control providers, filterBrowsers = true, filterSockets = true • Data Provider implements handleNewFlow for socket/browser flows • Control Provider implements handleNewFlow for browser flows • Enabled via saveToPreferences() and toggled ON in Settings
3
1
125
Jun ’25
NEFilterManager saveToPreferences fails with "permission denied" on TestFlight build
I'm working on enabling a content filter in my iOS app using NEFilterManager and NEFilterProviderConfiguration. The setup works perfectly in debug builds when running via Xcode, but fails on TestFlight builds with the following error: **Failed to save filter settings: permission denied ** **Here is my current implementation: ** (void)startContentFilter { NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults synchronize]; [[NEFilterManager sharedManager] loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (error) { NSLog(@"Failed to load filter: %@", error.localizedDescription); [self showAlertWithTitle:@"Error" message:[NSString stringWithFormat:@"Failed to load content filter: %@", error.localizedDescription]]; return; } NEFilterProviderConfiguration *filterConfig = [[NEFilterProviderConfiguration alloc] init]; filterConfig.filterSockets = YES; filterConfig.filterBrowsers = YES; NEFilterManager *manager = [NEFilterManager sharedManager]; manager.providerConfiguration = filterConfig; manager.enabled = YES; [manager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (error) { NSLog(@"Failed to save filter settings: %@", error.localizedDescription); [self showAlertWithTitle:@"Error" message:[NSString stringWithFormat:@"Failed to save filter settings: %@", error.localizedDescription]]; } else { NSLog(@"Content filter enabled successfully!"); [self showAlertWithTitle:@"Success" message:@"Content filter enabled successfully!"]; } }); }]; }); }]; } **What I've tried: ** Ensured the com.apple.developer.networking.networkextension entitlement is set in both the app and system extension. The Network extension target includes content-filter-provider. Tested only on physical devices. App works in development build, but not from TestFlight. **My questions: ** Why does saveToPreferencesWithCompletionHandler fail with “permission denied” on TestFlight? Are there special entitlements required for using NEFilterManager in production/TestFlight builds? Is MDM (Mobile Device Management) required to deploy apps using content filters? Has anyone successfully implemented NEFilterProviderConfiguration in production, and if so, how?
1
0
260
Jun ’25
Network connectivity issue observed on OS 15.4.1
Recently, we have observed that after upgrading to OS 15.4.1, some devices are experiencing network issues. We are using a Network Extension with a transparent app proxy in our product. The user encounters this issue while using our client, but the issue persists even after stopping the client app. This appears to be an OS issue. Below is the sytem logs. In the system logs, it says [C669.1 Hostname#546597df:443 failed transform (unsatisfied (No network route), flow divert agg: 2)] event: transform:children_failed @0.001s In scutil --dns, it says not reachble. DNS configuration resolver #1 flags : reach : 0x00000000 (Not Reachable) resolver #2 domain : local options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 300000 resolver #3 domain : 254.169.in-addr.arpa options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 300200 resolver #4 domain : 8.e.f.ip6.arpa options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 300400 resolver #5 domain : 9.e.f.ip6.arpa options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 300600 resolver #6 domain : a.e.f.ip6.arpa options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 300800 resolver #7 domain : b.e.f.ip6.arpa options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 301000 We need to restart the system to recover from the issue.
10
0
356
Jun ’25
Simultaneous Use of PacketTunnelProvider and DNSProxyProvider extensions
Hi! I'm working on a solution (iOS 18) that uses Network Extensions PacketTunnelProvider and Content Filter. Currently I'm trying to integrate it with another extension – DNSProxyProvider. My goal is to process dns queries and use resolved ips and names for additional routing inside of the packet tunnel. I'm running into a major issue: whenever both VPN and DNS proxy are active simultaneously, the device completely loses internet connectivity — no traffic goes through, and DNS resolution seems to stop working entirely. I know about the mdm supervision requirement to use DNSProxyProvider and that's covered as I work with a managed device and install a DNS proxy profile, here's how its .mobileconfig file looks like: The DNS proxy itself works fine when working by itself (without VPN being turned on), as I implemented it that it successfully processes DNS packets flows while collecting information about domains etc, and everything works perfectly. Problems begin when using VPN at the same time. I'm aware that tunnel settings include dns related options that can affect this, but I haven't had much luck with tweaking them. Here's how they look right now for reference: let settings: NEPacketTunnelNetworkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "240.0.0.1") // let dnsSettings = NEDNSSettings(servers: "8.8.8.8,8.8.4.4".components(separatedBy: ",")) // dnsSettings.matchDomains = [""] // settings.dnsSettings = dnsSettings settings.proxySettings = nil /* ipv4 settings */ let ipv4Settings = NEIPv4Settings(addresses: ["240.0.0.2"], subnetMasks: ["255.255.255.0"]) ipv4Settings.includedRoutes = [NEIPv4Route.default()] settings.ipv4Settings = ipv4Settings /* MTU */ settings.mtu = 1500 return settings I've tried excluding some dns related ip routes and dns settings shenanigans but nothing. I haven't found any information that might suggest that using both of these extensions at the same time doesn't work, on the contrary, this page in the official documentation about the expected use of packet tunnel provider the expected use of packet tunnel provider, as it talks about the fact that you should not use it for interception of all of DNS traffic, as the use of DNSPRoxyProvider (or dns settings) are built for that, which in my mind, suggests that there should be no problem with using them both and just splitting the dns traffic handling to the proxy. Will be thankful for any help!
3
0
151
May ’25
TLS communication error between iPhone and iPad
We are implementing a connection between iPad and iPhone devices using LocalPushConnectivity, and have introduced SimplePushProvider into the project. We will have it switch between roles of Server and Client within a single project. ※ iPad will be Server and the iPhone will be Client. Communication between Server and Client is via TLS, with Server reading p12 file and Client setting public key. Currently, a TLS error code of "-9836" (invalid protocol version) is occurring when communicating from Client's SimplePushProvider to Server. I believe that Client is sending TLS1.3, and Server is set to accept TLS1.2 to 1.3. Therefore, I believe that the actual error is not due to TLS protocol version, but is an error that is related to security policy or TLS communication setting. Example: P12 file does not meet some requirement NWProtocolTLS.Options setting is insufficient etc... I'm not sure what the problem is, so please help. For reference, I will attach you implementation of TLS communication settings. P12 file is self-signed and was created by exporting it from Keychain Access. Test environment: iPad (OS: 16.6) iPhone (OS: 18.3.2) ConnectionOptions: TLS communication settings public enum ConnectionOptions { public enum TCP { public static var options: NWProtocolTCP.Options { let options = NWProtocolTCP.Options() options.noDelay = true options.enableFastOpen return options } } public enum TLS { public enum Error: Swift.Error { case invalidP12 case unableToExtractIdentity case unknown } public class Server { public let p12: URL public let passphrase: String public init(p12 url: URL, passphrase: String) { self.p12 = url self.passphrase = passphrase } public var options: NWProtocolTLS.Options? { guard let data = try? Data(contentsOf: p12) else { return nil } let pkcs12Options = [kSecImportExportPassphrase: passphrase] var importItems: CFArray? let status = SecPKCS12Import(data as CFData, pkcs12Options as CFDictionary, &amp;importItems) guard status == errSecSuccess, let items = importItems as? [[String: Any]], let importItemIdentity = items.first?[kSecImportItemIdentity as String], let identity = sec_identity_create(importItemIdentity as! SecIdentity) else { return nil } let options = NWProtocolTLS.Options() sec_protocol_options_set_min_tls_protocol_version(options.securityProtocolOptions, .TLSv12) sec_protocol_options_set_max_tls_protocol_version(options.securityProtocolOptions, .TLSv13) sec_protocol_options_set_local_identity(options.securityProtocolOptions, identity) sec_protocol_options_append_tls_ciphersuite(options.securityProtocolOptions, tls_ciphersuite_t.RSA_WITH_AES_128_GCM_SHA256) return options } } public class Client { public let publicKeyHash: String private let dispatchQueue = DispatchQueue(label: "ConnectionParameters.TLS.Client.dispatchQueue") public init(publicKeyHash: String) { self.publicKeyHash = publicKeyHash } // Attempt to verify the pinned certificate. public var options: NWProtocolTLS.Options { let options = NWProtocolTLS.Options() sec_protocol_options_set_min_tls_protocol_version(options.securityProtocolOptions, .TLSv12) sec_protocol_options_set_max_tls_protocol_version(options.securityProtocolOptions, .TLSv13) sec_protocol_options_set_verify_block( options.securityProtocolOptions, verifyClosure, dispatchQueue ) return options } private func verifyClosure( secProtocolMetadata: sec_protocol_metadata_t, secTrust: sec_trust_t, secProtocolVerifyComplete: @escaping sec_protocol_verify_complete_t ) { let trust = sec_trust_copy_ref(secTrust).takeRetainedValue() guard let serverPublicKeyData = publicKey(from: trust) else { secProtocolVerifyComplete(false) return } let keyHash = cryptoKitSHA256(data: serverPublicKeyData) guard keyHash == publicKeyHash else { // Presented certificate doesn't match. secProtocolVerifyComplete(false) return } // Presented certificate matches the pinned cert. secProtocolVerifyComplete(true) } private func cryptoKitSHA256(data: Data) -&gt; String { let rsa2048Asn1Header: [UInt8] = [ 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00 ] let data = Data(rsa2048Asn1Header) + data let hash = SHA256.hash(data: data) return Data(hash).base64EncodedString() } private func publicKey(from trust: SecTrust) -&gt; Data? { guard let certificateChain = SecTrustCopyCertificateChain(trust) as? [SecCertificate], let serverCertificate = certificateChain.first else { return nil } let publicKey = SecCertificateCopyKey(serverCertificate) return SecKeyCopyExternalRepresentation(publicKey!, nil)! as Data } } } }
3
0
312
May ’25
0xBAADCA11 Occurs when VoIP Call Incoming (APNs Push Notification)
I am developing a VoIP phone application(Our Phoneapp) using APNs VoIP push. I have a question regarding a behavior I discovered during testing of this application. When performing the following operations using an iPhoneSE3 with an sXGP-NW SIM inserted, 0xBAADCA11 occurs upon receiving an APNs VoIP PUSH. Do you have any information regarding this issue? 0xBAADCA11 occurs in operation 8. However, since there were no problems in operation 4 (the app works when Wi-Fi is off), I think there is no issue with the Our Phoneapp. [Configuration of system components] [VoIP Telephone] --Call to iPhone(Phoneapp)--> [Our VoIP PBX Server] -- VoIP PUSH request --> [Apple APNs Server] -- VoIP PUSH --> [Our Phoneapp (iPhoneSE3(with sXGP SIM)] [Operations] (The issue is reproducible 100% by following oparation) iPhoneSE3: Power on (iPhoneSE3 with sXGP SIM) iPhoneSE3: Wi-Fi off, connect to the internet via SIM. VoIP Telephone: Call to Our Phoneapp iPhoneSE3: Receives VoIP PUSH and Phoneapp launches. Successfully answers the call and communication is possible. (Receives VoIP push notification from APNs via sXGP SIM) iPhoneSE3: Wi-Fi is turned ON, connect to the internet via Wi-Fi. iPhoneSE3: Task kill Our Phoneapp. VoIP Telephone: Call to Our Phoneapp iPhoneSE3: iOS does not call the push notification delegate (didReceiveIncomingPushWithPayload). As a result our Phoneapp is unable to detect the incoming call, However, an ips log with 0xBAADCA11 is output. in other words, iOS received the VoIP PUSH, but Our Phoneapp dose not call CallKit, so Our Phoneapp was terminated by iOS.
13
0
599
May ’25
Replacing Packet Filter (pf) with Content Filter for VPN Firewall Use Case
Hi, We're in the process of following Apple’s guidance on transitioning away from Packet Filter (pf) and migrating to a Network Extension-based solution that functions as a firewall. During this transition, we've encountered several limitations with the current Content Filter API and wanted to share our findings. Our VPN client relies on firewall functionality to enforce strict adherence to split tunneling rules defined via the routing table. This ensures that no traffic leaks outside the VPN tunnel, which is critical for our users for a variety of reasons. To enforce this, our product currently uses interface-scoped rules to block all non-VPN traffic outside the tunnel. Replicating this behavior with the Content Filter API (NEFilterDataProvider) appears to be infeasible today. The key limitation we've encountered is that the current Content Filter API does not expose information about the network interface associated with a flow. As a workaround, we considered using the flow’s local endpoint IP to infer the interface, but this data is not available until after returning a verdict to peek into the flow’s data—at which point the connection has already been established. This can result in connection metadata leaking outside the tunnel, which may contain sensitive information depending on the connection. What is the recommended approach for this use case? NEFilterPacketProvider? This may work, but it has a negative impact on network performance. Using a Packet Tunnel Provider and purely relying on enforceRoutes? Would this indeed ensure that no traffic can leak by targeting a specific interface or by using a second VPN extension? And more broadly—especially if no such approach is currently feasible with the existing APIs—we're interpreting TN3165 as a signal that pf should be considered deprecated and may not be available in the next major macOS release. Is that a reasonable interpretation?
5
0
296
May ’25
NWConnections in Network Extension Redirected to Proxy
We have a setup where the system uses proxy settings configured via a PAC file. We are investigating how NWConnection behaves inside a Network Extension (NETransparentProxyProvider) with a transparent proxy configuration based on this PAC file. Scenario: The browser makes a connection which the PAC file resolves as "DIRECT" (bypassing the proxy) Our Network Extension intercepts this traffic for analysis The extension creates a new connection using NWConnection to the original remote address. The issue: despite the PAC file’s "DIRECT" decision, NWConnection still respects the system proxy settings and routes the connection through the proxy. Our questions: Is it correct that NWConnection always uses the system proxy if configured ? Does setting preferNoProxies = true guarantee bypassing the system proxy? Additionally: Whitelisting IPs in the Network Extension to avoid interception is not a viable solution because IPs may correspond to multiple services, and the extension only sees IP addresses, not domains (e.g., we want to skip scanning meet.google.com traffic but still scan other Google services on the same IP range). Are there any recommended approaches or best practices to ensure that connections initiated from a Network Extension can truly bypass the proxy (for example, for specific IP ranges or domains)?
1
0
181
May ’25
Getting WIFI SSID
Greetings I'm trying to get on iPad the SSID from the wifi I'm connected to. For that, I added the wifi entitlement and I'm requesting permission to the user for Location. Once I have it, I'm using the function CNCopySupportedInterfaces to get the interfaces, but I can only receive the en0, which using the method CNCopyCurrentNetworkInfo returns nil. I also tried using the NEHotspotNetwork.fetchCurrent and the SSID keeps being nil. So right now I'm drawing a blank. Is there any way to make it work? Thanks.
1
0
584
May ’25
Mac can't find or register NE App Extension without App Sandbox entitlement
Recently, while developing a network extension on macOS, I encountered a very interesting issue. When the App Sandbox entitlement is included, the NE (Network Extension) can be called and run normally. However, when the App Sandbox is removed, with everything else remaining unchanged, an error occurs. The logs are as follows: Failed to find an app extension with identifier app.acmeVpnM.extension and extension point com.apple.networkextension.packet-tunnel: (null) Found 0 registrations for app.acmeVpnM.extension (com.apple.networkextension.packet-tunnel) If you add app sandbox, it will run normally. this is my container app entitlement this is my NE extension (without App SandBox) I want to know the reason for this. App sandbox shouldn't be mandatory. How can I make my NE run in an environment without app sandbox?
2
0
195
May ’25
Memory release problem of VPN connection object
Hello, I encountered a memory management issue while developing VPN functionality and would like to seek your advice. The specific phenomenon is as follows: Problem description: After multiple calls to the 'createTCPConnectToEndpoint' and 'create UDPSessionToEndpoint' interfaces to create connection objects, the application memory continues to grow. Even if the cancel interface is immediately called to actively release the object, the memory does not fall back. 3. Confirm that there is no other code referencing these objects, but the system does not seem to automatically reclaim memory. Attempted measures: Immediately call the cancel method after creating the object, and the memory is not reduced Use tools such as Profiler to monitor memory and confirm that objects have not been released. doubt: Is this phenomenon normal? Is there a known memory management mechanism (such as cache pooling) that causes delayed release? 2. Are there any other interfaces or methods (such as release, dispose) that need to be explicitly called? Supplementary Information: Development environment: [iOS 16, 14pm] Reproduction steps: After continuously creating connection objects, the memory grows without falling back. Could you please help confirm if there are any abnormalities and the correct memory release posture. Thank you for your support!
3
0
136
May ’25
Enhancing NEFilterPacketProvider with Process-Level Filtering
Our application currently uses NEFilterPacketProvider to filter network traffic based on Layer 4 rules (5-tuple: source IP, destination IP, source port, destination port, and protocol) on a packet-by-packet basis. We now want to extend this filtering to also consider the associated process—for example, allowing traffic from a specific source IP to a destination IP and port only if it's associated with a specific local process. That is, we’d like to make filtering decisions not just based on the 5-tuple, but also on the identity of the process either sending or receiving the traffic. We’ve looked into NEFilterSocketProvider, which does expose Layer 7 information such as process identifiers. However, it doesn’t seem to be tightly synchronized with the packet flow handled by NEFilterPacketProvider. As a result, there’s a risk that we might only get process information after the TCP handshake is complete, or before the socket is fully bound—at which point some of the 5-tuple fields (such as the local port) may still be unavailable. What we need is a way to correlate the 5-tuple with the relevant process name (either sender or receiver) at the time the first packet—e.g., a SYN packet—is about to be sent or received. Is there a recommended way to achieve this kind of early, process-aware filtering using NetworkExtension APIs?
Replies
1
Boosts
0
Views
114
Activity
Jun ’25
AdHoc IPA: "permission denied" when installing DNS Proxy NetworkExtension (all entitlements and profiles seem correct)
Hi all! I’m having trouble distributing an iOS app with a DNS Proxy NetworkExtension via AdHoc. The app and extension work perfectly with development profiles, but when I export and install the AdHoc IPA, I get a “permission denied” error when trying to install/enable the DNS Proxy extension. What I’ve done: Both the app and the DNS Proxy extension have their own App IDs in the Apple Developer portal. Both App IDs have the same App Group enabled: group.com.irakai.SafeLinkApp2. The extension App ID has the NetworkExtension capability with dns-proxy enabled. I created two AdHoc provisioning profiles (one for the app, one for the extension), both including the same devices and the correct entitlements. I assigned the correct AdHoc profiles to each target in Xcode and exported the IPA via Organizer. I install the IPA on a registered device using Apple Configurator. Entitlements (extracted from the signed binaries on device): App: <key>application-identifier</key><string>6PBG234246.com.irakai.SafeLinkApp2</string> <key>com.apple.developer.networking.networkextension</key><array> <string>packet-tunnel-provider</string> <string>dns-proxy</string> </array> <key>com.apple.developer.team-identifier</key><string>6PBG234246</string> <key>com.apple.security.application-groups</key><array> <string>group.com.irakai.SafeLinkApp2</string> </array> <key>get-task-allow</key><false/> DNSProxy Extension: <key>application-identifier</key><string>6PBG234246.com.irakai.SafeLinkApp2.DNSProxy</string> <key>com.apple.developer.networking.networkextension</key><array> <string>dns-proxy</string> </array> <key>com.apple.developer.team-identifier</key><string>6PBG234246</string> <key>com.apple.security.application-groups</key><array> <string>group.com.irakai.SafeLinkApp2</string> </array> <key>get-task-allow</key><false/> Error message (from my app’s logs): Error instalando DNS Proxy: permission denied Usuario: Roberto AppGroup: group.com.irakai.SafeLinkApp2 AppGroupPath: /private/var/mobile/Containers/Shared/AppGroup/D8AD2DED-AD96-4915-9B7A-648C9504679B Entitlements: BundleId: com.irakai.SafeLinkApp2 Debug info: Error Domain=NEDNSProxyErrorDomain Code=1 "permission denied" UserInfo={NSLocalizedDescription=permission denied} Other details: The device is included in both AdHoc profiles. The App Group is present and identical in both entitlements. The extension’s bundle identifier matches the App ID in the portal. The extension is signed with the correct AdHoc profile. I have tried rebooting the device and reinstalling the IPA. The error only occurs with AdHoc; development builds work fine. Questions: Is there anything else I should check regarding AdHoc provisioning for NetworkExtension DNS Proxy? Are there any known issues with AdHoc and NetworkExtension on recent iOS versions? Is there a way to get more detailed diagnostics from the system about why the permission is denied? Could this be a bug in iOS, or am I missing a subtle configuration step? Any help or suggestions would be greatly appreciated. Thank you!
Replies
1
Boosts
0
Views
145
Activity
Jun ’25
NEFilterDataProvider + NEFilterControlProvider not catching in-app requests
Goal : Block all outbound connections to a static list of hosts (both In-app requests and WKWebView/Safari). App & both extensions have Network Extension entitlement with content-filter-provider and filter-control-provider What’s working: Safari and WKWebView requests matching the block list are dropped. What’s broken: In-app traffic never reaches the Data Provider—those requests always succeed. Setup: • NEFilterProviderConfiguration with both Data & Control providers, filterBrowsers = true, filterSockets = true • Data Provider implements handleNewFlow for socket/browser flows • Control Provider implements handleNewFlow for browser flows • Enabled via saveToPreferences() and toggled ON in Settings
Replies
3
Boosts
1
Views
125
Activity
Jun ’25
NEFilterManager saveToPreferences fails with "permission denied" on TestFlight build
I'm working on enabling a content filter in my iOS app using NEFilterManager and NEFilterProviderConfiguration. The setup works perfectly in debug builds when running via Xcode, but fails on TestFlight builds with the following error: **Failed to save filter settings: permission denied ** **Here is my current implementation: ** (void)startContentFilter { NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults synchronize]; [[NEFilterManager sharedManager] loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (error) { NSLog(@"Failed to load filter: %@", error.localizedDescription); [self showAlertWithTitle:@"Error" message:[NSString stringWithFormat:@"Failed to load content filter: %@", error.localizedDescription]]; return; } NEFilterProviderConfiguration *filterConfig = [[NEFilterProviderConfiguration alloc] init]; filterConfig.filterSockets = YES; filterConfig.filterBrowsers = YES; NEFilterManager *manager = [NEFilterManager sharedManager]; manager.providerConfiguration = filterConfig; manager.enabled = YES; [manager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (error) { NSLog(@"Failed to save filter settings: %@", error.localizedDescription); [self showAlertWithTitle:@"Error" message:[NSString stringWithFormat:@"Failed to save filter settings: %@", error.localizedDescription]]; } else { NSLog(@"Content filter enabled successfully!"); [self showAlertWithTitle:@"Success" message:@"Content filter enabled successfully!"]; } }); }]; }); }]; } **What I've tried: ** Ensured the com.apple.developer.networking.networkextension entitlement is set in both the app and system extension. The Network extension target includes content-filter-provider. Tested only on physical devices. App works in development build, but not from TestFlight. **My questions: ** Why does saveToPreferencesWithCompletionHandler fail with “permission denied” on TestFlight? Are there special entitlements required for using NEFilterManager in production/TestFlight builds? Is MDM (Mobile Device Management) required to deploy apps using content filters? Has anyone successfully implemented NEFilterProviderConfiguration in production, and if so, how?
Replies
1
Boosts
0
Views
260
Activity
Jun ’25
Network connectivity issue observed on OS 15.4.1
Recently, we have observed that after upgrading to OS 15.4.1, some devices are experiencing network issues. We are using a Network Extension with a transparent app proxy in our product. The user encounters this issue while using our client, but the issue persists even after stopping the client app. This appears to be an OS issue. Below is the sytem logs. In the system logs, it says [C669.1 Hostname#546597df:443 failed transform (unsatisfied (No network route), flow divert agg: 2)] event: transform:children_failed @0.001s In scutil --dns, it says not reachble. DNS configuration resolver #1 flags : reach : 0x00000000 (Not Reachable) resolver #2 domain : local options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 300000 resolver #3 domain : 254.169.in-addr.arpa options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 300200 resolver #4 domain : 8.e.f.ip6.arpa options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 300400 resolver #5 domain : 9.e.f.ip6.arpa options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 300600 resolver #6 domain : a.e.f.ip6.arpa options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 300800 resolver #7 domain : b.e.f.ip6.arpa options : mdns timeout : 5 flags : reach : 0x00000000 (Not Reachable) order : 301000 We need to restart the system to recover from the issue.
Replies
10
Boosts
0
Views
356
Activity
Jun ’25
Simultaneous Use of PacketTunnelProvider and DNSProxyProvider extensions
Hi! I'm working on a solution (iOS 18) that uses Network Extensions PacketTunnelProvider and Content Filter. Currently I'm trying to integrate it with another extension – DNSProxyProvider. My goal is to process dns queries and use resolved ips and names for additional routing inside of the packet tunnel. I'm running into a major issue: whenever both VPN and DNS proxy are active simultaneously, the device completely loses internet connectivity — no traffic goes through, and DNS resolution seems to stop working entirely. I know about the mdm supervision requirement to use DNSProxyProvider and that's covered as I work with a managed device and install a DNS proxy profile, here's how its .mobileconfig file looks like: The DNS proxy itself works fine when working by itself (without VPN being turned on), as I implemented it that it successfully processes DNS packets flows while collecting information about domains etc, and everything works perfectly. Problems begin when using VPN at the same time. I'm aware that tunnel settings include dns related options that can affect this, but I haven't had much luck with tweaking them. Here's how they look right now for reference: let settings: NEPacketTunnelNetworkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "240.0.0.1") // let dnsSettings = NEDNSSettings(servers: "8.8.8.8,8.8.4.4".components(separatedBy: ",")) // dnsSettings.matchDomains = [""] // settings.dnsSettings = dnsSettings settings.proxySettings = nil /* ipv4 settings */ let ipv4Settings = NEIPv4Settings(addresses: ["240.0.0.2"], subnetMasks: ["255.255.255.0"]) ipv4Settings.includedRoutes = [NEIPv4Route.default()] settings.ipv4Settings = ipv4Settings /* MTU */ settings.mtu = 1500 return settings I've tried excluding some dns related ip routes and dns settings shenanigans but nothing. I haven't found any information that might suggest that using both of these extensions at the same time doesn't work, on the contrary, this page in the official documentation about the expected use of packet tunnel provider the expected use of packet tunnel provider, as it talks about the fact that you should not use it for interception of all of DNS traffic, as the use of DNSPRoxyProvider (or dns settings) are built for that, which in my mind, suggests that there should be no problem with using them both and just splitting the dns traffic handling to the proxy. Will be thankful for any help!
Replies
3
Boosts
0
Views
151
Activity
May ’25
TLS communication error between iPhone and iPad
We are implementing a connection between iPad and iPhone devices using LocalPushConnectivity, and have introduced SimplePushProvider into the project. We will have it switch between roles of Server and Client within a single project. ※ iPad will be Server and the iPhone will be Client. Communication between Server and Client is via TLS, with Server reading p12 file and Client setting public key. Currently, a TLS error code of "-9836" (invalid protocol version) is occurring when communicating from Client's SimplePushProvider to Server. I believe that Client is sending TLS1.3, and Server is set to accept TLS1.2 to 1.3. Therefore, I believe that the actual error is not due to TLS protocol version, but is an error that is related to security policy or TLS communication setting. Example: P12 file does not meet some requirement NWProtocolTLS.Options setting is insufficient etc... I'm not sure what the problem is, so please help. For reference, I will attach you implementation of TLS communication settings. P12 file is self-signed and was created by exporting it from Keychain Access. Test environment: iPad (OS: 16.6) iPhone (OS: 18.3.2) ConnectionOptions: TLS communication settings public enum ConnectionOptions { public enum TCP { public static var options: NWProtocolTCP.Options { let options = NWProtocolTCP.Options() options.noDelay = true options.enableFastOpen return options } } public enum TLS { public enum Error: Swift.Error { case invalidP12 case unableToExtractIdentity case unknown } public class Server { public let p12: URL public let passphrase: String public init(p12 url: URL, passphrase: String) { self.p12 = url self.passphrase = passphrase } public var options: NWProtocolTLS.Options? { guard let data = try? Data(contentsOf: p12) else { return nil } let pkcs12Options = [kSecImportExportPassphrase: passphrase] var importItems: CFArray? let status = SecPKCS12Import(data as CFData, pkcs12Options as CFDictionary, &amp;importItems) guard status == errSecSuccess, let items = importItems as? [[String: Any]], let importItemIdentity = items.first?[kSecImportItemIdentity as String], let identity = sec_identity_create(importItemIdentity as! SecIdentity) else { return nil } let options = NWProtocolTLS.Options() sec_protocol_options_set_min_tls_protocol_version(options.securityProtocolOptions, .TLSv12) sec_protocol_options_set_max_tls_protocol_version(options.securityProtocolOptions, .TLSv13) sec_protocol_options_set_local_identity(options.securityProtocolOptions, identity) sec_protocol_options_append_tls_ciphersuite(options.securityProtocolOptions, tls_ciphersuite_t.RSA_WITH_AES_128_GCM_SHA256) return options } } public class Client { public let publicKeyHash: String private let dispatchQueue = DispatchQueue(label: "ConnectionParameters.TLS.Client.dispatchQueue") public init(publicKeyHash: String) { self.publicKeyHash = publicKeyHash } // Attempt to verify the pinned certificate. public var options: NWProtocolTLS.Options { let options = NWProtocolTLS.Options() sec_protocol_options_set_min_tls_protocol_version(options.securityProtocolOptions, .TLSv12) sec_protocol_options_set_max_tls_protocol_version(options.securityProtocolOptions, .TLSv13) sec_protocol_options_set_verify_block( options.securityProtocolOptions, verifyClosure, dispatchQueue ) return options } private func verifyClosure( secProtocolMetadata: sec_protocol_metadata_t, secTrust: sec_trust_t, secProtocolVerifyComplete: @escaping sec_protocol_verify_complete_t ) { let trust = sec_trust_copy_ref(secTrust).takeRetainedValue() guard let serverPublicKeyData = publicKey(from: trust) else { secProtocolVerifyComplete(false) return } let keyHash = cryptoKitSHA256(data: serverPublicKeyData) guard keyHash == publicKeyHash else { // Presented certificate doesn't match. secProtocolVerifyComplete(false) return } // Presented certificate matches the pinned cert. secProtocolVerifyComplete(true) } private func cryptoKitSHA256(data: Data) -&gt; String { let rsa2048Asn1Header: [UInt8] = [ 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00 ] let data = Data(rsa2048Asn1Header) + data let hash = SHA256.hash(data: data) return Data(hash).base64EncodedString() } private func publicKey(from trust: SecTrust) -&gt; Data? { guard let certificateChain = SecTrustCopyCertificateChain(trust) as? [SecCertificate], let serverCertificate = certificateChain.first else { return nil } let publicKey = SecCertificateCopyKey(serverCertificate) return SecKeyCopyExternalRepresentation(publicKey!, nil)! as Data } } } }
Replies
3
Boosts
0
Views
312
Activity
May ’25
0xBAADCA11 Occurs when VoIP Call Incoming (APNs Push Notification)
I am developing a VoIP phone application(Our Phoneapp) using APNs VoIP push. I have a question regarding a behavior I discovered during testing of this application. When performing the following operations using an iPhoneSE3 with an sXGP-NW SIM inserted, 0xBAADCA11 occurs upon receiving an APNs VoIP PUSH. Do you have any information regarding this issue? 0xBAADCA11 occurs in operation 8. However, since there were no problems in operation 4 (the app works when Wi-Fi is off), I think there is no issue with the Our Phoneapp. [Configuration of system components] [VoIP Telephone] --Call to iPhone(Phoneapp)--> [Our VoIP PBX Server] -- VoIP PUSH request --> [Apple APNs Server] -- VoIP PUSH --> [Our Phoneapp (iPhoneSE3(with sXGP SIM)] [Operations] (The issue is reproducible 100% by following oparation) iPhoneSE3: Power on (iPhoneSE3 with sXGP SIM) iPhoneSE3: Wi-Fi off, connect to the internet via SIM. VoIP Telephone: Call to Our Phoneapp iPhoneSE3: Receives VoIP PUSH and Phoneapp launches. Successfully answers the call and communication is possible. (Receives VoIP push notification from APNs via sXGP SIM) iPhoneSE3: Wi-Fi is turned ON, connect to the internet via Wi-Fi. iPhoneSE3: Task kill Our Phoneapp. VoIP Telephone: Call to Our Phoneapp iPhoneSE3: iOS does not call the push notification delegate (didReceiveIncomingPushWithPayload). As a result our Phoneapp is unable to detect the incoming call, However, an ips log with 0xBAADCA11 is output. in other words, iOS received the VoIP PUSH, but Our Phoneapp dose not call CallKit, so Our Phoneapp was terminated by iOS.
Replies
13
Boosts
0
Views
599
Activity
May ’25
Replacing Packet Filter (pf) with Content Filter for VPN Firewall Use Case
Hi, We're in the process of following Apple’s guidance on transitioning away from Packet Filter (pf) and migrating to a Network Extension-based solution that functions as a firewall. During this transition, we've encountered several limitations with the current Content Filter API and wanted to share our findings. Our VPN client relies on firewall functionality to enforce strict adherence to split tunneling rules defined via the routing table. This ensures that no traffic leaks outside the VPN tunnel, which is critical for our users for a variety of reasons. To enforce this, our product currently uses interface-scoped rules to block all non-VPN traffic outside the tunnel. Replicating this behavior with the Content Filter API (NEFilterDataProvider) appears to be infeasible today. The key limitation we've encountered is that the current Content Filter API does not expose information about the network interface associated with a flow. As a workaround, we considered using the flow’s local endpoint IP to infer the interface, but this data is not available until after returning a verdict to peek into the flow’s data—at which point the connection has already been established. This can result in connection metadata leaking outside the tunnel, which may contain sensitive information depending on the connection. What is the recommended approach for this use case? NEFilterPacketProvider? This may work, but it has a negative impact on network performance. Using a Packet Tunnel Provider and purely relying on enforceRoutes? Would this indeed ensure that no traffic can leak by targeting a specific interface or by using a second VPN extension? And more broadly—especially if no such approach is currently feasible with the existing APIs—we're interpreting TN3165 as a signal that pf should be considered deprecated and may not be available in the next major macOS release. Is that a reasonable interpretation?
Replies
5
Boosts
0
Views
296
Activity
May ’25
NWConnections in Network Extension Redirected to Proxy
We have a setup where the system uses proxy settings configured via a PAC file. We are investigating how NWConnection behaves inside a Network Extension (NETransparentProxyProvider) with a transparent proxy configuration based on this PAC file. Scenario: The browser makes a connection which the PAC file resolves as "DIRECT" (bypassing the proxy) Our Network Extension intercepts this traffic for analysis The extension creates a new connection using NWConnection to the original remote address. The issue: despite the PAC file’s "DIRECT" decision, NWConnection still respects the system proxy settings and routes the connection through the proxy. Our questions: Is it correct that NWConnection always uses the system proxy if configured ? Does setting preferNoProxies = true guarantee bypassing the system proxy? Additionally: Whitelisting IPs in the Network Extension to avoid interception is not a viable solution because IPs may correspond to multiple services, and the extension only sees IP addresses, not domains (e.g., we want to skip scanning meet.google.com traffic but still scan other Google services on the same IP range). Are there any recommended approaches or best practices to ensure that connections initiated from a Network Extension can truly bypass the proxy (for example, for specific IP ranges or domains)?
Replies
1
Boosts
0
Views
181
Activity
May ’25
How to start a VPN connection with Widget ios 17?
I need to implement a VPN connection from the ios 17 widget without opening the main application. (I have seen such an implementation in other applications) How can this be implemented?
Replies
1
Boosts
0
Views
131
Activity
May ’25
Getting WIFI SSID
Greetings I'm trying to get on iPad the SSID from the wifi I'm connected to. For that, I added the wifi entitlement and I'm requesting permission to the user for Location. Once I have it, I'm using the function CNCopySupportedInterfaces to get the interfaces, but I can only receive the en0, which using the method CNCopyCurrentNetworkInfo returns nil. I also tried using the NEHotspotNetwork.fetchCurrent and the SSID keeps being nil. So right now I'm drawing a blank. Is there any way to make it work? Thanks.
Replies
1
Boosts
0
Views
584
Activity
May ’25
Mac can't find or register NE App Extension without App Sandbox entitlement
Recently, while developing a network extension on macOS, I encountered a very interesting issue. When the App Sandbox entitlement is included, the NE (Network Extension) can be called and run normally. However, when the App Sandbox is removed, with everything else remaining unchanged, an error occurs. The logs are as follows: Failed to find an app extension with identifier app.acmeVpnM.extension and extension point com.apple.networkextension.packet-tunnel: (null) Found 0 registrations for app.acmeVpnM.extension (com.apple.networkextension.packet-tunnel) If you add app sandbox, it will run normally. this is my container app entitlement this is my NE extension (without App SandBox) I want to know the reason for this. App sandbox shouldn't be mandatory. How can I make my NE run in an environment without app sandbox?
Replies
2
Boosts
0
Views
195
Activity
May ’25
Memory release problem of VPN connection object
Hello, I encountered a memory management issue while developing VPN functionality and would like to seek your advice. The specific phenomenon is as follows: Problem description: After multiple calls to the 'createTCPConnectToEndpoint' and 'create UDPSessionToEndpoint' interfaces to create connection objects, the application memory continues to grow. Even if the cancel interface is immediately called to actively release the object, the memory does not fall back. 3. Confirm that there is no other code referencing these objects, but the system does not seem to automatically reclaim memory. Attempted measures: Immediately call the cancel method after creating the object, and the memory is not reduced Use tools such as Profiler to monitor memory and confirm that objects have not been released. doubt: Is this phenomenon normal? Is there a known memory management mechanism (such as cache pooling) that causes delayed release? 2. Are there any other interfaces or methods (such as release, dispose) that need to be explicitly called? Supplementary Information: Development environment: [iOS 16, 14pm] Reproduction steps: After continuously creating connection objects, the memory grows without falling back. Could you please help confirm if there are any abnormalities and the correct memory release posture. Thank you for your support!
Replies
3
Boosts
0
Views
136
Activity
May ’25