PAC File
A proxy auto-config (PAC) file defines how web browsers and other user agents can automatically choose the appropriate proxy server (access method) for fetching a given URL.
functionFindProxyForURL(url, host) {
// If the hostname matches, send direct.
if(dnsDomainIs(host, "intranet.domain.com") ||
shExpMatch(host, "(*.abcdomain.com|abcdomain.com)"))
return"DIRECT";
// If the protocol or URL matches, send direct.
if(url.substring(0, 4)=="ftp:"||
return"DIRECT";
// If the requested website is hosted within the internal network, send direct.
if(isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0"))
return"DIRECT";
// If the IP address of the local machine is within a defined
// subnet, send to a specific proxy.
if(isInNet(myIpAddress(), "10.10.5.0", "255.255.255.0"))
return"PROXY 1.2.3.4:8080";
// DEFAULT RULE: All other traffic, use below proxies, in fail-over order.
return"PROXY 4.5.6.7:8080; PROXY 7.8.9.10:8080";
}
Recommendations
When deploying URL and host rules care must be taken to ensure rules are as explicit as possible. The examples below detail how host and URL rules should be implemented.
Host Example
if (dnsDomainIs(host, "abcdomain.com") || dnsDomainIs(host, "www.abcdomain.com"))
return "DIRECT";
URL Example
if (shExpMatch(url, "http://abcdomain.com/folder/*"))
return "DIRECT";
Warnings
The following code is an example which may have unintended consequences due to the broad interpretation of using the shExpMatch function, wildcards, and hostnames.
Cautionary Example
// Would send both of the following requests direct to the Internet:
// 1. www.hotmail.com 2. phishing-scam.com?email=someone@hotmail.com
if (shExpMatch(url, "*hotmail.com*"))
return "DIRECT";
Safe Example
// Would send only traffic to the host and subdomains of hotmail.com
if (shExpMatch(host, "*.hotmail.com"))
return "DIRECT";
PAC Functions
dnsDomainIs
Evaluates hostnames and returns true if hostnames match. Used mainly to match and exception individual hostnames.
Example
// If the hostname matches google.com or www.google.com
// send direct to the Internet.
if (dnsDomainIs(host, "google.com") || dnsDomainIs(host, "www.google.com"))
return "DIRECT";
shExpMatch
Will attempt to match hostname or URL to a specified shell expression, and returns true if matched.
Example
// Any requests with a hostname ending with the extension .local
// will be sent direct to the Internet.
if (shExpMatch(host, "*.local"))
return "DIRECT";
Example
// A request for the host vpn.domain.com or any request for a file or folder in the
// location http://abcdomain.com/folder/ will be sent direct to the Internet.
if (shExpMatch(host, "vpn.domain.com") ||
shExpMatch(url, "http://abcdomain.com/folder/*"))
return "DIRECT";
isInNet
This function evaluates the IP address of a hostname, and if within a specified subnet returns true. If a hostname is passed the function will resolve the hostname to an IP address.
Example
// If IP of requested website website falls within IP range, send direct to the Internet.
if (isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0"))
return "DIRECT";
dnsResolve
Resolves hostnames to an IP address. This function can be used to reduce the number of DNS lookups, e.g. below example.
Example
// If IP of the requested host falls within any of the ranges specified, send direct.
if (isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0"))
return "DIRECT";
localHostOrDomainIs
Evaluates hostname and only returns true if exact hostname match is found.
Example
// If the Host requested is "www" or "www.google.com", send direct.
if (localHostOrDomainIs(host, "www.google.com"))
return "DIRECT";
isResolvable
Attempts to resolve a hostname to an IP address and returns true if successful. WARNING – This may cause a browser to temporarily hang if a domain isn’t resolvable.
Example
// If the host requested can be resolved by DNS, send via proxy1.example.com.
if (isResolvable(host))
return "PROXY proxy1.example.com:8080";
Protocol Control
// HTTP
if (url.substring(0,5)=="http:") return "DIRECT";
// HTTPS
if (url.substring(0,6)=="https:") return "DIRECT";
// FTP
if (url.substring(0,4)=="ftp:") return "DIRECT";
Machine IP Based Routing
Example:1
if (isInNet(myIpAddress(), "10.10.5.0", "255.255.255.0"))
return "PROXY 1.2.3.4:8080";
Example: 2
function FindProxyForURL(url, host)
{
var privateIP = /^(0|10|127|192\.168|172\.1[6789]|172\.2[0-9]|172\.3[01]|169\.254|192\.88\.99)\.[0-9.]+$/;
var resolved_ip = dnsResolve(host);
/* Don't send non-FQDN or private IP auths to us */
if (isPlainHostName(host) || isInNet(resolved_ip, "192.0.2.0","255.255.255.0") || privateIP.test(host))
return "DIRECT";
Points to remember:
ü After updating my PAC file, the change I made don’t seem to have taken effect?
Browsers will cache a PAC file rather than retrieve it for each request; in some cases a browser restart is insufficient for obtaining an updated version of the file.In order to obtain the latest version it may be necessary to clear the browser cache, close all browser windows, and reopen the browser application.
ü Why might web browsing performance degrade when using a PAC file?
A PAC file may leverage several functions which rely on the local DNS server(s) in order to resolve a requested host. These functions are isInNet(), isResolvable(), and dnsResolve().
ü Tools to validate the pac file –