HomeBrainDump Controlling Internet Access using a Pac Fi...
Controlling Internet Access using a Pac File
Proxy Access Control (PAC) files solve a problem that is becoming more and more common as organizations spread out geographically and workers become more mobile. If this sounds like your company, and you're an administrator concerned with how your users access the Internet and company intranets, keep reading. This might be exactly what you're looking for.
Contributed by Luke Niland Rating: / 21 June 26, 2007
Controlling how users across an organization connect to the Internet and intranets can be a tricky thing to administer. You could have people at different physical locations that all want to go out through different proxies, internal sites that you need them to access directly and roaming users who sometimes work from their own connections at home.
This is where a PAC (Proxy Access Control) file comes in. With this one file you can control how all of your clients access the web. Most of the modern browsers will use a PAC file without any problems. The only exception I know of was the old Macs prior to OSX. I've not used one over the last few years so I don't know if they still have this problem.
Basics of the PAC file
The PAC file contains one function called FindProxyForURL. This function is passed the parameters URL and host. URL is the address of the site that the browser is requesting, while host is the IP address of the client machine making the request.
Once all the logic of the PAC file has been read, the last thing it will do is return the correct proxy server to use (in the format of "PROXY IPAddress:PortNo") or if it is an address that can be reached internally, it will return DIRECT.
Below is a very simple example of a PAC file. Use notepad or your preferred text editor to create the file, and save it as proxy.pac.
function FindProxyForURL(url, host)
{
//set the ip address of the proxy into a variable named proxy
var proxy = "PROXY 192.168.0.1:8080";
return proxy;
}
This very simple example of a PAC file will just re-direct traffic out through a proxy server running at 192.168.0.1 on port 8080. This of course is a very simple example but it should work. To test the PAC file drop it onto one of your internal web servers, and point your browser's automatic config file at the URL, e.g.
http://webserver1/proxy.pac
Once you have set this, as long as the IP and port in the PAC file match yours, you should start using the logic contained in this file. How to distribute the PAC file to clients is discussed later in the article.
If that is working, you can now build more into the file to control what happens to certain sites and subnets.
One of the most useful things you can do is send different subnets through different proxies. This is very good for multiple sites that each have their own Internet connection.
To do this we use a simple if statement to test for the client's IP address, and then set the proxy server based on what is returned, like this:
// Test for entire subnets
// if (isInNet(myIpAddress(), "192.168.0.0", "255.255.255.0"))
// proxy = "PROXY 192.168.0.1:8080";
This statement uses the function IsInNet to determine whether or not the client's IP address matches the one you specify. In the above code if you are any client on the 192.168.0.0 subnet, the function will return true and set the proxy variable to be 192.168.0.1:8080.
You can also use a similar block of code to send individual clients to a certain proxy instead of the entire subnet. This could be useful if certain people are heavy Internet users and have a dedicated proxy.
// Test for individual clients
if (isInNet(myIpAddress(), "192.168.0.25", "255.255.255.255"))
proxy = "PROXY 192.168.0.242:8080";
Of course if you want to use this on certain clients, they will have to have a static IP address.
Directing Traffic based on URL
Next we will test for a certain site URL, and if we find the user wants to access that URL we will send them down yet another proxy.
if (url.substring(0, 24) == "http://www.microsoft.com")
proxy = "PROXY 192.168.0.242:8080";
This function tests the URL string passed into the PAC file for the website address. The 0, 24 parameters tell the function to start at position 0 from the left hand side of the string, and count 24 characters. If the string matches the function returns true and the proxy variable is set.
As we are using the Substring function, we can not only test for a specific web site, but specific protocols as well. For instance you might want all of your FTP traffic to go out over a different link from your normal HTTP and HTTPS traffic.
Now that we have got this far, we are almost ready to send the user to the correct proxy. The only thing we have not done yet is make sure that, if they are trying to access a site on your internal network, they go directly and do not use the proxy. This is done like so:
if (isInNet(host, "192.168.0.0", "255.255.0.0"))
{
return "DIRECT";
}
else {
return proxy;
}
The first part of the IF statement is the IsInNet function again, this time on the IP address of the destination passed into the PAC file. If it is in the IP scope specified, then the user is sent directly to the site. At this point the logic of the PAC file concludes and the user is sent to the site.
If the IF statement returns false, then the user is sent to the proxy server that is currently held in the proxy variable.
Put it all Together
Now that we have all the building blocks, we can create our PAC file. If we wish, we can also set it up so that, instead of using the IP address of the proxy, it points to a DNS entry. This is useful if you have backup proxies. In that case, if the main one goes offline you can change the DNS entry to the backup and the clients will be re-directed, without you having to alter the PAC file. We use this in our final completed example.
function FindProxyForURL(url, host)
{
//Set a default proxy if non are returned below
var proxy = "PROXY 192.168.0.244:8080";
// Test for Prestons subnets
if (isInNet(myIpAddress(), "192.168.1.0", "255.255.255.0"))
proxy = "PROXY proxy_preston:8080";
if (isInNet(myIpAddress(), "192.168.2.0", "255.255.255.0"))
proxy = "PROXY proxy_preston:8080";
// Test for Londons subnets
if (isInNet(myIpAddress(), "192.168.3.0", "255.255.255.0"))
proxy = "PROXY proxy_blackpool:8080";
if (isInNet(myIpAddress(), "192.168.4.0", "255.255.255.0"))
proxy = "PROXY proxy_blackpool:8080";
//Now direct the user out through the proxy if not internal site
if (isInNet(host, "192.168.0.0", "255.255.0.0"))
{
return "DIRECT";
}
else if (url.substring(0, 24) == "http://www.microsoft.com")
Now that you have your PAC file, you need to get your users to start using it. There are a couple of ways you can accomplish this, apart from the obvious one of getting them to do it themselves.
Please note that all the options discussed below are for use with Internet Explorer; they won't affect FireFox, Opera, Safari etc. If you have any way of setting up these browsers send them to me and I'll attach them as a comment to this article.
Hacking the Registry
The IE home page is just a simple setting in the registry. It is specific for each user profile on the machine and lives in
If you are running in an active directory domain, this is probably the best way to control it. By using this method you can not only set the location of the PAC file, but disable the option in Internet Explorer so that the user can't go in and change it.
Open up (or create) a Policy file that will hold the settings for your users. The options you need are all in the USER section under Windows Settings/Internet Explorer Maintenance/Connection. To use your PAC file, open up the Automatic Browser Configuration option.
In here tick the Enable Automatic Configuration box, and then in the bottom text area named Auto-proxy URL, put the address of your PAC file in. For example, http://webserver1/proxy.pac.
You can also set a time in minutes that will reload the PAC file. If you leave this blank the PAC file is just re-read every time you reload the browser.
Going Forward
As the language of the PAC file is JavaScript-based, there are a lot more functions you could build into it, such as re-directing the user to one site if they try to visit a page they shouldn't be visiting. There are also various other options for distributing the PAC file. One of the most interesting is using DNS and DHCP to implement the Web Proxy Autodiscovery (WPAD) protocol.