24x7 Linux Página personal y profesional HTML 4.01 válido CSS válido
Túneles de aplicación con OpenSSH

Una de las muchas cosas que se pueden hacer con OpenSSH es crear túneles entre dos máquinas y enviar a través de estos túneles los datos de ciertas aplicaciones o protocolos que son inseguros, por enviar la información en claro por la red. Los únicos requisitos para configurar estos túneles son disponer en un extremo del cliente de OpenSSH ssh y en el otro del servidor sshd. Una limitación de los túneles de aplicación con OpenSSH es que, al menos de momento, sólo funcionan para protocolos basados en TCP, pero no para los basados en UDP.

Para tener un ejemplo concreto sobre el que explicar cómo configurar los túneles, supondremos que deseamos acceder desde una máquina llamada cliente a una máquina remota llamada servidor, en concreto desamos hacer consultas a la base de datos MySQL instalada en servidor desde cliente usando el programa mysql. MySQL, al menos hasta su versión 4.0.x, no soporta de manera nativa conexiones seguras mediantes SSL entre los clientes y el servidor, de manera que la identificación de los usuarios remotos y los datos de las consultas y las respuestas serían visibles a cualquier máquina de la red.

Supondremos que en cliente ya está instalado el programa cliente de MySQL mysql y que en servidor está instalado, configurado y funcionando el servidor de bases de datos. Sin embargo, y para demostrar de manera más fehaciente el funcionamiento de los túneles, sería recomendable (aunque no necesario) forzar al servidor mysqld a escuchar peticiones de la red únicamente en la dirección del localhost. Para ello, asegúrese de que en el archivo de configuración /etc/mysql/my.cnf tiene lo siguiente:

[mysqld]
# Comentamos la directiva "skip-networking" para que "mysqld" escuche en la red
# y no sólo en el "socket" local.
#skip-networking
bind-address = 127.0.0.1
port         = 5000

Si reiniciamos el servidor de bases de datos sólo podremos conectar con la base de datos desde la máquina local, bien usando como dirección localhost o conectando mediante el socket local. En cualquier caso, verifique que en efecto el servidor está lanzado y escuchando sólo en la dirección local, mediante el comando "netstat -ant". Compruebe también que está lanzado y escuchando en la dirección externa el servidor sshd:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      

Antes de continuar compruebe que desde la propia máquina servidor puede conectar con la base de datos, y desde cliente verifique que puede ingresar mediante ssh a la máquina remota:

servidor:~# mysql -u root -h localhost -P 5000 -p test
Enter password: 
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6 to server version: 3.23.49-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> 
usuario@cliente:/tmp$ ssh -l usuario servidor
usuario@servidor's password: 
Linux servidor 2.4.20 #2 mar sep 3 20:16:52 CEST 2002 i686 unknown

No mail.
usuario@servidor:~$ 

Mediante el primer comando intentamos entrar a la base de datos llamada test como el usuario administrador (root) de la base de datos. Mediante el segundo comando ingresamos desde cliente en la máquina remota servidor, identificándonos ante el extremo remoto como usuario. Si alguno de estos comandos falla consulte la documentación para solucionar el problema antes de seguir leyendo, o los túneles no funcionarán.

Hay dos maneras de establecer túneles mediante ssh, una en el lado local (opción -L) y otra en el lado remoto (opción -R). En nuestro caso vamos a iniciar las conexiones desde el lado local contra el lado remoto, así que usaremos la primera de las opciones. En tal caso, ssh se pondrá a la escucha en el puerto local que le indiquemos, y todo el tráfico de red que llegue a él lo redirigirá (encapsulándolo en el túnel) a una máquina remota, en la cual se extraerá el tráfico previamente tunelado, y se le pasará a una dirección IP y puerto que nosotros indiquemos. La situación es como la que se ve en la figura:
Esquema del túnel SSH configurado

