Unable to embed and bring up PacketTunnelProvider from command-line-tool application

Hi,


I have an existing macOs application for remote-access use-case that uses NKEs.

The application consists of two processes, a user facing part and a (daemon) background process (maintained as two different Xcode projects).

The daemon has the logic of my tunnelling protocol, configures the virtual interface created using NKEs and is responsible for handling the packets.


As the NKEs are getting deprecated, I plan on modifying my app to use PacketTunnelProvider NetworkExtension.


My containing app is the daemon.

I tried adding PacketTunnelProvider target to the project and made sure the right entitlements are in place, configured the TunnelProviderManager and tried to bringup the PacketTunnelProvider.

But it looks like my NETunnelProviderManager is failing to initialise without any sort of error reported on console.


I had tried bringing up PacketTunnelProvider using a single-view application as the containing app and it worked flawlessly with that.


When I use a command-line-tool as the containing application, the extension is not brought up. (Not able to embed the extension with the app target)


Is there an exception on adding a NetworkExtension to a command-line-tool? Can we not embed a NetworkExtension within a command-line-tool?


It also came to my notice that I cannot add a provisioning profile to my command-line-tool app target but it can be added to the single-view application.

Can someone please let me know if I am missing something here?


Thank You.

Accepted Reply

I want to start by addressing the Single View application working flawlessly. When you installed your extension for the first time using the Single View app you were most likely prompted to allow permissions for the NetworkExtension and then configure a network profile for your VPN. This is done with visual prompts that the user needs to accept to allow the NetworkExtension to run. I am suspecting this may be one of the issues involved here; the user is not receiving these prompts to allow the NetworkExtension to proceed with installation from a daemon or command line tool.


There are also limitations on what you can support from a daemon and command line tool compared to a full app. You could investigate packaging your daemon code in an app-like structure to see if that has any impact on the situation. Quinn wrote an excellent post on this from the standpoint of Endpoint Security, called Packaging a Daemon with a Provisioning Profile. There is some great info here on how to take your daemon code and move it into an app target.


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

Replies

I want to start by addressing the Single View application working flawlessly. When you installed your extension for the first time using the Single View app you were most likely prompted to allow permissions for the NetworkExtension and then configure a network profile for your VPN. This is done with visual prompts that the user needs to accept to allow the NetworkExtension to run. I am suspecting this may be one of the issues involved here; the user is not receiving these prompts to allow the NetworkExtension to proceed with installation from a daemon or command line tool.


There are also limitations on what you can support from a daemon and command line tool compared to a full app. You could investigate packaging your daemon code in an app-like structure to see if that has any impact on the situation. Quinn wrote an excellent post on this from the standpoint of Endpoint Security, called Packaging a Daemon with a Provisioning Profile. There is some great info here on how to take your daemon code and move it into an app target.


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

Thank you for the reply Matt.
Using the solution provided by you and Quinn, I can now successfully package a Daemon with a Provisioning Profile.

A process without a UI component is not sufficient for NetworkExtension bringup. However I found out that this can be achieved by running the app in background using open command with -gj flags.
Thank you.