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”.
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.
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 proxyhost: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 aSOCKS
-proxy. This might be interesting for IT administrators, because you can use this to forward requests via aSOCKS
-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!