PAC Files Explained

What is a PAC file?

A Proxy Auto-Configuration (PAC) file is a set of instructions, coded in JavaScript, that determines whether web browser requests go directly to their desired destination or are forwarded to a web proxy server.
In other words, a PAC file defines how web browsers/devices can automatically choose the appropriate access method (proxy or direct) for fetching a given URL.

The big advantage of PAC files is that they are usually relatively easy to create and maintain and they allow you to only proxy the sites that you want to proxy, keeping both privacy in mind and Rocket processes to a minimum.

A PAC file is:

  • Flexible and extensible
  • Supported by all popular browsers
  • Easy to administer and maintain in any size network
  • Able to support mobile devices that use standard browsers

A PAC file can:

  • Be stored on any server in your network. Small networks may store the file on the proxy itself, but large, enterprise-class networks should use a separate server for storing the PAC file
  • Perform load distribution
  • Handle proxy failover

A PAC file fulfills the following vital functions:

  • The PAC file provides critical security, ensuring that traffic is always proxied when it should be, while allowing secure requests to go direct to the destination.
    • Typically, Internet-bound HTTP, HTTPS, and FTP traffic is sent to the proxy.
    • Typically, intranet traffic goes direct to the destination.
    • Exceptions can be made for internal or external sites that, for whatever reason, must go to or bypass the proxy.
  • The PAC file locks down the web browser’s LAN egress configuration.
  • The PAC file provides a flexible, easy to maintain, script-driven method of controlling the routing of web requests.
  • The PAC file can include code that handles proxy load distribution and failover.

A PAC file can have rules to route traffic, including:

  • Internet vs Intranet request
  • IP address of requested website
  • Host of the requested website
  • Date/Time

 

Creating a Basic Pac File

A PAC file is a single function written in Javascript where you can specify a set of rules and conditions.

Note: When creating and editing a PAC file you should use a simple text editor such as Notepad++ or Textwrangler on Windows or Text Edit on MAC. You should not use a google doc or a Word doc as they can cause formatting issues. You can also download code text editors that are open source, such as Atom.

Example:

function FindProxyForURL(url, host) {
// This is a template PAC file for schools built by Lightspeed Systems
// Your proxy server name and port
  var proxy_yes = "PROXY YOUR_PROXY_FQHN:PORT";
  var proxy_no = "DIRECT";
// If the hostname matches, send to proxy.
if (shExpMatch(url, "*.google.com/*"))
    return proxy_yes;
// DEFAULT RULE: All other traffic, send direct
    return proxy_no;
}

The file will consist of the following:

  • The function itself
  • Comments
  • Variable for your Proxy server
  • Rules for proxying
  • Fallback instructions

Let’s go through each of these components below, using the above PAC file as a reference.

Function

function FindProxyForURL(url, host){
}        

When a web browser makes a request, the request first goes through the PAC file to see if the URL being requested matches any rules set in the function.

Parameters
URL – The URL being requested by the web browser.
Host – The hostname extracted from the URL.

Results
When the function is performed, it determines what should happen with the request based on the rules that you setup within the function itself.

The results will typically be one of the following:

  • DIRECT – Connections should be made directly, without any proxies
  • PROXY – Connections should be proxied.

Example: If a web browser makes a request for http://www.google.com, the request is run through the PAC file to determine if there are any rules specified.

Comments

You can add comments throughout your PAC file. This is extremely helpful as you update your PAC file over time and want to keep things clear.

You can add a comment by starting a new line in your PAC file and adding //.

You will need to add the // to the beginning of every line you want to utilize as a comment.

Example:

// If the hostname matches, send to proxy

Variables

Since the PAC file is javascript, you can use javascript variables to make it easier to create and less likely to make a mistake in your syntax. That way you will not have to retype your Proxy FQHN and Port for every rule you put into the PAC file.

Example:

var proxy_yes = "PROXY HOSTNAME:8080";

For this variable you need to add the FQHN for the Rocket you intend to utilize for proxying. You also need to specify which port you are using for your proxy traffic.

You can find the FQHN for your Rocket by navigating to Settings: Network Interfaces

