Skip to content

Dynamic proxy auto configuration

wordpress meta

title: 'Dynamic Proxy Auto Configuration'
date: '2012-11-12T20:37:22-06:00'
status: publish
permalink: /dynamic-proxy-auto-configuration
author: admin
excerpt: ''
type: post
id: 85
category:
    - PHP
    - Squid
tag: []
post_format: []

Some businesses still rely on the the Proxy auto-config file format originally designed by Netscape in 1996. I have had instances where the javascript can get pretty complex and long. Plus sometimes I have to rely on the javascript to report the IP address of the client accurately. Sometimes the browser reports 127.0.0.1 or even IPv6 addresses. Meaning the rules in the PAC file becomes useless since they are making decisions on where to direct the client based on its subnet.

One other idea is to use PHP to generate the javascript dynamically. For one you can really simplify the code by reading your lists from files into arrays dynamically but also you can correctly capture the IP address of the client.

Example: I simplified it a little for readability and its been a while since I played with this so don't recall if this one actually was a working copy.

<?php
    $proxy = "mainsquid001.domain.com";
    $port  = "3128";

    header ("Content-type: application/x-ns-proxy-autoconfig");
    header ("Date: " . gmdate('D, d M Y H:i:s \G\M\T', time ()));
    header ("Last-Modified: " . gmdate('D, d M Y H:i:s \G\M\T', time ()));
    header ("Expires: " . gmdate('D, d M Y H:i:s \G\M\T', time () + 60 * 30));

    #echo "// Request from: " . $_SERVER ['REMOTE_ADDR'] . "\n";
    #echo "// OS: " . $_SERVER ['HTTP_USER_AGENT'] . "\n";

    $netProxyMap = array('172.16'=>'uksquid001','172.19'=>'casquid001');
    // I removed a lot of subnets from above array for readability.
    $ipA = explode(".", $_SERVER ['REMOTE_ADDR']);
    $bNetPart = $ipA[0] . "." . $ipA[1];
    $cNetPart = $bNetPart . "." . $ipA[2];

    if ( array_key_exists($cNetPart, $netProxyMap) ) {
      $proxy = $netProxyMap[$cNetPart] . ".domain.com";         
    } else {
    if ( array_key_exists($bNetPart, $netProxyMap) ) {
          $proxy = $netProxyMap[$bNetPart] . ".domain.com";         
        }
    }
?>

// Proxy Servers
var proxy = "PROXY <?php echo $proxy; ?>:<?php echo $port?>;";
var dmzproxy = "PROXY dmzproxy.domain.com:3128;";

// Proxy Logic
function FindProxyForURL(url, host)
{
    if (url.substring(0,6)=="https:") { return "DIRECT"; }

    else if (shExpMatch(url,"*.google.com*") ||
      shExpMatch(url,"*.gotomeeting.com*") 
      { return "DIRECT"; }

    else if ((host == "localhost") || (shExpMatch(host, "localhost.*")) || (host == "127.0.0.1")) 
     { return "DIRECT;"; }

    else if ( (host == "hostedext1.domain.com") || (host == "hostedext2.domain.com") 
     { return olddmzproxy; }

    else if ((host == "www.domain.com") || (host == "dmzapp1.domain.com")  
     { return dmzproxy; }

    else if (shExpMatch(url,"http://domain.com/")) { return dmzproxy; }

    else if (dnsDomainIs(host, ".domain.com")) { return "DIRECT;"; }

    else if (isPlainHostName(host)) { return "DIRECT;"; } 

    else return proxy;
}