I have setup a Network Extension as Per-App NEAppProxyProviderManager. I use a .mobileconfig setup (See bellow)
I do get Safari traffic but not other Apps traffic, at this moment I'm trying Chrome (com.google.Chrome)
I do get Safari traffic in the
I want extend the proxy to get Chrome traffic as well. For that I create the section "AppLayerVPNMapping" with the bundle IDs and DesignatedRequirement of Chrome.
The interesting thing is that I get the UDP traffic redirected to
It is known that if rejected, Chrome passes to use TCP instead of UDP, I have tested it with another type of Proxy (transparent Proxy).
The result is that the TCP flow is not redirected to the NE and Chrome does not navigate.
Chrome is based in many processes so I have added the "helper" it uses to the list of apps.
I have used "NETestAppMapping" in info.plist but doesn't help.
This is the mobileconfig I'm using.
Anyone has succeeded to get complex apps traffic ?
Thanks !
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-...">
<plist version="1">
<dict>
<key>PayloadUUID</key>
<string>DF2B6E99-2857-474B-B98A-3FF2E71E90C6</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadOrganization</key>
<string>myorg</string>
<key>PayloadIdentifier</key>
<string>DF2B6E99-2857-474B-B98A-3FF2E71E90C6</string>
<key>PayloadDisplayName</key>
<string>NC1</string>
<key>PayloadDescription</key>
<string/>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadEnabled</key>
<true/>
<key>PayloadRemovalDisallowed</key>
<true/>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadUUID</key>
<string>A7F5A3B5-7E12-4E9D-8F9A-0355E9338F97</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed.applayer</string>
<key>PayloadOrganization</key>
<string>myorg</string>
<key>PayloadIdentifier</key>
<string>A7F5A3B5-7E12-4E9D-8F9A-0355E9338F97</string>
<key>PayloadDisplayName</key>
<string>VPN</string>
<key>PayloadDescription</key>
<string/>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadEnabled</key>
<true/>
<key>IPSec</key>
<dict>
<key>OnDemandEnabled</key>
<integer>0</integer>
<key>PromptForVPNPIN</key>
<false/>
</dict>
<key>IPv4</key>
<dict>
<key>OverridePrimary</key>
<integer>1</integer>
</dict>
<key>Proxies</key>
<dict/>
<key>UserDefinedName</key>
<string>TestNC Jon</string>
<key>VPN</key>
<dict>
<key>RemoteAddress</key>
<string>myprod</string>
<key>OnDemandUserOverrideDisabled</key>
<integer>1</integer>
<key>ExcludeLocalNetworks</key>
<integer>0</integer>
<key>AuthName</key>
<string>user</string>
<key>ProviderDesignatedRequirement</key>
<string>identifier "com.myprod.ne" and anchor apple generic and certificate leaf[subject.CN] = "Mac Developer: me (xxxxxxxx)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<key>ProviderBundleIdentifier</key>
<string>com.myprod.ne</string>
<key>AuthenticationMethod</key>
<string>Password</string>
<key>ProviderType</key>
<string>app-proxy</string>
<key>IncludeAllNetworks</key>
<integer>0</integer>
</dict>
<key>VPNType</key>
<string>VPN</string>
<key>VPNSubType</key>
<string>com.myprod.ne-app</string>
<key>VendorConfig</key>
<dict/>
<key>VPNUUID</key>
<string>825886EA-BB00-4805-ADD6-1674C531669E</string>
<key>OnDemandMatchAppEnabled</key>
<true/>
<key>SafariDomains</key>
<array>
<string>.com</string>
<string>.net</string>
<string>.org</string>
</array>
<key>OnDemandUserOverrideDisabled</key>
<integer>1</integer>
</dict>
<dict>
<key>PayloadUUID</key>
<string>A959CFCB-BABF-4819-B2A6-41F95926AF78</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed.appmapping</string>
<key>PayloadIdentifier</key>
<string>com.apple.vpn.managed.appmapping.663DE2E8-0B7D-46D7-B1AE-331985F4082B</string>
<key>PayloadDescription</key>
<string>Configures TestApp-macOS to use the per-app VPN connection.</string>
<key>PayloadDisplayName</key>
<string>Per-App VPN App Mappings</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>AppLayerVPNMapping</key>
<array>
<dict>
<key>VPNUUID</key>
<string>825886EA-BB00-4805-ADD6-1674C531669E</string>
<key>Identifier</key>
<string>com.google.Chrome</string>
<key>SigningIdentifier</key>
<string>com.google.Chrome</string>
<key>DesignatedRequirement</key>
<string>(identifier "com.google.Chrome" or identifier "com.google.Chrome.beta" or identifier "com.google.Chrome.dev" or identifier "com.google.Chrome.canary") and (certificate leaf = H"85cee8254216185620ddc8851c7a9fc4dfe120ef" or certificate leaf = H"c9a99324ca3fcb23dbcc36bd5fd4f9753305130a")</string>
</dict>
<dict>
<key>VPNUUID</key>
<string>825886EA-BB00-4805-ADD6-1674C531669E</string>
<key>Identifier</key>
<string>com.google.Chrome.helper</string>
<key>SigningIdentifier</key>
<string>com.google.Chrome.helper</string>
<key>DesignatedRequirement</key>
<string>(identifier "com.google.Chrome" or identifier "com.google.Chrome.beta" or identifier "com.google.Chrome.dev" or identifier "com.google.Chrome.canary") and (certificate leaf = H"85cee8254216185620ddc8851c7a9fc4dfe120ef" or certificate leaf = H"c9a99324ca3fcb23dbcc36bd5fd4f9753305130a")</string>
</dict>
<dict>
<key>Identifier</key>
<string>org.mozilla.firefox</string>
<key>VPNUUID</key>
<string>825886EA-BB00-4805-ADD6-1674C531669E</string>
<key>SigningIdentifier</key>
<string>org.mozilla.firefox</string>
<key>DesignatedRequirement</key>
<string>anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "43AQ936H96"</string>
</dict>
</array>
</dict>
</array>
</dict>
</plist>
I do get Safari traffic but not other Apps traffic, at this moment I'm trying Chrome (com.google.Chrome)
I do get Safari traffic in the
(BOOL)handleNewFlow:(NEAppProxyFlow *)flow {}
I want extend the proxy to get Chrome traffic as well. For that I create the section "AppLayerVPNMapping" with the bundle IDs and DesignatedRequirement of Chrome.
The interesting thing is that I get the UDP traffic redirected to
(BOOL)handleNewUDPFlow:(NEAppProxyUDPFlow *)flow initialRemoteEndpoint:(NWEndpoint *)remoteEndpoint {}
It is known that if rejected, Chrome passes to use TCP instead of UDP, I have tested it with another type of Proxy (transparent Proxy).
The result is that the TCP flow is not redirected to the NE and Chrome does not navigate.
Chrome is based in many processes so I have added the "helper" it uses to the list of apps.
I have used "NETestAppMapping" in info.plist but doesn't help.
This is the mobileconfig I'm using.
Anyone has succeeded to get complex apps traffic ?
Thanks !
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-...">
<plist version="1">
<dict>
<key>PayloadUUID</key>
<string>DF2B6E99-2857-474B-B98A-3FF2E71E90C6</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadOrganization</key>
<string>myorg</string>
<key>PayloadIdentifier</key>
<string>DF2B6E99-2857-474B-B98A-3FF2E71E90C6</string>
<key>PayloadDisplayName</key>
<string>NC1</string>
<key>PayloadDescription</key>
<string/>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadEnabled</key>
<true/>
<key>PayloadRemovalDisallowed</key>
<true/>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadUUID</key>
<string>A7F5A3B5-7E12-4E9D-8F9A-0355E9338F97</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed.applayer</string>
<key>PayloadOrganization</key>
<string>myorg</string>
<key>PayloadIdentifier</key>
<string>A7F5A3B5-7E12-4E9D-8F9A-0355E9338F97</string>
<key>PayloadDisplayName</key>
<string>VPN</string>
<key>PayloadDescription</key>
<string/>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadEnabled</key>
<true/>
<key>IPSec</key>
<dict>
<key>OnDemandEnabled</key>
<integer>0</integer>
<key>PromptForVPNPIN</key>
<false/>
</dict>
<key>IPv4</key>
<dict>
<key>OverridePrimary</key>
<integer>1</integer>
</dict>
<key>Proxies</key>
<dict/>
<key>UserDefinedName</key>
<string>TestNC Jon</string>
<key>VPN</key>
<dict>
<key>RemoteAddress</key>
<string>myprod</string>
<key>OnDemandUserOverrideDisabled</key>
<integer>1</integer>
<key>ExcludeLocalNetworks</key>
<integer>0</integer>
<key>AuthName</key>
<string>user</string>
<key>ProviderDesignatedRequirement</key>
<string>identifier "com.myprod.ne" and anchor apple generic and certificate leaf[subject.CN] = "Mac Developer: me (xxxxxxxx)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<key>ProviderBundleIdentifier</key>
<string>com.myprod.ne</string>
<key>AuthenticationMethod</key>
<string>Password</string>
<key>ProviderType</key>
<string>app-proxy</string>
<key>IncludeAllNetworks</key>
<integer>0</integer>
</dict>
<key>VPNType</key>
<string>VPN</string>
<key>VPNSubType</key>
<string>com.myprod.ne-app</string>
<key>VendorConfig</key>
<dict/>
<key>VPNUUID</key>
<string>825886EA-BB00-4805-ADD6-1674C531669E</string>
<key>OnDemandMatchAppEnabled</key>
<true/>
<key>SafariDomains</key>
<array>
<string>.com</string>
<string>.net</string>
<string>.org</string>
</array>
<key>OnDemandUserOverrideDisabled</key>
<integer>1</integer>
</dict>
<dict>
<key>PayloadUUID</key>
<string>A959CFCB-BABF-4819-B2A6-41F95926AF78</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed.appmapping</string>
<key>PayloadIdentifier</key>
<string>com.apple.vpn.managed.appmapping.663DE2E8-0B7D-46D7-B1AE-331985F4082B</string>
<key>PayloadDescription</key>
<string>Configures TestApp-macOS to use the per-app VPN connection.</string>
<key>PayloadDisplayName</key>
<string>Per-App VPN App Mappings</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>AppLayerVPNMapping</key>
<array>
<dict>
<key>VPNUUID</key>
<string>825886EA-BB00-4805-ADD6-1674C531669E</string>
<key>Identifier</key>
<string>com.google.Chrome</string>
<key>SigningIdentifier</key>
<string>com.google.Chrome</string>
<key>DesignatedRequirement</key>
<string>(identifier "com.google.Chrome" or identifier "com.google.Chrome.beta" or identifier "com.google.Chrome.dev" or identifier "com.google.Chrome.canary") and (certificate leaf = H"85cee8254216185620ddc8851c7a9fc4dfe120ef" or certificate leaf = H"c9a99324ca3fcb23dbcc36bd5fd4f9753305130a")</string>
</dict>
<dict>
<key>VPNUUID</key>
<string>825886EA-BB00-4805-ADD6-1674C531669E</string>
<key>Identifier</key>
<string>com.google.Chrome.helper</string>
<key>SigningIdentifier</key>
<string>com.google.Chrome.helper</string>
<key>DesignatedRequirement</key>
<string>(identifier "com.google.Chrome" or identifier "com.google.Chrome.beta" or identifier "com.google.Chrome.dev" or identifier "com.google.Chrome.canary") and (certificate leaf = H"85cee8254216185620ddc8851c7a9fc4dfe120ef" or certificate leaf = H"c9a99324ca3fcb23dbcc36bd5fd4f9753305130a")</string>
</dict>
<dict>
<key>Identifier</key>
<string>org.mozilla.firefox</string>
<key>VPNUUID</key>
<string>825886EA-BB00-4805-ADD6-1674C531669E</string>
<key>SigningIdentifier</key>
<string>org.mozilla.firefox</string>
<key>DesignatedRequirement</key>
<string>anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "43AQ936H96"</string>
</dict>
</array>
</dict>
</array>
</dict>
</plist>
Thanks Matt !
I see that Chrome is trying to reach port 53 (DNS)
0x232948 20:07:18.106075+0300 com.xxxx (2436633849): New flow: NEFlow type = datagram, app = com.google.Chrome, name = , address = 192.168.68.1, port = 53, filter_id = , interface = en0
0x232948 20:07:18.106439+0300 com.*** (2746240844): New flow: NEFlow type = datagram, app = com.google.Chrome, name = , address = 192.168.68.1, port = 53, filter_id = , interface = en0
0x232948 20:07:18.106847+0300 com.*** (1652494299): New flow: NEFlow type = datagram, app = com.google.Chrome, name = , address = 10.0.0.10, port = 53, filter_id = , interface = en0
I return non flow accepted. I do the same for 443 (in App-proxy, not per-app-proxy) and it falls back to TCP. But it seems it is not doing it for the 53 case (in Per-App).
I do have a NENetworkRule that accepts 443 to then reject it to force a TCP fallback.
I'm not sure why I get the 53 flow. I don't have any rule for it, and it seems it can be set in any rule.
According to .h, include exclude do not accept 53 (bellow) So I can't really enforce anything on 53.
In App-Proxy I do get only 443 UDP via a rule(includedNetworkRules). Do you think it is possible in Per-App-Proxy to do the same. Could it be that in Per-App sends everything to the NE and does not really use the NENetworkRules ?
/*!
*/
@property (copy, nullable) NSArray<NENetworkRule *> *includedNetworkRules API_AVAILABLE(macos(10.15)) API_UNAVAILABLE(ios, tvos) __WATCHOS_PROHIBITED;
/*!
*/
@property (copy, nullable) NSArray<NENetworkRule *> *excludedNetworkRules API_AVAILABLE(macos(10.15)) API_UNAVAILABLE(ios, tvos) __WATCHOS_PROHIBITED;
I see that Chrome is trying to reach port 53 (DNS)
0x232948 20:07:18.106075+0300 com.xxxx (2436633849): New flow: NEFlow type = datagram, app = com.google.Chrome, name = , address = 192.168.68.1, port = 53, filter_id = , interface = en0
0x232948 20:07:18.106439+0300 com.*** (2746240844): New flow: NEFlow type = datagram, app = com.google.Chrome, name = , address = 192.168.68.1, port = 53, filter_id = , interface = en0
0x232948 20:07:18.106847+0300 com.*** (1652494299): New flow: NEFlow type = datagram, app = com.google.Chrome, name = , address = 10.0.0.10, port = 53, filter_id = , interface = en0
I return non flow accepted. I do the same for 443 (in App-proxy, not per-app-proxy) and it falls back to TCP. But it seems it is not doing it for the 53 case (in Per-App).
I do have a NENetworkRule that accepts 443 to then reject it to force a TCP fallback.
I'm not sure why I get the 53 flow. I don't have any rule for it, and it seems it can be set in any rule.
According to .h, include exclude do not accept 53 (bellow) So I can't really enforce anything on 53.
In App-Proxy I do get only 443 UDP via a rule(includedNetworkRules). Do you think it is possible in Per-App-Proxy to do the same. Could it be that in Per-App sends everything to the NE and does not really use the NENetworkRules ?
/*!
- @property includedNetworkRules
- @discussion An array of NENetworkRule objects that collectively specify the traffic that will be routed through the transparent proxy. The following restrictions
- apply to each NENetworkRule in this list:
- Restrictions for rules with an address endpoint:
- If the port string of the endpoint is "0" or is the empty string, then the address of the endpoint must be a non-wildcard address (i.e. "0.0.0.0" or "::").
- If the address is a wildcard address (i.e. "0.0.0.0" or "::"), then the port string of the endpoint must be non-empty and must not be "0".
- A port string of "53" is not allowed. Destination Domain-based rules must be used to match DNS traffic.
- The matchLocalNetwork property must be nil.
- The matchDirection property must be NETrafficDirectionOutbound.
*/
@property (copy, nullable) NSArray<NENetworkRule *> *includedNetworkRules API_AVAILABLE(macos(10.15)) API_UNAVAILABLE(ios, tvos) __WATCHOS_PROHIBITED;
/*!
- @property excludedNetworkRules
- @discussion An array of NENetworkRule objects that collectively specify the traffic that will not be routed through the transparent proxy. The following restrictions
- apply to each NENetworkRule in this list:
- Restrictions for rules with an address endpoint:
- If the port string of the endpoint is "0" or is the empty string, then the address of the endpoint must be a non-wildcard address (i.e. "0.0.0.0" or "::").
- If the address is a wildcard address (i.e. "0.0.0.0" or "::"), then the port string of the endpoint must be non-empty and must not be "0".
- A port string of "53" is not allowed. Destination Domain-based rules must be used to match DNS traffic.
- The matchLocalNetwork property must be nil.
- The matchDirection property must be NETrafficDirectionOutbound.
*/
@property (copy, nullable) NSArray<NENetworkRule *> *excludedNetworkRules API_AVAILABLE(macos(10.15)) API_UNAVAILABLE(ios, tvos) __WATCHOS_PROHIBITED;