Autoconfiguración de proxy por ubicación con proxy.pac

Uno de los quebraderos de cabeza que me ha tenido durante bastante tiempo dándole vueltas, es la configuración de los navegadores de forma automática para la salida a internet a través de proxy, y con la particularidad de tener varios proxies en distintas ubicaciones con acceso a internet.

La solución tenía que atender el supuesto de que un enlace a internet o proxy estuvieran caídos y el cliente automáticamente pueda salir a través de otra línea en otra ubicación.

La forma más eficiente que he encontrado es la de crear un archivo proxy.pac en perl que el navegador consulta y éste le devuelve el archivo correctamente configurado según su ubicación.

Otras implementaciones de autoconfiguración fallan al no obtener correctamente la dirección IP del equipo, pues en casos de clientes con Windows 7 la devolvía en formato IPv6, añadiendo que según qué navegador utilizara devolvía una IP que, en unos casos correspondía a la interface de loopback y en otros el código javascript no era capaz de reconocer

Bueno, para que el script se ejecute es necesario tener un servidor web (Apache, etc.) y la entrada para reconocer los archivos .pac:

AddType application/x-ns-proxy-autoconfig .pac

El script hay que guardarlo y hacerlo ejecutable (en el caso de linux) en la ruta cgi-bin del servidor web:

#!/usr/bin/perl

# Asignamos a una variable la direccion ip del cliente
$remote_addr = $ENV{'REMOTE_ADDR'};
$srv_host = $ENV{'SERVER_NAME'};

# Dependiendo de la ip del cliente seleccionamos el orden de los proxies a utilizar
if ( $remote_addr =~ /192.168.1./ || $remote_addr =~ /192.168.2./ ){
        $proxy = "PROXY proxy1.cygnux.org:8081; " .
                "PROXY proxy2.cygnux.org:8081; DIRECT";

	# Variable para imprimir la ubicacion
        $ubicacion = "Delegacion 1";
} else {
        $proxy = "PROXY proxy2.cygnux.org:8081; " .
                "PROXY proxy1.cygnux.org:8081; DIRECT";

	# Variable para imprimir la ubicacion
        $ubicacion = "Delegacion 2";
}

print <<"EOI";
Content-type: application/x-ns-proxy-autoconfig

// Proxy CYGNUX
//
// proxy.pac autoconfigurado para $ubicacion desde $srv_host
//
// IP Cliente: $remote_addr

function FindProxyForURL(url, host)
{
        // Excepciones por pertenecer a las redes locales
        if (isPlainHostName(host) ||
            isInNet(host, "192.168.0.0","255.255.0.0") ||
            isInNet(host, "172.16.0.0","255.255.0.0") ||
            isInNet(host, "10.0.0.0","255.0.0.0") ||
            isInNet(host, "127.0.0.1","255.255.255.255")){
                return "DIRECT";
        }

        return "$proxy";
}
EOI

Espero que os sirva 😉

4 thoughts on “Autoconfiguración de proxy por ubicación con proxy.pac

  1. Ales

    Salvo por el IF que controla si está en una dirección de IP de rango privado, lo demás tiene buena pinta.

    Me refiero a esta parte:
    isInNet(host, “172.16.0.0”,”255.255.0.0″)

    La red privada es 172.16.0.0/12 y no /16, por lo que lo correcto sería:
    isInNet(host, “172.16.0.0”,”255.240.0.0″)

    Un saludo

    Reply
    1. nuxsmin Post author

      Gracias por el comentario Ales!!

      Es cierto, las subredes de clase B tienen una máscara /12, pero no la he usado ya que no era necesario para el entorno donde se aplica el script.

      Está en producción y funciona perfectamente en todos los navegadores.

      Saludos

      Reply
    1. nuxsmin Post author

      Hola!…gracias!

      Para omitir el proxy tienes que establecer la variable a DIRECT, es decir, declarar una sentencia if que contenga dichas subredes y la variable que indica el proxy tiene que tener el valor DIRECT.

      Saludos

      Reply

Leave a Reply to nuxsmin Cancel reply

Your email address will not be published. Required fields are marked *

CAPTCHA Image

*