Introducción
Hace un tiempo hablábamos de
Cómo Utilizar los Archivos de Configuración Automática de Proxy (PAC), pero parece ser que este formato tiene algunos problemas -principalmente por las dudas que me han ido enviando- así que vamos a ver Cuáles son los problemas de una configuración automática (PAC) y cómo solucionarlas
Archivos PAC
Ya hemos hablado de cuál es su formato, pero vamos a hacer un pequeño repaso. Un archivo PAC, simplemente es una función JavaScript que devuelve si es necesario utilizar un Proxy -y cual- para una URL determinada.
El Problema
Nuestro principal problema viene dado con los equipos móviles, es decir, aquellos que necesitan diferentes configuraciones, veamos un ejemplo:
"Un equipo portátil que se conecta desde La Oficina, VPN y Wifi públicas"
Este equipo, deberá tener las siguientes configuraciones: Proxy 01 para la oficina, Proxy 02 para VPN y SIN Proxy para Wifi públicas
Si hemos definido un Archivo PAC que -por ejemplo- está en $HOME/proxy.pac tendremos un problema ya que no podemos
identificar cuándo y dónde se encuentra <JavaScript Nos permite saber la IP local, pero cómo sabemos si esa IP es nuestra?>
La Solución
Para solucionar este problema está
perl que nos va a aportar las funciones necesarias para poder crear un archivo PAC
bajo demanda en función de
quién y desde dónde -es cierto que cualquier lenguaje de script nos permite esto
php, jsp, pero con yo he optado por
perl-
Como podemos ver en el gráfico, necesitamos tener un DNS -o utilizar el archivo /etc/hosts- para resolver la dirección proxy.test.com de forma
interna y un
pequeño servidor Web -en mi caso Apache- capáz de ejecutar
scripts.
Además, nuestro archivo de configuración <pac> estará ubicado en una dirección web y éste se creará mediante un
script dinámicamente. Por último, necesitaremos que el DNS público resuelva también el host, en mi caso, la URL es http://proxy.test.com/cgi-bin/proxy-conf.sf
Instalación del Sistema de Configuración
Lo primero que debemos hacer es Instalar
Apache en Solaris 10 y le añadimos soporte para ejecución de <cgi>, para ello, editaremos el archivo $APACHE_HOME/conf/httpd.conf en la sección de <mod_mime.c> añadiremos la siguiente entrada
AddHandler cgi-script .sf
A continuación definiremos el VirtualHost
<VirtualHost *:80>
ServerName proxy.test.com
DocumentRoot /www/proxy.test.com
ServerAdmin support@test.com
# Script
ScriptAlias /cgi-bin /www/proxy.test.com/cgi-bin
ErrorLog logs/proxy.test.com-error_log
CustomLog logs/proxy.test.com-access_log combined
</VirtualHost>
Verificamos y recargamos Apache
# /opt/www/apache-1.3.41/bin/apachectl configtest
Syntax OK
# /opt/www/apache-1.3.41/bin/apachectl restart
Creación del script en Perl
Vamos a crear un pequeño script en perl que, básimanente buscará la dirección IP origen, y en función de cuál sea, devolverá una respuesta a otra. En el ejemplo, si la dirección IP es 192.168.0.0/16 entonces, devolverá el proxy "PROXY-01.test.com", en caso contrario el acceso será DIRECT
# vi /www/proxy.test.com/cgi-bin/proxy-conf.sf
#!/usr/bin/perl -w
use strict;
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
# #################################################
# PROYX-CONF.SF
#
# Description:
# - script encargado de configurar los accesos de los clientes
# hacia los diferentes proxy's y/o las excepciones necesarias
#
# - la validacion de la configuracion se hace mediante el uso
# de reglas.
# #################################################
# #################################################
# INFO SISTEMA
# #################################################
my ($cgiversion) = "ProxyAutoconf 3.0.0b_1 on Producction on 03.MAR.2008 by Urko";
# #################################################
# inicio del sistema de configuracion
# #################################################
## escribimos el tipo de archivo y las configuraciones necesarias
print "Content-type: application/x-ns-proxy-autoconfig\n\n";
# SOURCE_IP
my ($sourceip) = $ENV{REMOTE_ADDR};
# escribimos un pequeno comentario
print "// $cgiversion\n";
print "// (c) SafeChildren S.L. 2005-2010\n";
# generamos las cabeceras de la funcion
print "function FindProxyForURL(url, host) {\n";
# generamos el cuerpo en funcion de la IP origen
# si esta en la LAN 192.168.0.0/8
my($islan) = rindex($sourceip, "192.168");
if ( $islan >= 0) {
print "return \"PROXY proxy-01.sfchildren.com:3128\";\n";
}else {
print "return \"DIRECT\";\n";
}
# generamos el fin de la funcion
print "\n}\n\n";
Ahora vamos a comprobar su funcionamiento, primero desde un
host de la LAN <192.168.0.0/16> y luego desde
Internet
$ wget http://proxy.sfchildren.com/cgi-bin/proxy-conf.cgi
--16:14:25-- http://proxy.sfchildren.com/cgi-bin/proxy-conf.cgi
=> `proxy-conf.cgi'
Resolving proxy.sfchildren.com... 10.4.7.17
Connecting to proxy.sfchildren.com|10.4.7.17|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/x-ns-proxy-autoconfig]
[ <=> ] 184 --K/s
16:14:25 (10.26 MB/s) - `proxy-conf.cgi' saved [184]
$ more proxy-conf.cgi
// ProxyAutoconf 3.0.0b_1 on Producction on 03.MAR.2008 by Urko
// (c) SafeChildren S.L. 2005-2010
function FindProxyForURL(url, host) {
return "PROXY proxy-01.sfchildren.com:3128";
}
Y ahora desde una pública
$ wget http://proxy.sfchildren.com/cgi-bin/proxy-conf.cgi
--16:14:25-- http://proxy.sfchildren.com/cgi-bin/proxy-conf.cgi
=> `proxy-conf.cgi'
Resolving proxy.sfchildren.com... 193.24.37.17
Connecting to proxy.sfchildren.com|193.24.37.17|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/x-ns-proxy-autoconfig]
[ <=> ] 184 --K/s
16:24:35 (1.59 MB/s) - `proxy-conf.cgi' saved [184]
$ more proxy-conf.cgi
// ProxyAutoconf 3.0.0b_1 on Producction on 03.MAR.2008 by Urko
// (c) SafeChildren S.L. 2005-2010
function FindProxyForURL(url, host) {
return "DIRECT";
}
Conclusión
Es cierto que el uso de Proxy PAC puede darnos
algún que otro problema -principalmente con Java- pero si somos capaces de crear un entorno donde los usuarios no se vean afectados, esto nos ayudará mucho en nuestras tareas de administración.
Aunque en este
post yo os he puesto un
pequeño script, éste puede ser tan complejo como queramos, por ejemplo: En función de las Horas, Delegaciones, Usuarios, ... y de esta forma parametrizar de forma eficiente nuestras salidas a Internet.
A modo de
anécdota sólo deciros que la implemntación de Java 1.5.x de ProxyPAC no era del todo correcta y fallaba, así que tuve que hacer un
apaño para que si era Java devolviese el nombre del proxy sin más, era algo así -no está completo-
sub getRequestAgent () {
my($agent) = $ENV{HTTP_USER_AGENT};
my($isagent) = rindex($agent,"Mozilla");
if ( $isagent != -1 ) {
return "browser";
} else {
return "java";
}
}
sub createFindProxyBody()
{
my($arg1) = @_;
my($browser) = &getRequestAgent();
# si pone "java" entonces devolvemos el PROXY sin mas
if ( $browser eq "java" ) {
# ponemos el proxy de Java
print "return \"PROXY sol10-proxy-02.sfchildren.com:3128\";\n";
return 0;
}else {
my($sourceIP) = $arg1;
# esta aquí y no es JavaWS
&createHTTPS();
&createCommonExceptions($sourceIP);
&createCommonRules($sourceIP);
}
}
Referencias