2008-10-10

Saltar Firewalls usando OpenSSH

En la mayoría de instituciones educativas, empresas, bibliotecas, etc. Hay un Firewall (por lo general un ISA Server) que restringe el acceso a Internet a determinados puertos, esto lo hacen con el fin de evitar que los usuarios que se encuentran por dentreo del Firewall accedan a apliciones y protocolos que el Administrador ha marcado como inseguros o que consumen mucho ancho de banda, como por ejemplo MSN Messenger, Radio por Internet o juegos en línea (Como Lineage II).

Para todos nosotros los que nos encontramos atrapados dentro de los Firewall esto es frustante, pero se acabó. Ya no hay que preocuparse por eso, hay una forma de saltar cualquier Firewall y no despierta ninguna sospecha* ya que utiliza los puertos 80 (HTTP) y 443 (HTTPS) para establecer la conexiones, todo parece una inocente conexión a una página de Internet.

* Siempre y cuando el Firewall que estamos intentando saltar no tenga un analizador de paquetes. Ni nadie se extrañe por el continuo flujo de datos a través de HTTP (aunque esto podría ser por ejemplo un vídeo de YouTube).

Bueno, para todos ustedes los impacientes que están leyendo va ahora si el cómo hacerlo:

Que se necesita:
  1. Tener un equipo por fuera del Firewall que tenga instalado OpenSSH y en el que tengamos credenciales de acceso. (Yo uso el PC de mi casa).
  2. Tener un cliente SSH en el equipo que está dentro del Firewall desde el que nos queremos conectar al protocolo / servicio restringido.
¿Nada del otro mundo verdad?

Preparando el equipo Relevador

El equipo relevador es el equipo que tenemos por fuera del Firewall, hay que instalarle el OpenSSH Server y configurarlo para servir a través del puerto 80. Esto se debe a que el Firewall solo nos permite conexiones a ese puerto.

El OpenSSH se puede descargar de Internet de forma gratuita, si el equipo relevador es un equipo Linux pues bastara con buscar el paquete OpenSSH Server en el administrador de paquetes e instalarlo. Si se trata de un equipo con Microsoft® Windows® entonces se puede bajar el OpenSSH para Windows, que es un proyecto de código fuente abierto que está en SourceForge: http://sshwindows.sourceforge.net/

Una vez instalado el Servidor OpenSSH hay que configurarlo:

Configurar el Servidor OpenSSH (En windows)

Bueno, lo primero que hay que configurar es el puerto por el que servirá el servidor (valga la redundancia) como ya se dijo debe ser el puerto 80 como el OpenSSH por defecto sirve por el 22 hay que modificar esta configuración predeterminada, para hacerlo:
  1. Abrimos con el WordPad el archivo C:\Archivos de Programa\OpenSSH\etc\sshd_config
  2. En ese archivo localizamos la línea #Port 22 y debajo de ella agregamos la línea Port 80
El archivo debe quedarnos más o menos así:

# $OpenBSD: sshd_config,v 1.65 2003/08/28 12:54:34 markus Exp $

# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options change a
# default value.

#Port 22
Port 80
#Protocol 2,1
Protocol 2
#ListenAddress 0.0.0.0
#ListenAddress ::

[...]

Listo, ya está configurado el servidor para servir por el puerto 80, ahora lo único que resta es preparar el Key Based Authentication que es lo que nos permitira autenticar en nuestro servidor SSH (si no lo hacemos siempre nos negara el acceso), para hacerlo:
  1. Abrimos una consola y nos dirijimos a C:\Archivos de Programa\OpenSSH\bin\
  2. Allí escribimos estos comandos:
mkgroup -l >> ..\etc\group

y luego:

mkpasswd -l -u nombre_usuario >> ..\etc\passwd

Estos comandos preparan el key based authentication, lo que hace el primer comando es guardar la información de los grupos locales en el archivo ..\etc\group y el segundo crea un password para el usuario nombre_usuario en el archivo ..\etc\passwd.

