I've implemented a custom VPN system extension for macOS, utilizing Packet Tunnel Provider.
One of the users reported a problem: he was connected to the VPN, and then his Mac entered sleep mode. Upon waking, the VPN is supposed to connect automatically (because of the on-demand rules).
The VPN's status changed to 'connecting', but it remained stuck in this status.
From my extension logs, I can see that the 'startTunnelWithOption()' function was called 2 minutes after the user clicked the 'connect' button.
From the system logs, I noticed some 'suspicious' logs, but I can't be sure if they are related to the problem. Some of them are:
kernel: (Sandbox) Sandbox: nesessionmanager(562) deny(1) system-fsctl (_IO "h" 47)
entitlement com.apple.developer.endpoint-security.client not present or not true (I don't need this entitlement at the extension)
nesessionmanager: [com.apple.networkextension:] NESMVPNSession[Primary Tunnel:XXXXXX(null)]: Skip a start command from YYYYY:session in state connecting
NetworkExtension.com.***: RunningBoard doesn't recognize submitted process - treating as a anonymous process
sysextd: activateDecision found existing entry of same version: state activated_enabled, ID FAE...
Are any of the logs related to the above problem? How can I debug such issues? What info should I get from the user?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I've implemented a custom system extension VPN for macOS using Packet Tunnel Provider. The VPN is configured with on-demand, and a rule to always connect whenever there's traffic:
onDemandRules = [NEOnDemandRuleConnect()]
As expected, if the VPN isn't active, all traffic gets blocked until it is ready.
Not expected: In the following scenario, there is some 'traffic leak':
Use only WiFi (not wired cable)
Connect the VPN
Disable the WiFi and wait for the VPN to disconnect
Enable the WiFi
Some packets are routed outside the VPN, and aren't being blocked
Some moments after, all traffic will be blocked, and the VPN will start the 'connecting' process.
Is the above scenario a 'known' issue? Can it be a race condition in the OS, where some packets can be sent after the network is brought back before the VPN process starts? Is there any way to fix this problem?
P.S:
I'm not using flags such as 'capture all network'
I've implemented a VPN app with Packet Tunnel Provider for MacOS and iOS.I have two questions regarding the Extension's sleep/wake functions:1. If the VPN configuration is set with disconnectOnSleep = false, and at the extension I'm sending keep-alives every X seconds, What would happen when the device enters sleep mode? Will it keep sending keep-alive (because the VPN is configured with disconnectOnSleep=false) ?2. If the VPN configuration is set with disconnectOnSleep = true, and also isOnDemandEnabled = true. When the device enters sleep mode, do I need to disconnect the VPN myself? Or the OS would take care of it? And if I should disconnect it myself, the on-demand won't try to turn it on again (because the on-demand) ?
I've implemented a custom system extension VPN for macOS using Packet Tunnel Provider.
The VPN is configured with on-demand, and a rule to always connect whenever there's traffic:
onDemandRules = [NEOnDemandRuleConnect()]
As for the tunnel's settings (at the Packet Tunnel Provider), I've configured a split tunnel, so some routes are excluded from the tunnel.
Now I have the following scenario:
The VPN is connected
The Mac enters sleep
The sleep() function is called (at my Packet Tunnel Provider)
The Mac briefly awakes to check emails/push notifications/etc. This traffic is excluded from the tunnel.
What is the expected behavior here? Should the wake function be called because of the on-demand rule? Or should the VPN remain asleep because this traffic is excluded from the tunnel?
I've implemented a custom system extension VPN for macOS, using Packet Tunnel Provider.
I have a XPC connection, from the containing app to the (system) extension.
What is the expected behavior after the Mac's sleep/wake?
Will the same XPC remain valid? Should I start a new connection?
I've implemented a custom system extension VPN for macOS, using a Packet Tunnel Provider.
I saw something suspicious on macOS 15.2.0: When I disconnected my VPN, the UTUN was not being cleared.
This results in a lot of UTUNs when the user connects and disconnects multiple times.
utun77: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
utun78: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
This happens only on macOS 15.2. I tried the same app on older versions (15.0, 15.1.x), and it didn't reproduce.
Can those 'dirty' UTUNs cause a networking problem?
Since it happens only on macOS 15.2, is there a bug in this OS version?
How can I check if something in my code causes this behavior? How can I 'fix' it or force clean the 'dirty' UTUNs?
I've implemented a custom VPN for macOS (system extension, Packet Tunnel Provider, Developer ID). My tunneling logic uses BSD sockets.
My VPN is configured with on-demand and should always connect when there's traffic:
targetManager?.isOnDemandEnabled = true
targetManager?.onDemandRules = [NEOnDemandRuleConnect()]
I have encountered some issues when the device enters sleep (or waking up from sleep). I've tried two scenarios.
Scenario 1:
protocolConfiguration?.disconnectOnSleep = true
With this flag set, the OS will disconnect the VPN just before entering to sleep. However, there were cases when the OS disconnected the VPN but immediately restarted it - probably because of how I defined the on-demand rules. This resulted in the VPN disconnection, then trying to reconnect, and then the Mac entered sleep.
When the Mac woke up, the VPN didn't work well.
Is there a way to avoid waking up, just before the Mac enters sleep?
Scenario 2:
protocolConfiguration?.disconnectOnSleep = false
Disconnect on sleep is unset, and I've implemented the sleep/wake functions at the provider.
With this configuration, the OS won't disconnect the VPN, so even in sleep, the extension should stay 'alive,' so it won't have the problem from (1).
But in this case, I had other problems:
On sleep, I'm disconnecting the tunnel. But sometimes, on wake(), all my network calls fail. Are the interfaces still down? How can I detect this case from the system extension?
Is it possible that the OS would call sleep and then quickly call wake?
Is it possible that after sleep, the OS would call the startTunnelWithOptions() function?
Is it possible to restart the extension from a clean state right from the wake() function?
I've implemented a custom system extension VPN for macOS using a Packet Tunnel Provider.
At the Protocol Configuration, the 'includeAllNetworks' flag is unset.
At the provider, I included all routes (IPv4 default route).
What is the expected behavior for LAN traffic? Should the LAN traffic go via the VPN?
By 'LAN traffic', I'm referring to local hosts, ssh, printer access, etc.
I've implemented a custom VPN for iOS using a Packet Tunnel Provider.
I have the entitlement for 'com.apple.managed.vpn.shared'.
One option to connect is to use a certificate - this can be done by distributing a VPN payload with the required certificate for the connection.
My question is if there's any way to distribute multiple certificates and that I'll be able to read them on my iOS app.
For example, on the Certificates payload, I can add multiple certificates, but on the VPN payload, I can choose only one of them. So, can my app read more than one certificate?
Is it possible to have both 'includeAllNetworks' and split-tunnel simultaneously?
I want to enable a split tunnel so only some of the traffic will reach the tunnel, but at the same time, to make sure that the above traffic will always reach the tunnel - even if it's coming from some low-level networking API or even if the traffic started before creating the tunnel.
Setting the 'includeAllNetworks' flag will help with the above cases, but then I'll get all the traffic via the tunnel without consideration in the split tunnel configuration.
(Details: System-extension, PacketTunnelProvider)
I downloaded the ES sys-ext sample project. I built the 'NOTIFY' extension, and I was able to install it. However, it doesn't seem to work (or - it doesn't report anything).
This is what I did:
I download the project
I renamed the bundle IDs
I disabled SIP
I tried both signing options - let 'Xcode automatically manage signing', and I also tried to use my 'Developer ID'
I moved the app to the Applications folder
I grant the 'Full Disk Access' permission to the extension
I verified that the extension is running
I did not get the needed entitlement yet, but since SIP is disabled, I don't think it's a problem
I did get the message 'Successfully installed the extension ✅'
At the terminal, I tried to capture relevant logs:
log stream --style compact --predicate 'sender == "myBundleId"'
(I tried it with the app bundleID, and with the extension's bundleId)
And yet, 'ps' triggers no logs.
*At the Console, I get those messages:
"Unsatisfied entitlements: com.apple.developer.endpoint-security.client"
Disallowing: myBundleId
amfid: Restricted entitlements not validated, bailing out. Error: Error Domain=AppleMobileFileIntegrityError Code=-413 "No matching profile found" UserInfo={NSURL=, unsatisfiedEntitlements=, NSLocalizedDescription=No matching profile found}
Any idea where's the problem at?
At my app I have a SecKey which I want to sign some Data with it, and at my sever I need to do the verification process, but this time with openSSL.
I didn't find any common key or any steps to achieve this between Apple Security framework and OpenSSL.
For example, I've tried the following:
Signing (Apple Security):
let signedStrCFData = SecKeyCreateSignature(key, .rsaSignatureRaw, plaintextData, &error)
Verifying (OpenSSL):
ret = RSAverify(NIDrsaSignature, (const unsigned char *)challenge, (unsigned int)strlen(challenge), challengeenc,
challengeenc_size, rsa); Which key to choose is not really important to me (as long as it's a reasonable signing key), so I tried multiple types of keys, but I wasn't able to do it.
Any idea what I'm missing here?
[Network Extension, Packet Tunnel Provider, iOS, split tunnel]
I've implemented a custom network extension app for iOS using Packet Tunnel Provider.
A customer enabled a split tunnel, set the tunnel's DNS servers, and added relevant 'search domains' and 'match domains'.
Then, he reported an error related to DNS, specifically, DNS Over HTTPS. He noticed that DNS queries were sent over HTTPS.
He also has the corresponding app for Mac (Packet Tunnel Provider, macOS, system extension), and everything works fine with the same DNS configuration, and the DNS queries were sent as a 'clear text', not DoH.
Is DoH the default behavior on iOS? Is it the default on macOS?
Can we somehow change this behavior?
Are DoH queries reach the tunnel as plain DNS queries?
Now that the flag includeAllNetworks is working as expected (see https://developer.apple.com/forums/thread/722156), I tried to set it and also the ExcludeLocalNetworks flag.
As described in the documentation, I'm able to use AirPlay and AirDrop while being connected, but what I was hoping for was to exclude from the tunnel all the LAN traffic, including pings to local hosts, ssh, printer access, etc.
Isn't it what ExcludeLocalNetworks should accomplish? If not, how can I exclude LAN traffic from a full tunnel (i.e. not a split tunnel)?
[Custom VPN, macOS, Packet Tunnel Provider, system extension]
The feature of phased release is very useful for our company, but a big minus for us is that the 'Percentage of Users' starts very slow, and at the last two days it's go up very fast.
For now what we can do is to start the phased release, pause it after 50% of users get the new version, and after a weak - resume the release.
I know it's not the purpose of the pause/resume but we want a better control at the percentages/days of the phase release.
Is it possible to change those somehow? Change the percentages per day/ change number of days for the phased release?