Change in iOS 10.2 and Greater Proxy pac Files⚓︎
Posted February 20, 2017
iOS Now Honors Absolute ‘Unambiguous’ FQDN Requests in Proxy pac Files⚓︎
Previous to iOS 10.2⚓︎
In versions of Apple iOS previous to 10.2, Automatic Proxy Configuration files which used dnsDomainIs functions like those below use to work without issue.
// Return DIRECT for all domain.com requests else if (dnsDomainIs(host,".domain.com") || dnsDomainIs(host,"domain.com")) return "DIRECT";
// Return DIRECT for VPN servers else if (dnsDomainIs(host,"vpn.domain.com")) return "DIRECT";
Note that these statements could also be used to direct users to a proxy server if the URL matches the domain.
These type statements are quite common and have worked for years without issue in most all browsers. If you look at various documentation on how to use dnsDomainIs you will find that this is the suggested usage.
iOS 10.2 and greater⚓︎
It would seem that starting in iOS 10.2 (to include 10.2, 10.2.1, and all 10.3 betas) Apple has changed how iOS deals with the domain names and proxy pac files.
Take for example the following debug log from our VPN client, which ironically is taken from an iOS 9.3.5 device, which was able to VPN without issue.
Info ( 530): Flip dot in https://vpn.domain.com:443/ssl-vpn/prelogin.esp Info ( 532): New url https://vpn.domain.com.:443/ssl-vpn/prelogin.esp
Notice that the FQDN is be rewritten in to an unambiguous, rooted, or absolute FQDN. This same log can be found in the debug logs on iOS 10.2.
While not commonly known, the trailing “.” is part of RFC 1034, commonplace in DNS, and is not only valid, but should be used by the web browsers internally. This is known by many names, more commonly absolute FQDN, but also as rooted FQDN, or unambiguous FQDN. Without the trailing dot is known as relative FQDN, ambiguous FQDN, or simply just FQDN.
There are others who have documented this topic already so if this is new to you please see the following links.
It would seem that while in iOS 9 this process of adding the training dot was taking place, the proxy engine logic was ignoring, stripping, or otherwise eliminating, this trailing “.”. This is, arguably, how most web browsers operate, and is in fact highly debated every time it comes up.
In iOS 10.2+ this “.” is now passed to, or parsed by, the proxy engine. This is what is causing dnsDomainIs to return false in the above example, despite it returning a true in previous versions of iOS.
The solution is simple, just add a check for both FQDN without the “.” and with the “.” and your pac file will start working again. I’d highly recommend adding both as users will not be adding the trailing “.” to any url they type, only software wishing to be certain of the server it is talking to will be adding this.
// Return DIRECT for all domain.com requests else if (dnsDomainIs(host,".domain.com.") || dnsDomainIs(host,".domain.com") || dnsDomainIs(host,"domain.com")) return "DIRECT";
// Return DIRECT for VPN servers else if (dnsDomainIs(host,"vpn.domain.com.") || dnsDomainIs(host,"vpn.domain.com")) return "DIRECT";
Some might argue that using shExpMatch, as in the example below, may be a more preferred way, though be careful with this as many examples use a trailing “/”, or port number, which would again break the statement.
// Return DIRECT for VPN servers if (shExpMatch(host, "vpn.domain.com")) return "DIRECT";
While the above will work, the following will still have the same issues as dnsDomainIs.
if (shExpMatch(host, "vpn.domain.com/")) return "DIRECT"; if (shExpMatch(host, "vpn.domain.com:443")) return "DIRECT";
Did this help you out?⚓︎
If you found this helpful please drop me a line, I’d like to know how many people have run in to this issue as I have not found this information coming up in any forums as of this writing.