[NOTA:] nombre_usuario debe ser un nombre de usuario de la máquina local, el nombre que usamos para iniciar sesión en Windows®. Después de esto el OpenSSH permitirá que nombre_usuario y solo nombre_usuario inicie una consola remota en la máquina, si queremos otro usuario pues simplemente ejecutamos el mismo comando con el otro nombre de usuario y ya.

Listo, eso es todo, ahora solamente hay que subir el servicio, para ello ejecutamos:

sc start "OpenSSHd"

Luego de eso el Servidor SSH estará corriendo en el equipo sirviendo por el puert 80.

Configurar el Servidor OpenSSH (En Linux)

Configurar el servidor OpenSSH en Linux es igual de fácil que en Windows, lo que hacemos es lo siguiente:

Localizamos el archivo sshd_config que se encuentra en /etc/ssh y lo editamos con permisos de super usuario, en el archivo vamos a ver algo similar a esto:

# Package generated configuration file
# See the sshd(8) manpage for details

# What ports, IPs and protocols we listen for
Port 22

[...]

Allí editamos la línea del puerto, en vez de 22 escribimos 80 o 443 según el puerto que podamos usar con nuestro ISP. Yo uso normalmente el 443 por que el 80 me lo tienen bloqueado.

Una vez que hemos editado el archivo debemos bajar y volver a subir el servicio del SSH Server, para hacerlo:

$ sudo /etc/init.d/ssh stop
$ sudo /etc/init.d/ssh start

Y listo. En linux no es necesario preparar la key-based authentication ya que el servidor SSH utiliza el sistema de autenticación del sistema operativo así que no hay que hacer nada más.

Hacer el Port Forwarding

Bueno, ahora si viene la parte divertida, conectarse a un puerto "prohibido", a partir de este punto estamos en la máquina que está dento del Firewall. Recordemos que en ese equipo debe estar instalado el cliente SSH. Si no tenemos permisos de instalación podemos buscar un cliente SSH que no lo requiera, no sé si el Putty pueda hacerlo poero valdría la pena probarlo (Posteen sus comentarios si lo intentan)

Para hacer esto más fácil de entender vamos a poner un ejemplo sencillo, digamos que queremos escuchar Anime Academy Radio dentro de la Universidad, normalmente eso no se puede por que el puerto está cerrado pero como ya tenemos nuestra máquina Relevadora por fuera del Firewall entonce si podemos.

Entonces, bueno, cuando entramos a la página de la estación descargamos un .m3u que básicamente nos apunta a la URL donde está el punto de publicación del servidor, la dirección donde apunta ese m3u es: rs1.animeacademyradio.net:8500

Tenemos que hacer que la máquina que está por fuera nos releve al puerto 8500 del servidor rs1.animeacademyradio.net entonces para eso ejecutamos este comando:

ssh ip_maquina -p 80 -l nombre_usuario -L 8500:rs1.animeacademyradio.net:8500

Escribimos nuestra contraseña y ya está, eso nos abre una consola remota y hace el Forwarding del puerto, ya voy a explicar como funciona, pero primero hace falta un paso, después de eso vamos a la página de Anime Academy Radio y hacemos clic en el link como siempre, la conexion fallará por que el proxy de la Universidad no permite conexiones al puerto 8500, entonces, en el WinAmp le damos clic derecho a la entrada de la lista de reproducción y seleccionamos Editar Entrada y ahi donde dice rs1.animeacademyradio.net escribimos localhost y volvemos a darle reproducir, ya debería funcionar.

[NOTA:] Se puede agregar la opción -N al comando para que no nos abra una consola remoto sino que solo haga el Port Forwarding, en Windows® igual la ventana de la consola quedará bloqueada entonces pues da como lo mismo.

Explicación

