Mysql: Tunelizando la conexión por medio de SSH

En esta oportunidad vamos a aprender a conectarnos a un servidor remoto de MYSQL utilizando un túnel SSH para maximizar la seguridad del acceso.


Motivaciones

¿Cuántas veces necesitamos utilizar algún cliente de conexión a MySQL como el mysql-client o MySQL Workbench, para poder administrar un servidor Mysql?

Claro, para ello “necesitamos” abrir el puerto tcp 3306 en el servidor, lo que a simple vista no parece una muy buena idea.

Ya se, se preguntarán ¿Por qué no utilizar phpmyadmin y utilizar el web server?

Particularmente prefiero no utilizarlo por una cuestión de seguridad en mis servidores, pero eso es otro tema.

Entonces… ¿cuál podría ser la solución?

Y la respuesta a esta pregunta viene, como muchas veces, de la mano de SSH 🙂

Túnel SSHssh mysql

SSH es un súper protocolo, un protocolo extremadamente versátil y útil para un montón de aplicaciones.

Ya hemos escrito largo y tendido sobre SSH en este blog, algunas de las entradas que pueden ser de interés son:

A grandes rasgos, SSH permite establecer una conexión de contenido cifrado de alta seguridad entre nuestro ordenador y un servidor en la red.

SSH, además de permitirnos armar túneles para proxificar una conexión web, o realizar conexiones invertidas, o montar un sistema de archivos en red, o incluso levantar una VPN, también permite, como es la intención explicar aquí, tunelizar otros protocolos de aplicación sobre SSH… en este caso, MySQL.

Esquema de la comunicación

En la siguiente figura se puede analizar brevemente el esquema de la comunicación a realizar.

mysql tunnel ssh security privacy hack hacking

La idea es dejar oculto el puerto tcp3306 en el servidor (mysql), y solo permitirnos conexión por SSH (¿quien no tiene ya un SSH en el server? :D).

El cliente al establecer la conexión SSH contra el servidor, va a abrir automáticamente en el host local (Cliente) el puerto 3306 para el mysql, pero de una forma en la que el cliente Mysql local, como mysql-client por línea de comandos, o MySQL Workbench, o cualquier otro, se conecten al server remoto apuntándole a la dirección ip local 127.0.0.1.

Todo el tráfico Mysql dirigido a la ip local de localhost será reenviado, automáticamente, al servidor remoto, por medio del túnel cifrado de SSH, así el único acceso al servidor remoto será por SSH.

El tráfico mysql en sí, será cifrado en el cliente, enviado por dentro del túnel de red de SSH, descifrado en el servidor y entregado localmente al server en su puerto tcp 3306 local.

¿Interesante no? Vamos con la práctica.

Configuración SSH – MySQL

Suponiendo que nuestro servidor SSH/mysql está en la dirección ip 11.22.33.44, y queremos abrir el puerto cliente 3306 en el cliente, en la dirección ip de localhost 127.0.0.1, como explicamos en el esquema anterior, solo debemos ejecutar el siguiente comando (previo, por supuesto, ya disponer de cliente y server SSH configurado).

Aquí,

  • -L permite especificar un puerto local que será reenviado al servidor SSH remoto hacia un puerto remoto.
  • 12345: es el puerto local que reenviaremos al servidor remoto.
  • 127.0.0.1 es la dirección ip local en el equipo remoto en la que atiende el servicio. En este caso es la de localhost.
  • :3306 es el puerto remoto que será mapeado y asociado a esta conexión en el puerto local.
  • usuario_ssh es el usuario con el que vamos a conectarnos al SSH remoto.
  • 11.22.33.44 es el servidor remoto que atiende en el puerto de SSH hacia Internet, y que localmente tiene un servidor Mysql escuchando en una ip privada.

Luego de ejecutar este comando, podremos ver el puerto 3306 en nuestra ip local esperando conexiones, y por supuesto, podremos utilizar cualquier cliente de Mysql para conectarnos al servidor “127.0.0.1” o “localhost” con el puerto TCP 12345.

Por supuesto, no necesariamente tienen que ser estos puertos, podemos abrir cualquier puerto en el cliente, y que este puerto mapee contra el servidor en el 3306, simplemente reemplazando el primer “12345” en el comando anterior, por cualquier otro.

Además, suponiendo que en nuestra LAN tengamos mas de un equipo que quiera conectarse al mismo servidor, no es necesario que conecte SSH también, podemos especificar la ip de nuestra LAN antes del puerto local (192.168.x.y idealmente), o incluso * para permitir conectar a cualquier ip local de la LAN.

El comando quedaría así:

Como nota adicional cabe aclarar que MySQL Workbench ya dispone de la lógica para permitir conexión a un server Mysql remoto por medio de un túnel SSH… pero en mi caso necesitaba, además, abrir el puerto para permitir conexiones de otros equipos virtualizados locales 🙂

Ejemplo

Si ejecutamos:

Y nos autenticamos contra el servidor, luego podremos conectar, por ejemplo, nuestro cliente mysql por línea de comandos de esta forma:

mysql -h 127.0.0.1n -P 12345 -u usuario_mysql -p

¿Y si nuestro cliente es Windows?

Si el equipo cliente es Window$, podemos simplemente instalar Putty, el genial cliente SSH para sistemas EXE, y ejecutarlo.

En los datos de conexión debemos colocar el usuario y host del equipo servidor remoto:

Luego, ir a la sección Connection -> SSH -> Tunnels, y crear un túnel local automático con un puerto origen determinado, 3306 en este caso, y socket destino ip:port del servidor remoto de mysql:

Al dar clic en Add / Agregar, veremos lo siguiente:

Esto indica que se ha configurado correctamente… solo debemos dar clic en “Open/Abrir” y typear nuestra contraseña SSH contra el servicio remoto, que si loguea, ya tendremos en la ip 127.0.0.1:3306 el servicio Mysql remoto corriendo y atendiendo en forma local 🙂

¡Espero que les sea de utilidad!


Video complementario

En nuestro canal de youtube hemos publicado un video con la explicación de este artículo, esperamos sea interesante y ameno!

  • kabeza

    Buenisimo el dato. Consulta: en este caso tanto cliente como servidor tienen *nix como S.O., pero el cliente podria ser bien un Windows o cualquier cosa, no?

    • Hola! Si, si se puede configurando el túnel en Putty (el cliente SSH para Windows).
      Ahí actualicé el artículo y agregué esta info, es simplemente configurar un túnel SSH local automático contra el servcio remoto para que levante el puerto local.
      Espero te sirva!