miércoles, 14 de mayo de 2008

Tutorial: Probar un proxy a través de un tunel SSH

Inicio hoy una serie de tutoriales que espero sean del agrado de los visitantes. La verdad, no quería que este blog terminara siendo un típico recetario técnico, pero como habrán visto en mis últimos cuatro artículos, es casi en lo que se ha convertido... A mis lectores no técnicos, les prometo publicar algo divertido en breve.

A los técnicos, espero que disfruten de este tutorial, y espero tener tiempo de agregar alguno que otro sobre otras nimiedades similares de vez en cuando.

Tutorial: Probar un proxy a través de un túnel SSH

¿A quién no le ha pasado que un cliente le mande un mensaje de correo que dice "no tengo internet", y no le dá más pistas que "me aparece un cartelito en el internet explorer y no puedo abrir ningún sitio..."?

(Si, dije bien, el usuario dice NO tener internet, pero manda un mensaje de correo avisando del problema... (¿¡!?) recuerden que se trata de un pobre usuario, quien seguramente no sabe que para poder enviar correo, necesita internet, y el extraño hecho de que pueda enviar dicho mensaje de forma exitosa no sirve para demostrarle que en realidad el problema NO es que no tiene internet...)

Bueno, cuando eso pasa, ya sabemos (por simple razonamiento deductivo o por descarte) que el problema está en otra parte. Como el usuario no nos envió el mensaje que aparece en el "cartelito del internet explorer", tenemos que deducir que no es capaz tampoco de realizar un diagnóstico apropiado, aún indicándole telefónicamente cuales pasos debe seguir (de hecho, he intentado explicarle a un usuario como intentar un diagnóstico basándome en herramientas simples y técnicas sobrádamente fáciles de ejecutar, como por ejemplo, hacer un telnet al puerto 80 de www.sitioquefalla.com, teclear "HEAD / HTTP/1.0" y apretar dos veces seguidas la tecla ENTER, obteniendo como único e invariable resultado la pérdida de tiempo más atróz y el más terrible y atormentador de los sentimientos de defraudación e impotencia que haya sentido...), he terminado siempre recurriendo a técnicas totalmente unilaterales (sé que yo no me voy a equivocar en mis propias instrucciones), de las cuales siempre el resultado es el deseado: saber qué pasa sin ayuda ninguna del usuario.

Y bueno, en este caso, veremos cómo hacer para saber si el problema en cuestión es causado por el proxy, haciendo lo mismo que hace un usuario de la red detrás del firewall que vamos a diagnosticar.

Normalmente, utilizo SSH para conectarme a los firewalls de los clientes remotamente, lo cual me permite diagnosticar casi de primera mano cualquier problema de la red, incluso en algunos casos problemas físicos. En este caso, el firewall es un linux al cual me conecto remotamente vía SSH.

Esta vez, para poder diagnosticar el proxy una vez conectado, necesito saber qué implementación es, así que me conecto al firewall del cliente y reviso los procesos del mismo:


root@fw-cliente:~ # ps xa
[...]
10508 ? Ss 0:00 squid
10510 ? R 1:03 (squid)
[...]


Bueno, tenemos Squid como implementación, lo cual es bastante común en mis instalaciones. Además, es altamente relevante el hecho de que el proxy está en ejecución en este momento, así que puedo descartar un fallo de funcionamiento que lo haya hecho caer. También deduzco, por el tiempo real de ejecución, que no está generando demasiada carga en el sistema, lo cual también es un indicativo de buena salud del proceso.

Reviso los logs, los cuales no parecen mostrar ningún problema, así que el misterio se complica. Normalmente, todos los problemas que pueda tener el proxy, suelen quedar registrados en los logs (en la mayoría de las implementaciones de Squid están el /var/log/squid/), lo cual terminaría rápidamente con el diagnóstico (y con este tutorial), pero en este caso, resulta que el usuario no puede entrar al sitio http://support.microsoft.com (si leyeron mi artículo anterior, se darán cuenta de qué hablo), y en los logs no queda ningún registro del problema, sino que, al contrario de lo que pudieramos pensar, los logs demuestran que el proxy vive despreocupadamente su vida totalmente ignorante de la situación lamentable de los servidores de Microsoft... así que tengo que seguir investigando.

Ahora veamos en qué puerto está configurado este squid, para lo cual tenemos dos opciones, o revisar la configuración, o ver qué puerto está "escuchando" este programita. Opto por la segunda opción, que me resulta más rápida y entretenida:

root@fw-cliente:~ # netstat -npl --inet
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:50393 0.0.0.0:* LISTEN 5347/sshd
tcp 0 0 192.168.0.1:3128 0.0.0.0:* LISTEN 10510/(squid)
[...]


