Windows proxy settings ultimate guide part III – WPAD/PAC configuration file

  1. History
  2. PAC/WPAD script
  3. Hosting proxy.pac/wpad.dat file
  4. Adding script file to IE/EDGE
  5. Autodetection of script using DHCP and DNS servers – WPAD
  6. P.S

History

The first proxy automatic detection system, called PAC (proxy auto-config), was developed in time of Netscape Navigator (if you are old enough like me you will remember). It allowed you to specify a JavaScript location which told the browser which proxy to use or bypass request. It also provided a central position from which to change proxy servers. In years after, there was a problem with changing script location. Clients needed to change script location manually, or you, as admin, needed to change script location yourself. The solution for this problem is WPAD (Web Proxy Auto Discovery). This is a set of methods for finding the PAC script to be tried in order, leveraging DHCP and DNS services on network. Let start with script itself.

Browser support for WPAD

PAC/WPAD script

A PAC/WPAD file contains a JavaScript function “FindProxyForURL(url, host)”. JavaScript is case sensitive, and IE itself converts the variables url and host into lowercase before the FindProxyForURL function is called. This condition is not true for WinHTTP. This is because WinHTTP passes the host and the url directly to the function. That’s why we need conversion to lowercase in script. If you are familiar with proxy settings up to now all comments in script should be self explanatory. Function returns a string with one or more access method specifications. These specifications cause browser to use a particular proxy server or to connect directly. You can copy this function in any text editor and save it under proxy.pac or wpad.dat file . Names can be different but its usual naming convection you will encounter.

function FindProxyForURL(url, host)
{
 
/* Normalize the URL for pattern matching */
url = url.toLowerCase();
host = host.toLowerCase();
 
/* Don't proxy local hostnames */
if (isPlainHostName(host))
{
return 'DIRECT';
}
 
/* Don't proxy local domains */
if (dnsDomainIs(host, ".example1.com") ||
(host == "example1.com") ||
dnsDomainIs(host, ".example2.com") ||
(host == "example2.com") ||
dnsDomainIs(host, ".example3.com") ||
(host == "example3.com"))
{
return 'DIRECT';
}
 
/* Don't proxy Windows Update */
if ((host == "download.microsoft.com") ||
(host == "ntservicepack.microsoft.com") ||
(host == "cdm.microsoft.com") ||
(host == "wustat.windows.com") ||
(host == "windowsupdate.microsoft.com") ||
(dnsDomainIs(host, ".windowsupdate.microsoft.com")) ||
(host == "update.microsoft.com") ||
(dnsDomainIs(host, ".update.microsoft.com")) ||
(dnsDomainIs(host, ".windowsupdate.com")))
{
return 'DIRECT';
}
 
if (isResolvable(host))
{
var hostIP = dnsResolve(host);
 
/* Don't proxy non-routable addresses (RFC 3330) */
if (isInNet(hostIP, '0.0.0.0', '255.0.0.0') ||
isInNet(hostIP, '10.0.0.0', '255.0.0.0') ||
isInNet(hostIP, '127.0.0.0', '255.0.0.0') ||
isInNet(hostIP, '169.254.0.0', '255.255.0.0') ||
isInNet(hostIP, '172.16.0.0', '255.240.0.0') ||
isInNet(hostIP, '192.0.2.0', '255.255.255.0') ||
isInNet(hostIP, '192.88.99.0', '255.255.255.0') ||
isInNet(hostIP, '192.168.0.0', '255.255.0.0') ||
isInNet(hostIP, '198.18.0.0', '255.254.0.0') ||
isInNet(hostIP, '224.0.0.0', '240.0.0.0') ||
isInNet(hostIP, '240.0.0.0', '240.0.0.0'))
{
return 'DIRECT';
}
 
/* Don't proxy local addresses.*/
if (false)
{
return 'DIRECT';
}
}
 
if (url.substring(0, 5) == 'http:' ||
url.substring(0, 6) == 'https:' ||
url.substring(0, 4) == 'ftp:')
{
return 'PROXY 10.0.40.50:9090';
}
 
return 'DIRECT';
}

Depending on configuration needed you can change script to fit your needs. For example if you have multiple branch offices, or subnets that have its own proxy server installed, you can configure script in next way to reflect your infrastructure

{
if (isInNet(myIpAddress(), "10.1.0.0", "255.255.0.0"))
{ return "PROXY wcg1.example.com:8080; " +
"PROXY wcg2.example.com:8080";
}
 
if (isInNet(myIpAddress(), "10.2.0.0", "255.255.0.0"))
{ return "PROXY wcg1.example.com:8080; " +
"PROXY wcg2.example.com:8080";
}
 
if (isInNet(myIpAddress(), "10.3.0.0", "255.255.0.0"))
{ return "PROXY wcg2.example.com:8080; " +
"PROXY wcg1.example.com:8080";
}
 
if (isInNet(myIpAddress(), "10.4.0.0", "255.255.0.0"))
{ return "PROXY wcg2.example.com:8080; " +
"PROXY wcg1.example.com:8080";
}
else return "DIRECT";
}

There is a lot of examples on the net about possible configuration but if you want to know more about function you can use in if statements visit next sites I consulted while creating this blog post.

https://www.websense.com/content/support/library/web/v76/pac_file_best_practices/PAC_best_pract.aspx

Hosting proxy.pac/wpad.dat file

You need to present your PAC file on some location that is accessible to computers on your network. Usually it is web location hosted on local web service. For our example we will put PAC file on root of default web site in IIS.

