Advertisement

You can find quite a few IT infrastructures where an HTTP proxy is used to secure the access to the “World Wide Web” (WWW). In smaller company environments you can configure the proxy for each workstation manually. In larger environments you normally use a so called “proxy.pac” for this. This article gives you an introduction to “proxy.pac”-files.

Introduction

A “proxy.pac” is a piece of JavaScript-code which tells the browser which “proxy” it should use for a given URL. “PAC” stands for “Proxy Auto Configuration”. An administrator stores the JavaScript-code in a file, distributes the file via a webserver like “Apache” or “nginx” (“proxy.pac” distribution server) and configures the browser to download the file from the webserver using an URL, e.g. “http://proxypac.in.example.net/proxy.pac”. Also see Fig 1. It shows the configuration dialog of the Firefox web browser to configure the “proxy” and “proxy.pac” settings. You can open the dialog via “Preferences” > “Advanced” > “Network” > “Settings”.

Configuration-dialog for "proxies" and "proxy.pac" of the Firefox web browser

Fig. 1: Configuration-dialog for “proxies” and “proxy.pac” of the Firefox web browser.

Request resources from a web server

When a user asks the browser to open a website, it downloads the “proxy.pac” from the “proxy.pac” distribution server (1.). After that it evaluates the “proxy.pac” for the entered URL. If the result tells the browser to use “Proxy A” it forwards the request to the given proxy (2.). The proxy will then request the resource from the webserver (3.) – please also see Fig 2. for a graphical representation of this process.

Process for requesting a resource from a webserver

Fig. 2: Process for requesting a resource from a webserver.

Structure of a “proxy.pac”

To give you an idea how a proxy.pac looks like, here’s an example. Every “proxy.pac” is required to contain the function FindProxyForURL(url, host). The “proxy.pac” found below always returns "DIRECT". Thus no proxy will be used for all domains – not a very usable “proxy.pac”, but this one should only show you the general structure of such a file.

function FindProxyForURL(url, host) {
  return "DIRECT";
}

Return values

The return value of the function FindProxyForURL() needs to something like "DIRECT", "PROXY host:port" or "SOCKS host:port".

  • DIRECT: This is used to tell the browser not to use a proxy at all.
  • PROXY: If the “proxy.pac” returns "PROXY host:port", then the browser will use the proxy host:port for HTTP-, HTTPS- and FTP-requests.
  • SOCKS: If the result is "SOCKS host:port", the browser will use the SOCKS-protocol to forward the request to a SOCKS-proxy. This might be interesting for IT administrators, because you can use this to forward requests via a SOCKS-tunnel setup via “SSH”.

JavaScript-functions in your “proxy.pac”

There are some special JavaScript-functions which you can use in your “proxy.pac” – a full list can be found here and here. Say you want to check if the host of a URL has no domain given, e.g. localhost, you can use isPlainHostName(host) test for that. To check if the host has domain in.example.net, you could use dnsDomainIs(host, "in.example.net").

The proxy.pac found below checks if a plain host or some internal domain is used. If the check returns true for a given URL, the request is sent directly, otherwise the proxy proxy.in.example.net listening on TCP port “8080” is used.

function FindProxyForURL(url, host) {
  if (
    isPlainHostName(host) ||
    dnsDomainIs(host, "in.example.net")
  ) {
    return "DIRECT";
  }

  return "PROXY proxy.in.example.net:8080";
}

Gotchas

When you need to maintain a “proxy.pac”, be careful. There are some gotchas which might cause you and your users some troubles:

  • Each new entry in your can change the result and thus can break the proxy configuration for your users’ browser.
  • Most browsers are not able print an error message at all if they fail to parse the “proxy.pac”.
  • Firefox and Internet Explorer do not accept the same JavaScript-code in a “proxy.pac”. Some JavaScript-statements accepted by Firefox cause errors in the Internet Explorer.
  • Some applications and mobile devices do not support each “proxy.pac”-JavaScript-function.

Helpful utilities

If you need to test your “proxy.pac” there are some helpful utilities. I listed two of them here.

  • proxy_pac_rb: A Rubygem to test, compress, lint and parse proxy auto-config files.
  • pacparser: A python/c-library to parse proxy auto-config (PAC) files

Conclusion

A “proxy.pac” is a very helpful “tool” for proxy administrators. It reduces the amount of work to maintain the proxy configuration for bigger infrastructures. But it has its own complexity the administrator needs to be aware of. If you distribute a broken “proxy.pac”, none of your users will have access to the WWW anymore. To prevent distributing a broken “proxy.pac” you should test it, before you distribute the file via a webserver.

Thanks for reading!

Discussion

If you found a mistake in this article or would like to contribute some content to it, please file an issue in this Git Repository

Disclaimer

The contents of this article are put together to the best of the authors' knowledge, but it cannot be guaranteed that it's always accurate in any environment. It is up to the reader to make sure that all information found in this article, does not do any damage to the reader's working environment or wherever this information is applied to. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, arising from, out of or in connection with this article. Please also note the information given on the Licences' page.