General:
DevForums tag: Network Extension
Network Extension framework documentation
Network Extension and VPN Glossary DevForums post
Debugging a Network Extension Provider DevForums post
Exporting a Developer ID Network Extension DevForums post
Network Extension vs ad hoc techniques on macOS DevForums post
Extra-ordinary Networking DevForums post
Wi-Fi management:
Wi-Fi Fundamentals DevForums post
TN3111 iOS Wi-Fi API overview technote
How to modernize your captive network developer news post
iOS Network Signal Strength DevForums post
See also Networking Resources.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Network Extension
RSS for tagCustomize and extend the core networking features of iOS, iPad OS, and macOS using Network Extension.
Posts under Network Extension tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Title: Loss of Internet Connectivity on iOS Device When Packet Tunnel Crashes
Feedback ticket: https://feedbackassistant.apple.com/feedback/14162605
Product: iPhone 12
Version: iOS - 17.5.1
Configuration: NETunnelProviderManager Configuration
Description: We are developing an iOS VPN client and have configured our packet tunnel provider according to Apple's guidelines. The configuration is as follows:
includeAllNetworks = YES
excludeLocalNetworks = NO
enforceRoutes = NO
This setup works as expected when the VPN successfully connects. However, we encounter a blocker issue where the device loses internet connectivity if the packet tunnel crashes.
Steps to Reproduce:
Configure the NETunnelProviderManager with the above settings.
Connect the VPN, which successfully establishes a connection.
Verify that resources are accessible and internet connectivity is functional.
Packet tunnel to crash unexpectedly.Observe that the NE process (Packet Tunnel) restarts automatically, as expected and attempts to reconnect the VPN;
however, the device now lacks internet connectivity, preventing VPN reconnection.
Try accessing resources using Safari or any other internet-dependent app, resulting in an error indicating the device is not connected to the internet.
Actual Results: The device loses internet connectivity after the packet tunnel crashes and fails to regain it automatically, preventing the VPN from reconnecting.
Expected Results: The device should maintain internet connectivity or recover connectivity to allow the VPN to reconnect successfully after the packet tunnel process restarts.
Workaround - iPhone device needs a restart to regain internet connectivity .
We have observed for a few months that the Instruments tool in Xcode does not show correct memory allocation for the PacketTunnelProvider process on iOS 17. The memory allocation does not exceed 6-7 MB, which is not the case with iOS 16 or 15. Additionally, Instruments crashes the PacketTunnelProvider process after profiling for a few minutes.
Please note that I am not running Xcode in debugger mode for the PacketTunnelProvider process along with instruments, as this is a known issue that causes the PacketTunnelProvider to be killed when both Instruments and the Xcode debugger are running.
Is anyone else facing this issue and have a workaround?
Looking for a spare phone anyone may have that they aren using that I can use with no strings attached. Thanks in advance for being a blessing f:)
Hi Team,
We are using the transparent app proxy in macOS and resolving DNS queries using DNSServiceQueryRecord in the TAP process.
According to the documentation, when passing the interfaceIndex as 0, it should be queried on all interfaces, and based on IP rules, it assigns the query to that particular interface.
However, when we pass 0, it does not query any of the interfaces. We need to provide the specific interface index.
I created a content filter app in iOS (swift). The app lets me toggle the content filter ON or OFF. When the content filter is on, it restricts access to one particular url.
This works as intended; however, I would like to generate a log that shows the url from each inspected flow (I'm using NEFilterFlow to inspect the url from each webkit flow). Ideally, I'd like the url, the verdict, and the verdict timestamp appended to the log each time a flow passes through the content filter for a decision.
I cannot figure out how to capture any data from the flow. I'm even trying to use the NEFilterReport class, but I can't seem to capture any of the data in the report. Can the url even be extracted from a NEFilterReport? I assume it can, since it's part of the flow.
I understand that FilterDataProvider can only communicate with FilterControlProvider (on a very limited basis). However, it is my understanding that FilterControlProvider can communicate with the main target.
So how can I send the url from FilterDataProvider over to FilterControlProvider, and then onward to the main target to print to the console?
I'm starting to read about IPCConnection. Hopefully that is the answer to my question and I will get there in the coming days. If not, please help. There is very limited information out there on the network extension framework and content filtering.
Hello,
I would like to ask how to connect using OpenVPN in such a way that the connection appears in System Settings > VPN, similar to how it does with NordVPN.
Thank you
After a week of testing iOS 18. iPhone XS keeps randomly up and down cellular network which shows low signal /no service/ hig signal after I use it for a few minutes. second bugs is keyboard switching , sometimes don’t work auto predictive and auto capitalisation in keyboard. Reported this issue through feedback assistant. Please fix this bug in next iOS 18 beta.
Hi. I'm trying to run tunnel_server from https://github.com/networkextension/SimpleTunnel sample on macOS Sonoma. Delegate's method netServiceWillPublish is called, but neither netServiceDidPublish nor netService(didNotPublish) are not.
Firewall is enabled, incoming connections to the tunnel_server app are allowed.
The app is not sandboxed and signed to run locally.
When running the app, Allow Connections prompt pops up which is allowed.
We have found a VPN that does not work while our TPP is running, and I have a hypothesis why, and it does not make any sense.
It only fails when our TPP asks for UDP flows.
Their VPN claims to fail at a DNS query, but it's getting EPIPE (this is Twingate for the curious). Looking at all the logs I can on the system, including dtruss and dtrace, I see that it does a sendto, and gets that errno. I can't, of course, determine more.
By adding more logging, I can see that their VPN tunnel provider tries to open up a UDP flow to 8.8.8.8 port 53. First red flag: I did not think we were supposed to get DNS queries -- my guess is that only means for apps that use the system DNS libraries, implying (to me) that this VPN has their own DNS code.
We look at the app name, and decide we don't care for it -- handleNewUDPFlow(_:initialEndpoint:) returns false/NO.
I see this in the system logs:
2024-06-26 11:06:56.342680+0100 0x300c839 Default 0x0 40823 0 ${us}.Redirector: (NetworkExtension) [com.apple.networkextension:] [Extension ${us}]: provider rejected new flow UDP ${them}.macos.tunnelprovider[{length = 20, bytes = 0xca1b405e014154c2e38e20159d033f9b2d3eea18}] local port 0 interface en0(bound)
which is all correct. But then the very next log entry is
2024-06-26 11:06:56.342717+0100 0x300cc14 Info 0x0 0 0 kernel: (399482302): received connect result 61
which, there you go, ECONNREFUSED which will be turned into EPIPE by sendto. (ETA: No, that's not what happens at all. I see other port 53 queries in my logs, and they follow the same, er, flow -- TPP refuses them, next log entry for the flow by the system is result 61.)
There is no traffic to 8.8.8.8 over any of the interfaces.
I have tried using a NENetworkRule that _excludes` port 53, but it does not allow that at all.
I am very deeply confused by all of this, to the point I'm not quite sure how to begin to articulate a request for help. If anyone has any thoughts, comments, questions, commiserative howls of agony, I'd appreciate it.
I was trying to check the documentation for handleNewUDPFlow over at https://developer.apple.com/documentation/networkextension/neappproxyprovider/3192017-handlenewudpflow and... it says it's deprecated on everything. Retroactively.
Since the release of macOS 14.0, we have encountered issues with the Content Filtering MDM Payload. This problem is unusual but can be resolved by restarting the system.
Prerequisites:
macOS 14 or higher
Any Mac with a Silicon (ARM) processor
Restrictions Payload and Parental Content Filtering Payload must be installed on the device, either manually or through any MDM service
Issue Details:
When the Parental Content Filtering Payload is removed after installation, it causes internet issues, and browsers display "The site can't be reached".
This affects applications as well, with Safari being the only application that continues to work.
The issue can be resolved by either re-adding the Content Filtering Payload or restarting the Mac.
Links:
Restriction Payload: https://drive.google.com/file/d/1buwLFgbjTRXij9ZSv1QrDeRnWbFfKNtq/view?usp=drive_link
Content Filtering Payload: https://drive.google.com/file/d/1eAJiBg4N__dML65MRDH7hYCocuTqOCcu/view?usp=drive_link
System Logs: https://drive.google.com/drive/folders/1hKKNAoMn_4x1CqMTxz1bPrUucCbftjO9?usp=drive_link
Screen Recording: https://drive.google.com/file/d/1uS8CJqe9p9DG9XzhUnIsY35eme4Dxs60/view?usp=drive_link
I saw this sentence in the documentation at https://developer.apple.com/documentation/bundleresources/information_property_list/nsrequirescertificatetransparency: 'Don’t use this key. The current system enforces this behavior, and new certificates can’t meet the requirement on older systems.'
I understand that new systems will enable CT (Certificate Transparency) verification by default. However, I created a new demo to verify this on an iOS 13 device, and CT verification was not actually enabled.
Hello, Apple community and support team.
We would like to get your input on a recent rejection we got in our latest app submission.
The app uses public APIs in an unapproved manner, which does not comply with guideline 2.5.1.
Specifically, your app utilizes the NEVPNManager APIs for non-approved uses.
Since there is no accurate way of predicting how an API may be modified and what effects those modifications may have, unapproved uses of public APIs in apps is not allowed.
We are currently uncertain about the specific ways in which the NEVPNManager APIs are being misused in our app, as we have diligently followed the instructions documented on Apple’s website.
Our app uses a Packet Tunnel Provider and configures it to use a local proxy server for reducing network traffic, especially for video streaming services. We initially don't send any of the received traffic to a VPN server and instead, traffic is only handled by the Proxy Server.
We are committed to ensuring our app complies with all guidelines and appreciate your assistance in resolving this matter. Your guidance will be invaluable in helping us make the necessary adjustments.
Thank you for your support.
Forward posting from the Swift Forums.
Within my iOS project (thesis project) I have set up a MITM server that is being sent data from a Packet Tunnel Provider. I am currently seeing that all IPv6 requests aren't able to have their IP address resolved when passed to Swift NIO that uses the default system DNS resolver.
On the Packet Tunnel Provider, I have set it to use the DNS's 8.8.8.8 and 8.8.4.4 that are also the system defaults. I have also attempted to use my routers DNS routing to no avail. Both v4 and v6 traffic are proxied to the MITM server that uses Swift NIO, with v4 traffic successfully being processed on ingress and egress as intended. IPv6 traffic is failing to resolve with the following error:
dev.thesis.apps.LocalProxyServer.ConnectHandler : [LocalPacketTunnelProvider] Connect failed: NIOConnectionError(host: "ipv6.mythic-beasts.com", port: 443, dnsAError: Optional(NIOCore.SocketAddressError.unknown(host: "ipv6.mythic-beasts.com", port: 443)), dnsAAAAError: Optional(NIOCore.SocketAddressError.unknown(host: "ipv6.mythic-beasts.com", port: 443)), connectionErrors: [])
ipv6.mythic-beasts.com for the purposes of this is just a test website I am using that only has a AAAA record associated with it:
When not connected to the Packet Tunnel Provider, the website is successfully resolved and can be viewed within the browser - so I have narrowed it down to either the server or tunnel configuration.
The server uses the GetaddrinfoResolver, that utilises the iOS's system default DNS resolver. This should conform to necessary RFC.
Could anyone provide me with a reason why this could be happening and if possible a link to a resource that could assist with remediating the issue? I'll be the first to admit this isn't my forte so would appreciate some support if possible.
I am aware that this isn't an expected use cases for Network Extension packet tunnel providers (as per TN3120). I'm just concerned as IPv4 DNS records are resolving but IPv6 aren't so wondering if this is a wider issue. would expect the system DNS resolver to still work as intended though.
Hi! I have been working on one idea for a while but can't figure out the proper way to do that. My app includes Content Filter and DNSProxy providers for filtering logic. And for the NEFilterSocketFlow everything works well, because the connection is first handled from DNSProxy and if it's blocked, NEFilterDataProvider returns datagrams that I wrote from DNSProxy (I return nxdomain). However, for NEFilterBrowserFlow it doesn't work, because webkit generated flows are for some reason intercepted by Content Filter first and at the time when the flow is checked for rules, there're none yet as DNSProxy didn't handle connection yet.
So the app returns the following behaviour:
In case the requested domain is not filtered by DNSProxy, the user is able to visit requested page, but if it's filtered, the flow just freezes and the page will never load for user. But I wanted to add proper handling and display block page.
In case I am using some third-party apps for testing like ICS Dig, filtered domains return nxdomain properly.
Not sure if there's a way to achieve desired result, but would be very grateful for any suggestions
Hey,
I'm currently developing an app that uses NEHotspotConfigurationManager to connect to and disconnect from a WiFi network based on user actions. I'm using the following code to connect and disconnect:
Connect
let configuration = NEHotspotConfiguration(ssid: ssid, passphrase: password, isWEP: false)
configuration.joinOnce = true
NEHotspotConfigurationManager.shared.apply(configuration) { (error) in
if let error = error {
print("Error connecting to WiFi network: \(error.localizedDescription)")
} else {
self.lastSSID = ssid
}
}
Disconnect
NEHotspotConfigurationManager.shared.removeConfiguration(forSSID: self.lastSSID)
The issue I'm encountering is that the app successfully connects to the WiFi network and disconnects properly the first time. However, after connecting again, the second disconnect attempt fails to disconnect from the WiFi network.
I found a similar bug report from 2020 that mentioned this issue. The suggested workaround involved setting joinOnce = false, which is not suitable for my app's requirements.
Our app uses NEVPNManager with IPsec to create VPN. Full tunnel is working fine both with NEVPNManager API and profile created using Apple Configurator.
Now, we are trying to create split tunnel using the same. Apple Configurator created profile is working when DNS Supplemental Match domains is set to empty string. But we couldn't find the equivalent to the DNS Supplemental Match domains in the NEVPNManager API. In NEVPNManager config, all DNS is routing to the default route instead of VPN.
Can you please help us on this?
I was developing an electron based app, and I want to embed a system extension in it, everything works fine with SIP disabled.
But for normal cases, I found out:
Notarization require hardened runtime enabled.
The container is an electron based app, which has JIT related feature, so it requires hardened runtime relaxation entitlements (some exception)
But System extension disallow these entitlements, this error message is captured from the log system: Hardened Runtime relaxation entitlements disallowed on System Extensions
So does this mean we can't embed a system extension in an Electron-based app?
OS: MacOS 14.3 (23D56)
I have PacketTunnelProvider VPN running with MTU on utun interface as 1300.
% ifconfig utun4
utun4: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1300
options=6460<TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>
inet 192.166.54.1 --> 192.166.54.1 netmask 0xffffff00
nd6 options=201<PERFORMNUD,DAD>
When I am sending Jumbo size packets using ICMP and it is working fine till 4068 bytes packet size, after that ICMP responses are not accepted by the utun interface.
Working till 4068 packets:
% ping 13.71.68.85 -s 4068
PING 13.71.68.85 (13.71.68.85): 4068 data bytes
4076 bytes from 13.71.68.85: icmp_seq=0 ttl=56 time=46.040 ms
4076 bytes from 13.71.68.85: icmp_seq=1 ttl=56 time=25.353 ms
Not Working after sending 4069 packets:
% ping 13.71.68.85 -s 4069
PING 13.71.68.85 (13.71.68.85): 4069 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
In System logs I could see below errors:
% log stream | grep utun4
2024-06-19 17:22:34.666286+0530 0x7ee9e2 Error 0x0 0 0 kernel: utun_netif_sync_rx utun4: legacy packet length 4097 > 4096
2024-06-19 17:22:35.637723+0530 0x7ee9e2 Error 0x0 0 0 kernel: utun_netif_sync_rx utun4: legacy packet length 4097 > 4096
Note: Same works fine on en0 interface when packet is not routed via utun interface.
Working till 8184 packets on en0 interface:
% ping 13.71.68.85 -s 8184
PING 13.71.68.85 (13.71.68.85): 8184 data bytes
8192 bytes from 13.71.68.85: icmp_seq=0 ttl=51 time=198.928 ms
8192 bytes from 13.71.68.85: icmp_seq=1 ttl=51 time=46.139 ms
% ping 13.71.68.85 -s 8185
PING 13.71.68.85 (13.71.68.85): 8185 data bytes
ping: sendto: Message too long
ping: sendto: Message too long
Does this mean, on utun interface we do not support packet inception of more than 4096 size?
We're encountering an issue with our Network Extension (utilizing NEPacketTunnelProvider and NETransparentProxy) on macOS 14.5 (23F79).
On some systems, the VPN fails to automatically start after a reboot despite calling startVPNTunnel(). There are no error messages.
Our code attempts to start the tunnel:
.......
do {
try manager.connection.startVPNTunnel()
Logger.default("Started tunnel successfully")
} catch {
Logger.error("Failed to launch tunnel")
}
......
System log analysis reveals the tunnel stopping due to userLogout (NEProviderStopReason(rawValue: 12)) during reboot.
However, the Transparent Proxy stops due to userInitiated (NEProviderStopReason(rawValue: 1)) for the same reboot.
We need to understand:
Why the VPNTunnel isn't starting automatically.
Why the userLogout reason is triggered during reboot.
Additional Context:
We have manually started the VPN from System Settings before reboot.