Problem you will encounter is next one (see picture below). To correct it you need to add PAC extension to host header mime types.

HTTP error 404.3 hosting pac file

Open IIS manager select website where you hosted pac file and open MIME types presented on next picture

MIME types


Click add to add pac file with next values FileExtension=’.pac’;mimeType= ‘application/x-ns-proxy-autoconfig’

Add pac file to MIME types

If you are using wpad.dat naming you will need same setting but you need to enter next values File extension: ‘dat’; MIME type: ‘application/x-javascript-config’

You can do same with PowerShell (example)

import-module WebAdministration
md c:\AutoConfig
New-Item 'IIS:\Sites\Default Web Site\AutoConfig' -Type VirtualDirectory -PhysicalPath c:\AutoConfig
add-WebConfigurationProperty //staticContent -name collection -PSPath 'IIS:\Sites\Default Web Site\AutoConfig' -Value @{FileExtension='.pac';mimeType= 'application/x-ns-proxy-autoconfig'

After that client will be able to get PAC file from web location.

Adding script file to IE/EDGE

To use script file you need to add script location resembling example on picture. You can use this config in IE settings also, or deploy it with GPO (refer to part II of this guide)

Proxy setup for pac file publisned on IIS website

What happens now is that every url you type in browser is evaluated with JavaScript function FindProxyForURL and accordingly, you will use or not use proxy for that url.

Autodetection of script using DHCP and DNS servers – WPAD

If you want to provide same proxy policy to all browsers, and ability to easily change PAC file location to all clients, you need two things:

  • Standard Proxy auto-config (PAC): Create and publish a central proxy configuration file.
  • Autodiscovery Protocol (WPAD) Web Proxy Standard

WPAD standard define method to retrieve location of PAC file using first DHCP or DNS if DHCP discovery fail or doesn’t exist (Firefox doesn’t support DHCP WPAD discovery). DHCP has a higher priority than DNS for automatic configuration. If DHCP provides the URL for configuration file, the process stops and the DNS lookup doesn’t happen.

For DHCP to work it need to support DHCPINFORM message, to obtain the DHCP options 252. Let first show configuration of that option on Windows Server DHCP.

First we need to add/configure that option on DHCP server level, and then to add that option to DHCP IP scope of our choice. Open DHCP management tools and right click on IPV4 and choose Set Predefined Options. In new window click Add and enter next values: NameWPAD; Code : 252; Data type select String, and then click OK. In string type URL of PAC file : http://192.168.0.2/proxy.pac. It will be default value for this option. After you create it check for its existence. It should be present like on the picture below.

DHCP option 252

After that you need to turn on created option to IP scope. Right click Scope options, and then click Configure options. Select option 252 from existing list. Default location of script will be presented but you can change it.

Selecting WPAD Scope option

For most of clients or browsers this setting is more than enough (except Firefox), but some clients have static ip addresses and they can not use DHCP. This is part where DNS comes in. If DHCP proxy discovery fails or doesn’t exist, DNS is next stop for WPAD. You need to create alias (CNAME) record in your local domain zone with name WPAD. It means that if your local domain name is contoso.com, client/browser will look for next URLs using WPAD method, trying to find autoproxy configuration file in next order

http://wpad.contoso.com/wpad.dat;

http://wpad.com/wpad.dat

wpad.dat vs proxy.pac

You probably noticed that client is looking for wpad.dat file. In our examples up to now we used proxy.pac naming. It would be beneficial to use wpad.dat file naming, even though, content of the file is same. Main reason is WPAD method mentioned above, where DNS discovery is trying to look for wpad.dat file. You can bypass it with HTTP URL rewrite rule on web site.

URL rewrite rule for wpad.dat

After yu setup everything usually what is happening is that if you try to resolve wpad entry in DNS you get nothing in response. Because of security reasons, and possible hijacking of wpad record in DNS, Microsoft decided to put wpad entry on DNS server global query block list. It exist from W2008 Server. To make it work you need to remove it with next command

Removing wpad grom DNS server global query block list

after that your DNS resolution will work

Everything that is left is to click automatically detect setting button in browser or system proxy settings.

This should be the last post of proxy trilogy from me. I was really tired of collecting bits and pieces about proxy setting from around the web. somwhow it turns out it can be a small book. There is some more things about proxy configuration, but I will leave that for readers to discover.

I wish you to enjoy rest of this summer. I am going to use it also on vacation staring next week.

P.S

One more thing you can research is Autoprox.exe utility for testing and debugin your PAC file. Download link

If you like you can read also about optimizing PAC file functions on https://docs.microsoft.com/en-us/troubleshoot/developer/browsers/connectivity-navigation/optimize-pac-performance

2 thoughts on “Windows proxy settings ultimate guide part III – WPAD/PAC configuration file”

  1. Hi Igor great post thanks very much, can I ask 1 question please as I am new to this and trying to test, we have a requirement to push Explicit URLS through out internal proxy and I am just wondering if I can use the if ((host without specifying dnsDomainIS so it is just for the specific url e.g.

    /**Send Traffic to internal proxy**/
    if ((host == “download.microsoft.com”) ||
    {
    return “PROXY myproxy.mycompany.local:8080”;

    1. I didnt work too much with pac scripts but logic of things is that you can return specific proxy for specific URL. I think it should work. Just put it in pac file what you have in mind, and test it out. You will not brake anything 🙂

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.