We are developing an app with Per-App VPN runs on iOS. This container app is designed for our some specific apps to connect network through VPN at certain times, while all the other apps not.
We want these specific apps connect network normally before VPN is turned on, after the container app and configuration profile are installed. And these specific apps connect network through VPN once VPN is manually turned on in the container app.
I have some questions can not find answers.
I've added NETestAppMapping key to Info.plist of my container app in Development. And Bundle Identifiers of those specific apps are added to NETestAppMapping. After building the container app and installing configuration profile by Apple Configurator 2, I found those specific apps can not connect to Internet until I turned on VPN in the container app. Is that normal?
NETestAppMapping is a way to config those specific apps in Development. I wonder the production mechanism for specifying app mappings.
Moreover, something really weird once happened. I deleted the configuration profile from iPhone, and NETestAppMapping from the container app. Then I turned on VPN in the container app by normal way. After done this, I found the function we want is implemented.
Thank you very much.
An app that is associated with a Per-App VPN, will only have its traffic routed through the Per-App VPN. If On-Demand is disabled, and the VPN is turned off, then no traffic will flow from the app.
As such, I see two ways to achieve having the apps route through the Per-App VPN only some of the time:
Implement the VPN using NEPacketTunnelProvider in such a way the VPN always launches On-Demand and continues to be 'active', but the VPN app can be used to toggle whether the NEPacketTunnelProvider actually routes the traffic through the VPN or whether it simply acts as a TCP/UDP forwarder.
Utilise an MDM and its SDK (assuming support) to associate and disassociate your applications from the Per-App VPN when a toggle is switched in the VPN app. Note that this will likely be clunky, with a time delay and may cause your app to be killed if it is running. I won't recommend this approach.
It's worth noting that NETestAppMapping only works for development builds and won't work for distribution builds (e.g. Enterprise (In-House) or App Store). You will need to use an MDM to utilise a Per-App VPN.
For an example of using an NEPacketTunnelProvider with packet forwarding, I would take a look at this paper: Does your phone spy on you? by Severin Amrein.
Related
I want to create secure communication channel between my RPI and iOS 11 mobile application in local environment. My RPI is running a python API code and my iOS mobile app creates different API calls to the RPI. For secure connection I’m using certificates signed by my private Certificate Authority. All certificates and signing requests were created using “OpenSSL” Linux command line tool.
As I mentioned earlier, devices are communicating in local network over default .local domain which is configured by avahi service on linux device, and bonjour (zeroconf) service on iOS device. In the beginning I had some issues with loading certificates in mobile app and after I’ve done some research I’ve found that I must have “NSAllowsLocalNetworking” flag enabled inside xCode IDE. With the “NS” flag enabled SSL certificate pinning was successful and secure communication was established.
What I don’t know and I would like to find out are two things:
Is there any restriction from Apple side with publishing application to the app store when the “NSAllowsLocalNetworking” flag was enabled?
Besides using certificates, what other options do I have in terms of secure communication between iOS mobile app and RPI?
You are using the correct approach. Using a self signed certificate with certificate pinning is the right approach will allow you to trust the connection, as long as you have protected the key used to generate the cert.
In fact, it is recommended by Apple:
Note: Although ATS is unenforced for connection to local hosts, Apple strongly recommends using Transport Layer Security (TLS) for any
local connection, along with the use of a self-signed certificate to
validate the local IP address.
Apple created the NSAllowsLocalNetworking specifically for scenarios such as this. As of current Apple documentation, use of this flag will not trigger the need to provide Apple with justification for disabling ATS. One additional thing to note is that this flag is only supported on iOS10 and later.
If you need to support older versions, Apple offers a way to do this to support older versions. Basically, you set both the NSAllowsArbitraryLoads flag to true, as well as the NSAllowsLocalNetworking flag. Basically, iOS9 only understand, so iOS 9 devices disable ATS altogether. iOS 10+ understands, both NSAllowsArbitraryLoads and NSAllowsLocalNetworking, so it has logic built in to let NSAllowsLocalNetworking override NSAllowsArbitraryLoads, and leaves ATS protections on for the rest of the app, while allowing local network connections to go through. Apple covers that on their documentation page under the header "Supporting Older Operating Systems".
Does iOS Per-App VPN require use of MDM?
Is there any other way in which this feature can be utilized?
So far my finding has been that it can only be used with MDM. See Routing Network Data to the VPN Section
Thanks!
Yes, technically it is possible to configure an app to use a Per-App VPN without an MDM. However, this is purely for development of your own VPN plugin and will not work for apps pushed to the app store.
Testing Per-App VPN
As described above, an MDM server is required to configure Per-App VPN
for VPN apps distributed via the App Store. To make testing Per-App
VPN easier, it is possible to configure Per-App VPN without an MDM
server during development by using the NETestAppMapping Info.plist
key.
The NETestAppMapping Info.plist key can only be used to create app
rules in apps that are signed with a Development provisioning profile.
In apps that are signed with Distribution provisioning profiles the
NETestAppMapping Info.plist key has no effect.
Source: https://developer.apple.com/documentation/networkextension/netunnelprovidermanager
I have found following network requirements for OTA deployment:
https://help.apple.com/deployment/ios/#/apda0e3426d7
Network configuration requirements
If the devices are connected to a closed internal network, you should let iOS devices access the following:
ax.init.itunes.apple.com: The device obtains the current file-size limit for downloading apps over the cellular network. If this website isn’t reachable, installation may fail.
ocsp.apple.com: The device contacts this website to check the status of the distribution certificate used to sign the provisioning profile.
I want to ask is it possible to deploy through intranet without access above website? Any work around?
Thanks.
We have OTA setup in our intranet. Works fine. Only requirement is that the device installing the app should be connected to the VPN or in the intranet.
I am trying to develop an enterprise environment where the specified app in the app store gets installed in all the iOS devices connected to the company infrastructure, which has a windows based AD to verify the users.
I went through various materials, and I found over the air profile delivery and few other methods like MDM to push the configuration. But it seems only the configuration can be pushed using these features.
In Apple Configurator and iPhone Configuration Utility, the devices should be connected to the computer physically. I would like to install the app in all the company-owened devices (around 1000 devices) without asking any permission from the user. Is there any way to do this?
You can't take over people's devices without their permission. Nor can you stealth-install an app. You can use MDM to register devices on which you can do this, but they need to be registered first. Apple is currently making MDM features more powerful for the Enterprise environment. As an Enterprise developer, you don't have to use the app store for your app - you can distribute it over your own web server. So even if you go the MDM route, you'll have to register those 1000 devices first. Once you do that, you have a lot more control.
Is there any way to restrict internet connection for any applications but currently running (my app)?
May be some configuration profile to make only one application running, or another way?
As far as I know this is only possible possible with the Enterprise Developer Program. There you can push profiles on the devices. These profiles can contain all kinds of restrictions.