You can find your port for your Proxy traffic by navigating to Web Filter: Proxy Server

Learn more about Firewall ports for proxy
Make sure to test both your FQHN and your port prior to utilizing your PAC file. If you put in an FQHN or port that is not resolvable, your devices may no longer be able to pass any internet traffic. As a result, you will not be able to resolve the problem without putting your hands on the devices.

Rules for Proxying

PAC files are highly extensible and customizable. You can decide to proxy based on URLs, domains, time ranges, IP ranges, and much more. The most basic function is the URL match function, shExpMatch. This function allows you to set a rule as to whether you want a certain URL to be proxied or to send direct. We’ll discuss adding multiple rules in the next step.

Example:

if (shExpMatch(url, "*.google.com/*"))
     return proxy_rocket;
Note: Utilizing wildcards (*) in your PAC file are useful ways to ensure that all the sites and URLs a user may visit on the host will be proxied. You should put one before the host domain itself and then one after the .tld/. Example: *domain.com/*

Fallback Instructions

It is best to end your PAC file with a rule for all other requests. As the function runs, it checks against all the rules you put together, and if it doesn’t match any of them, it will follow the default rule.

Example:

// DEFAULT RULE: All other traffic, send direct.
    return proxy_no;

File Type

The PAC auto-configuration file should be saved to a file with a .pac filename extension.

Example: southernacademy.pac

Sample PAC template

You can download a starter PAC template here.

Adding domains to your PAC file

Now that we’ve gone through the basic components of a PAC file, let’s start adding multiple rules.

Note: Make sure to replace YOUR_PROXY_FQHN with your own FQHN and PORT with your own Proxy Port #.

Sample PAC file – Proxy Yes List
      // This PAC file only proxies what is in proxy_list

      function FindProxyForURL(url, host) {
        // Variables defined for Proxy=Yes and Proxy=No
        var proxy_yes = "PROXY YOUR_PROXY_FQHN:PORT";
        var proxy_no = "DIRECT";
        // List of all domains you want to Proxy  
        var proxy_list = Array(
        "*.google.com/*",
        "*.youtube.com/*",
        "*.yahoo.com/*",
        "*.bing.com/*"
        );
        
        // This goes through the list of domains above for the request 
        // to see if it matches anything in the List
        // If the reuqest matches a domain in the list above, 
        // the request will be proxied
        for(var iter = 0; iter < proxy_list.length; ++iter) {
          if(shExpMatch(url, proxy_list[iter])) {
            return proxy_yes;
          }
        }
        
        // DEFAULT RULE: All other traffic, send direct.  
        return proxy_no;
      }
Sample PAC file – Proxy No List
      // This PAC file proxies everything that is NOT in the no_proxy_list

      function FindProxyForURL(url, host) {
        // Variables defined for Proxy=Yes and Proxy=No
        var proxy_yes = "PROXY YOUR_PROXY_FQHN:PORT";
        var proxy_no = "DIRECT";
        // List of all domains you want to Proxy
        var no_proxy_list = Array(
        "*.bankofamerica.com/*",
        "*.bank.com/*",
        "*.yourschooldomain.com/*",
        );
        
        // This goes through the list of domains above for the request 
        // to see if it matches anything in the List
        // If the request matches a domain in the list above, 
        // the request will be proxied
        for(var iter = 0; iter < no_proxy_list.length; ++iter) {
          if(shExpMatch(url, proxy_list[iter])) {
            return proxy_no;
          }
        }
        
        // DEFAULT RULE: All other traffic, send direct.
        return proxy_yes;
      }     

These two examples above represent the same concepts, the only difference is that one has you send to proxy the items in the array and send all other traffic direct, and the other has you send direct the itmes in the array and to proxy all other traffic.

Let’s break the new components of these PAC files down.

Adding an Array

To make it easier to maintain your PAC file over time, as you will likely add entries to it as you go, it is easiest to create an array (a list) of all the domains you want to Proxy (or exclude from Proxy).

To add an array:

  var no_proxy_list = Array(
  "domain.com"
  );

You need to put a comma , after every item in the array except the last item in the array’s list.

Note: If you leave a comma at the end of the last item in the array list your file will produce an error and will not work properly.

Running through the Array

Once you’ve added the array, you will need to add some code to have the URL request run through the array.

To run through an array of URLs that should not be proxied:

  for(var iter = 0; iter < proxy_list.length; ++iter) {
    if(shExpMatch(url, proxy_list[iter])) {
      return proxy_no;
    }
  }

Common Proxy Domains

There are certain domains that schools are always looking to proxy. The list below represents the most common requests that Lightspeed gets.

  // List of all domains you want to Proxy
  var proxy_list = Array(
  // Google
  "*.google.com/*",
  "*.google.co/*",
  "*gstatic.com*",
  "*.googlevideo.co*",
  "*.googlevideo.com*",
  "*.ytimg.com/*",
  // Search Engines
  "*.yahoo.com/*",
  "*.bing.com/*",
  // Video Sites
  "*.youtube.com/*",
  "*.vimeo.com/*",
  // Social Media Sites
  "*facebook.com/*",
  "*pinterest.com/*",
  // Add Your Additional Domains Here
  //
  // Lightspeed Systems
  "*.lightspeedsystems.com/*"
  );

Starter PAC files

We have two domain list starter files for you to build your PAC files from.
Proxy Certain URLS
Send Direct Certain URLs

Adding On/Off Network Rules to your PAC file

In addition to setting up rules based on URLs, you can setup rules based on being on network versus off network.

Sample PAC file – Proxy Selectively On Network, Proxy All Off Network

Note: Make sure to replace YOUR_PROXY_FQHN with your own FQHN and PORT with Port#. Make sure to repalce 000.000.00.00 with your FQHN’s Internal IP address.

      // DESCRIPTION: This PAC file proxies everything OFF network (relative to the proxy sever)
      //              and proxies selectively while ON network
      function FindProxyForURL(url, host) {
        
        // Variables defined for Proxy=Yes and Proxy=No
        var proxy_yes = "PROXY YOUR_PROXY_FQHN:PORT";
        var proxy_no = "DIRECT";
        
        // If your FQHN is your Internal IP address, proxy the following list (array)
        if(dnsResolve("YOUR_PROXY_FQHN") == "000.000.00.00") {

          var proxy_list = Array(
            // Google
            "*.google.com/*",
            "*.google.co/*",
            "*gstatic.com*",
            "*.ytimg.com/*",
            // Search Engines
            "*.yahoo.com/*",
            "*.bing.com/*",
            // Video Sites
            "*.youtube.com/*",
            "*.googlevideo.com*",
            "*.googlevideo.co*",
            "*.vimeo.com/*",
            // Social Media Sites
            "*facebook.com/*",
            "*pinterest.com/*",
            // Add Your Additional Domains Here
            //
            // Lightspeed Systems
            "*.lightspeedsystems.com/*"
          );
          
          // This goes through the list of domains above for the request 
          // to see if it matches anything in the List
          // If the request matches a domain in the list above, 
          // the request will be proxied
          for(var iter = 0; iter < proxy_list.length; ++iter) {
            if(shExpMatch(url, proxy_list[iter])) {
              return proxy_yes;
            }
          }

          // For all other on network traffic, DO NOT proxy
          return proxy_no;
        }

          // For all traffic off network, DO proxy
            else {
              return proxy_yes;
            }
      }
    

In the example above when the device is On Network (meaning the FQHN is directing to the Internal IP address) it will only proxy items in the proxy_list. When the device is Off Network it will proxy everything.

Let's break the new components of this PAC file down.

Internal Network Rule

If your FQHN has been set up properly then it will resolve to an Internal and External IP. So when the FQHN is requested by a device On Network, it directs to the Internal IP. When the FQHN is requested by a device Off Network, it directs to the External IP.

Learn more about FQHN Setup

To add a rule to check for IP:

  if(dnsResolve("OUR_PROXY_FQHN") == "000.000.00.00"){
    //All the rules that you want to have for your Internal IP should go in here
  }
  else {
    //Rules for everything Off Network go here
    return proxy_yes;
  }

The dnsResolvefunction is what you need to call in order for the PAC file to check IP. In the example above you need to make sure that the IP, listed above as 000.000.00.00 is your Internal IP for your FQHN.

Note: We highly recommend that when building a more advanced PAC file that you test manually. The more complex the PAC file, the more chances for errors. A small and simple error can keep your devices from accessing the internet, which in some instances can force you to put hands on each and every device that you have pushed the PAC file to in order to remedy.

Starter PAC files

We have two advanced files for you to build your own Network Rules PAC files from.
Selectively Proxy On Network, Proxy Everything Off Network
Proxy Everything On Netowrk, Selective Proxy Off Network

Manually Testing PAC

We suggest that you test a PAC file prior to mass deployment as a syntax error in this file could cause disable the internet connection on devices and the make them impossible to remotely manage.

Testing can be done manually, as well as through a variety of third-party automated testing software.

You can find your PAC file URL by navigating to Web Filter > Proxy Server under PAC Files. 

Testing on an iOS device

1. From the desktop, click on Settings. Click on Wi-Fi.

2. Click on your wireless connection.

3. Change the value of HTTP Proxy to Auto.

4. Type in the address of your proxy.pac file into the URL field.

Testing on a Windows device (Chrome)

1. Open Chrome and click on the Chome Menu and then Settings.

2. Scroll down and click Show Advanced Settings.

3. Scroll down to Network and click Change proxy settings…

4. The Internet Properties window will pop up. Click on LAN settings.

5. The Local Area Network (LAN) Settings window will pop up. Check the box next to Use automatic configuration script and enter your PAC file URL into the Address space. Click OK.

Setting Up Selective Proxy

The following step illustrate how to setup Selective proxy:

How to Upload PAC file to Rocket

1. Click Web Filter, then click Proxy Server.

2. On the Proxy Server page navigate to Forward Proxy > PAC Files.

3. In the PAC Files grid, click the green “+” icon. This action opens the following page:

4. In the Upload PAC File form, click Browse and select the PAC file to upload from your computer.

5. Enter a brief description, then click Save to upload the PAC file, or click Cancel to discard your changes and return to the previous page.

Note: To delete (permanently remove) a PAC file, mouse over the item you wish to remove, then click the X on the right side of the row. You will be prompted to confirm the action.
Note:  Click the name to download the PAC file. It will automatically be downloaded onto your computer.

Push Trusted CA Certificates to all Devices

In order for proxying to be a smooth experience, it is necessary for the devices being proxied to trust your proxy by adding the Web Filter’s proxy SSL certificate to your devices. In order to do that you will first need to access your proxy certificate from your Web Filter.

You can access your certificate by navigating to Settings > Appliance > SSL Certificates > Download Links. Click Download  or navigate to the URL to download your certificate.

 

Pushing an SSL certificate to several devices at once:

Pushing an SSL certificate to BYOD devices:

You can access individual instructions for pushing SSL certificates to BYOD devices by navigating to:
YOURDOMAIN.com/lsaccess/proxycerthelp (replace YOURDOMAIN.com with the URL of your Rocket.)
This pathway includes instructions for all major operating systems and web browsers.

Troubleshooting

PAC files can sometimes cause headaches.  There are a lot of moving pieces to deploy a Selective Proxy solution.  Below are some of the most common issues.

Your Web Browser is hanging or timing out (connection failure)

  • Check to make sure that your FQHN is resolving both internally and externally
  • Check to make sure that you entered your FQHN correctly in your PAC file
  • Check to make sure your Firewall port is open
  • Check to make sure that you entered your Firewall port correctly in your PAC file
  • Make sure that they link to your PAC file is entered correctly on your browser/device/MDM

Your PAC file doesn’t seem to be sending requests to the proxy

  • Check your PAC file for any javascript/syntax errors
  • Check your PAC for spelling errors
  • Trying entering your PAC file URL into a browser URL bar and see if it downloads, if it doesn’t you have an issue with your PAC file URL/FQHN

Your devices are not getting the appropriate rule set

  • This is likely not an issue with the PAC file itself, but with your Proxy Authentication