Bueno, ahora la explicación de lo que hicimos. En el comando que escribimos vemos lo siguiente:
  • ssh es el nombre del comando (no se necesita más explicacion)
  • ip_maquina es la IP (o en caso de que se tenga) el nombre de la máquina Relevadora
  • -p 80 es para decirle al SSH que se conecte al puerto 80 en ves de al puerto 22 (que es el puerto predeterminado)
  • -l nombre_usuario Es para decirle al OpenSSH que logee en la máquina remota con el nombre de usuario nombre_usuario. Si no se especifica esta opción el SSH logeara con el usuario actual.
  • -L 8500:rs1.animeacademyradio.net:8500 Esta es la parte teza del comando, lo que esta parte del comando le dice al OpenSSH es: Todos los paquetes que lleguen a la máquina local a través del puerto 8500 mandelos a la máquina remota (ip_maquina) y cuando lleguen allá digale al SSH Server que los mande a rs1.animeacademyradio.net en el puerto 8500. ¿Se entiende?
Así por ejemplo se pueden hacer otras cosas, digamos que por ejemplo tenemos un servidor de MySQL que se está ejecutando en nustro PC de la casa, pero claro, el cochino proxy de la universidad no nos permite conectarnos al puerto 3306 entonces:

ssh ip_maquina -p 80 -l nombre_usuario -L 3306:localhost:3306

Y listo, este comando a veces resulta un poco confuso pero lo voy a explicar en detalle: Le estamos diciendo a la máquina local, todo lo que le llegue por el 3306 mandelo a la máquina remota (ip_maquina) y digale al SSH Server que está allá que cuando llegue lo mande a localhost en el puerto 3306 ¿Localhost es la máquina donde ejecutamos el ssh o donde está el SSH Server? Es donde está el SSH Server, lo que colocquemos en la parte -L del comando ssh lo resuelve el sercvidor SSH y para el servidor SSH localhost es el pc donde se ejecuta.

De esta misma manera podemos redirigir cualquier puerto. Es muy util si se utiliza bien. El manual del SSH ofrece más información de como usar estas características, hay incluso otras opciones muy interesantes, como por ejemplo la opción -R, les recomiendo que la vean, por ahora voy a explicar como funciona la opción -L:

La opción -L tiene tres argumentos, por llamarlos así puerto local, destino y puerto remoto, estos argumentos se colocan separados por : así:

puerto_local:destino:puerto_remoto

Entonces: puerto_local es el puerto que el comando ssh escuchara en la máquina local. Cuando ejecutamos el comando ssh se abre un puerto en la máquina local y escucha por ahi, podemos constatarlo con un netstat -n -a. destino es la máquina FINAL a donde queremos acceder (donde está el servicio al que no podemos acceder por culpa del proxy). Recuerden que ese nombre o dirección la resuelve el Servidor SSH, por eso en el ejemplo del MySQL localhost resulta siendo la máquina donde está el SSH Server corriendo, y no donde ejecutamos el ssh.

Por ultimo el es el puerto_remoto puerto al que queremos conectarnos en la máquina FINAL.

Me lleva.... :C pero no quiero perder el puerto 80

A veces tenemos en nuestra máquina un servidor HTTP de verdad corriendo en el 80, en ese caso podemos usar el 443 (el HTTPS) para hacer que el OpensSSH Server sirva por ahi, en ese caso el comando del ejemplo quedaría así:

ssh ip_maquina -p 443 -l nombre_usuario -L 8500:rs1.animeacademyradio.net:8500

Noten el cambio en el -p.

Notese que esto del Port Forwarding permite conectarse al puerto que uno quiera en la máquina que uno quiera y parece que la conexión siempre para a través del puerto 80. Esto quiere decir (supongo que ya se habrán dado cuenta) que si uno tiene una máquina ejecutando el SSH Server por el puerto 80 no hay límite respecto a lo que se puede hacer, ¡no hay Firewall que pueda detenernos!

¡Tomen eso malditos de la DANIC!

Por ahora voy a dejar aquí, si tienen dudas o quieren mayores explicaciones me pueden escribir al correo electrónico o postear su comentario por aquí, estaré pendiente. También los que me conocen me pueden comentar por MSN.

Hay otros trucos en la bolsa por ahi pero ya no quiero escribir más por hoy, después postearé más.

Se cuidan

さようなら