Se puede apreciar que en cliente el programa mysql se comunica localmente con el programa ssh. Que en servidor es el demonio sshd el que se comunica con el servidor de bases de datos mysqld. Y que el tráfico de datos entre cliente y servidor ocurre entre el cliente y el servidor del protocolo SSH, de manera que todos los datos van cifrados e identificados por la red. El comando para establecer el túnel podría ser similar al siguiente:

usuario@cliente:/tmp$ ssh -l usuario -N -L 3306:127.0.0.1:5000 servidor
usuario@servidor's password: 

Cuando introduzca la contraseña que usuario tiene en servidor el comando anterior ya estará funcionando, puesto que la opción "-N" indica "no ejecutar comando alguno en el extremo remoto una vez correctamente identificado" (esta opción está pensada precisamente para el establecimiento de túneles). Por lo demás, el comando hace lo siguiente:

  • El comando ssh trata de establecer una conexión con el servidor sshd que escucha en el puerto 22 de la dirección IP asociada a servidor.
  • El comando ssh trata de identificarse como usuario ante el servidor remoto. En caso de que el cliente proporcione la contraseña adecuada:
    • En cliente, el programa ssh se pondrá a la escucha en el puerto 3306 del localhost.
    • En cliente, el programa ssh establecerá una conexión SSH (el túnel) desde un puerto libre de su IP externa asociada, al puerto 22 (el reservado para el protocolo SSH) de la IP externa asociada a servidor.
    • En servidor, el demonio sshd redirigirá todo el tráfico (ya descifrado) que llegue por el túnel establecido en el paso anterior, al puerto 5000 de la dirección 127.0.0.1 (precisamente la dirección IP y puerto donde previamente hemos puesto al servidor de bases de datos a escuchar).
  • En cliente cualquier usuario de la máquina ejecutará un comando para acceder a la base de datos remota, para lo cual intentará conectar con el extremo local del túnel como si ahí estuviera realmente escuchando el servidor de bases de datos remoto.

El comando que usar para conectar al servidor de bases de datos remoto usando como canal de comunicación el túnel recién configurado podría ser como el siguiente:

usuario@cliente:/tmp$ mysql -u root -h 127.0.0.1 -p test
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9 to server version: 3.23.49-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> 

Si se fija, la única diferencia entre este comando y el usado previamente en servidor para verificar el funcionamiento del servidor de bases de datos local es que en aquel caso debimos usar la opción "-P 5000" (el puerto predeterminado del servidor MySQL es el 3306) y en este caso debemos usar la dirección IP del localhost en lugar del nombre, porque de lo contrario parece que mysql trata de conectar usando el socket local en lugar de la red.

Para comprobar que el túnel funciona debidamente puede lanzar un programa sniffer de red y verificar que el tráfico entre cliente y servidor es tráfico de tipo SSH, y que viaja cifrado.

Tenga en cuenta que dependiendo de cómo esté configurado su servidor MySQL podrá tener o no problemas con la identificación de los usuarios. Recuerde que cuando conecta a través del túnel, mysqld ve las conexiones como provenientes de la máquina en la que está ejecutando, no de la máquina remota (cliente en este caso). De tal manera que puede ser necesario actualizar el control de acceso a usuarios de su servidor MySQL para permitir las conexiones desde todas las direcciones o nombres de la máquina local (servidor en este caso). Como siempre, si sucede algún error consulte los archivos de log, repase las configuraciones y consulte la documentación de todos los programas involucrados.

Ya para terminar, decir que es posible con OpenSSH configurar el acceso remoto sin contraseña (pero identificado mediante claves) para determinadas parejas de usuario y máquina remota, de manera que podríamos levantar automáticamente y sin intervención del usuario todos los túneles que hayamos configurado, siempre que los configuremos de tal modo. La configuración del acceso a máquinas remotas mediante ssh sin necesidad de contraseña lo veremos en un artículo posterior. Permanezcan a la escucha.

Última modificación: 11-January-2003 13:22:25 -0500

© 2002-2007 José Luis Domingo López. Todos los derechos reservados.
Contacte con el webmaster para informarle de fallos, incorrecciones o sugerencias.
Esta página cumple con los estándares HTML 4.01 y CSS2 del World Wide Web Consortium.