Apple OS X El Capitan Networkd Proxy Oddities

By | April 7, 2016

After receiving a new MacBook to test with VPN access. I noticed some oddities occurring specifically in relation to the VPN software adjusting the Proxy Auto Configuration URL to a loopback server that is providing an updated PAC file. Unfortunately this PAC file is considered corrupt by EL Capitan networkd process. At this point Safari, Chrome, Webex etc can no longer get to the internet.  This leaves a few questions why would VPN software want to adjust a PAC file and it makes me wonder what Apple is doing to make sure the networkd is resilient and can handle a PAC file that doesn’t meet what would be considered spec.  Note: This same issue seems to of cropped up for the Lantern Proxy VPN project https://github.com/getlantern/lantern/issues/3039.

Working PAC file with El Capitan Networkd:

function FindProxyForURL(url, host)
{
var proxyserver = “PROXY proxy.example.com:80”;

// Convert all hosts to lowercase
temphost = host.toLowerCase();
host = temphost;

// Local IPs

if (
isInNet(host, “172.16.0.0”, “255.240.0.0”) ||
isInNet(host, “192.168.0.0”, “255.255.0.0”) ||
isInNet(host, “10.0.0.0”, “255.0.0.0”) ||
isInNet(host, “127.0.0.0”, “255.0.0.0”)
)
{
return “DIRECT”;
}

// Standard String Match Expression

if (shExpMatch(host, “notexample.com”) ||
shExpMatch(host, “internal.notexample.com”) ||
shExpMatch(host, “137.99.*”))
{
return “DIRECT”;
}

return proxyServer;
}

Non Working PAC file adjusted by the VPN process causes networkd to throw the following error. Unforunately why the VPN software adjusts the PAC file as below is beyond me but it can be worked around to make things like Safari, Chrome and WebEx work

Apr  6 15:19:17 MacBookPro networkd[19757]: -[NETProxyLookup url] invalid URL scheme ‘44444’

function FindProxyForURL_Local(url, host)
{
var proxyserver = “PROXY proxy.example.com:80”;

// Convert all hosts to lowercase
temphost = host.toLowerCase();
host = temphost;

// Local IPs

if (
isInNet(host, “172.16.0.0”, “255.240.0.0”) ||
isInNet(host, “192.168.0.0”, “255.255.0.0”) ||
isInNet(host, “10.0.0.0”, “255.0.0.0”) ||
isInNet(host, “127.0.0.0”, “255.0.0.0”)
)
{
return “DIRECT”;
}

// Standard String Match Expression

if (shExpMatch(host, “notexample.com”) ||
shExpMatch(host, “internal.notexample.com”) ||
shExpMatch(host, “137.99.*”))
{
return “DIRECT”;
}

return proxyServer;
}

function FindProxyForURL_HTTPS_Local(url,host)
{
return FindProxyForURL_Local(url, host);
}

function FindProxyForURL_Remote(url,host)
{
return “DIRECT”;

}

function FindProxyForURL(url, host)
{
if (isPlainHostName(host) || isInNet(host, “127.0.0.1”, “255.255.255.255”)) return “DIRECT”;
if(localHostOrDomainIs(host, “vpn.example.com”)) return FindProxyForURL_HTTPS_Local(url,host);
if (shExpMatch(host, “*”)) return FindProxyForURL_Remote(url,host);
if(isInNet(host, “0.0.0.0”,”128.0.0.0″)) return FindProxyForURL_Remote(url,host);
if(isInNet(host, “128.0.0.0”,”128.0.0.0″)) return FindProxyForURL_Remote(url,host);
return FindProxyForURL_Local(url,host);

}