Y luego, dependiendo de en qué sistema operativo estoy en ese momento (si estoy en la casa de algún amigo o en un cybercafé, probablemente no tenga muchas opciones...), veo de configurar una segunda conexión SSH, pero declarando un túnel en la misma que apunte al puerto del proxy.

En Windows, utilizo PuTTY (de Simon Tatham, el mismo autor de Palm Puzzles, un adictivo set de puzzles que entretienen mis momentos de ocio cuando estoy en viajes), un excelente programa Open Source para varias plataformas y que maneja conexiones SSH y Telnet.


Así que configurar un túnel en PuTTY es tán simple como especificar en "Source port" el puerto que quiero (uso el mismo que usa el proxy, dado que no está ocupado en la máquina en la que estoy trabajando), y en "Destination", pongo la dirección IP y el puerto del proxy, separado por ":". Luego presiono el botón "Add" y ya está listo. Si ya teníamos la conexión con el firewall abierta y realizamos una "reconfiguración", no hay que hacer más nada, de lo contrario, si estamos configurando una nueva conexión, una vez aplicada la configuración del túnel, debemos conectarnos al firewall para que surta efecto.

En Linux/Unix, con OpenSSH la cosa es simple:

gcp@ereshkigal~: $ ssh -p 50393 -L 3128:192.168.0.1:3128 ops@fw-cliente.cliente.net
Password:
Last login: Wed May 14 11:32:47 2008 from gcpsite.homelinux.net
Welcome to FW-Cliente (There's no place like 127.0.0.1!)
ops@fw-cliente:~ $


Ese garabato significa algo así como: conectarse vía SSH al equipo "fw-cliente.cliente.net" utilizando el usuario "ops", a través del puerto 50393 (vean arriba el listado que resulta de la ejecución del netstat para darse cuenta de en qué puerto escucha el sshd), y crear un túnel Local desde el puerto origen 3128 de mi equipo, hacia el puerto destino 3128 de la dirección remota 192.168.0.1.

Una vez configurado el tunel, simplemente configuro el navegador que tenga a mano para que utilice el proxy local. En Internet Exploder:


En Firefox:



Nótese que uso la dirección "localhost" (que es "mi punta" del túnel) y el puerto 3128, que es el mismo que configuré en el PuTTY/SSH. Esto significa que cuando intente navegar con esa configuración, estaré utilizando en realidad el proxy del firewall remoto, lo cual me ayudará a probarlo como si estuviera en la misma red de los usuarios detrás de dicho firewall. De eso se trata todo esto... :-)

Luego, ponemos a desplegar los logs del Squid en una consola del firewall para poder verlos avanzar mientras intentamos navegar (y descubrir otros potenciales problemas) y comenzamos la prueba:

root@fw-cliente:~ # tail -f /var/log/squid/access.log | grep " 192.168.0.1 "
1210813210.057 2386 192.168.0.1 TCP_MISS/200 34612 GET http://support.microsoft.com/ - DIRECT/65.54.166.122 text/html
1210813212.191 1615 192.168.0.1 TCP_MISS/200 49840 GET http://support.microsoft.com/common/script/gsfx/common.js? - DIRECT/65.54.166.122 application/x-javascript
1210813214.227 548 192.168.0.1 TCP_MISS/200 11558 GET http://support.microsoft.com/common/script/gsfx/search.js? - DIRECT/65.54.166.122 application/x-javascript
[...]


Nótese que la dirección IP del cliente del proxy (nosotros) es la misma dirección interna del firewall, dado que el túnel termina allí. Esto puede resultar útil para el filtrado de la salida del tail (lo que hice con el grep) y así evitar que la consola se vea plagada de mensajes que le corresponden a conexiones de otras direcciones IP de la red lan que también están navegando y que no queremos ver en ese momento.

También hay que tomar en cuenta que cuando usamos políticas extremadamente restrictivas, la IP del mismo proxy podría no estar en la ACL donde se definen las IP de la LAN permitidas, así que si ven mensajes TCP_DENIED/400 durante la prueba, el problema probablemente sea que la IP interna del firewall no está en la lista de control de acceso que tiene permiso de navegar... Supongo que se darán cuenta de otros detalles cuando ejecuten la prueba.

Ah, un detalle más: Esta técnica se puede utilizar para cualquier servicio y para cualquier proxy que se quiera diagnosticar de la misma forma. Las posibilidades son inagotables, así que no duden en jugar con los túneles para lograr otras formas de "entretenimiento" basadas en esta técnica.

Y bueno, por ahora es todo. Creo que es un buen comienzo y espero que les haga provecho.

Happy hacking!

1 comentario:

Rubencho dijo...

Que bueno este truco para revisar squid en servidores remotos
Muchas gracais

 
Gustavo Castro

Crea tu insignia