Crear un tunel SSH para la conexión a un servidor MySQL detrás de un firewall con Linux Debian 5

Introducción.

Este es el panorama del esquema de red de la oficina del grupo de desarrollo.

Esquema de la red
Esquema de la red

Un servidor (centro) alberga los proyectos web (Apache) de los cuales el grupo de desarrollo manipula sus archivos (SSH + Samba), así como sus bases de datos (MySQL).  El servidor cuenta con dos interfaces de red las cuales separan físicamente el acceso de la red privada (eth1) de la red pública o Internet (eth0).

Los desarrolladores utilizan los clientes desde la red privada para la cual no hay ningún tipo de filtro en el servidor y pueden acceder a la totalidad de sus servicios.  Desde el exterior, el servidor implementa un firewall que sólo permite la consulta web de los proyectos y el acceso al SSH.  Como fácilmente se concluye, el firewall de la interfaz pública (eth0) filtra explícitamente el acceso a los servicios de MySQL y Samba que son considerados como inseguros.

El problema.

Se requiere ahora que los desarrolladores puedan acceder al servidor desde sus clientes a través de Internet.

El problema se divide en dos aproximaciones.

  1. Manipular el software, el código y los datos remotamente.
  2. Manipular el software y el código localmente, y los datos remotamente.

La solución.

Manipular el software, el código y los datos remotamente (1).

Este es el caso mas simple.  Como los aplicativos son web se acceden a través de un navegador, su código es manipulado a través de SSHFS (ver instrucciones para Linux y Windows) y sus datos son manipulados a través de la web con PHPMyAdmin.

Manipular el software y el código localmente y los datos remotamente (2).

Este caso es mas elaborado que el anterior ya que el software y el código reside localmente porque lo es muy fácil de manipular, sin embargo los datos (la base de datos MySQL) de los proyectos continúan viviendo en el servidor de desarrollo.

Dado que el puerto de acceso a MySQL se encuentra filtrado para el exterior por razones de seguridad es inicialmente imposible conectarse a la base de datos desde el cliente a través de Internet.  La solución es crear un tunel SSH desde el cliente remoto hasta el servidor a través del medio inseguro (Internet) y desde allí, ahora un lugar seguro, realizar la conexión con el puerto de la base de datos que en este caso reside en el mismo servidor.

Implementación de la solución (2).

Por razones que serán obvias, es necesario que los usuarios remotos cuenten con cuentas (nombre de usuario/contraseña) en el sistema operativo del servidor de desarrollo y que estas estén habilitadas para acceder al mismo a través de SSH.

Las siguientes acciones se realizan desde el cliente remoto.

Establecer el tunel SSH entre el cliente remoto y el servidor de desarrollo.

$ ssh desarrollador@desarrollo.com -L 3307:localhost:3306 -N -f

Con la instrucción anterior estamos creando un tunel entre el cliente remoto y el servidor desarrollo.com con el usuario desarrollador y utilizando al protocolo SSH.  Se le está indicando además que el tunel se deberá establecer entre el puerto 3307 local y el puerto 3306 del servidor remoto, en este caso el mismo localhost.  Es muy importante tener en cuenta que la referencia de este último servidor remoto se realiza previa conexión a desarrollo.com, es decir que su acceso se hace desde este y no directamente desde el cliente que inicia la conexión del tunel ejecutando el comando.

Otro aspecto interesante a tener en cuenta es que los puertos utilizados no necesariamente deben ser diferentes ya que uno es local (3307 en este ejemplo) y el otro es remoto (3306 el estándar de MySQL), sin embargo en el caso de que ya se cuente con una instalación local de MySQL (utilizando el puerto 3306) será entonces necesario utilizarlos diferentes como se ha planeado en este artículo.

Realizar la conexión a MySQL a través del tunel SSH.

Después de establecido el tunel entre cliente y servidor la conexión se realiza directamente con el puerto local (3307) del cliente remoto como si el servicio se estuviera ejecutando en la misma máquina cliente, el tunel se encarga de transmitir la información encriptada y realizar las conversiones necesarias a cada uno de los lados.

$ mysql -h 127.0.0.1 -u bd_usuario -p -P 3307 bd_nombre

Tenga en cuenta que el inicio de conexión (connect) a una base de datos toma cierto tiempo ya que el motor de bases de datos realiza una carga previa de los nombres de las tablas y de los campos de estas.  Si desea evitar esta precarga de información puede utilizar el parámetro -A en la invocación al cliente de MySQL (mysql).

Scripts de conexión.

A pesar de que el procedimiento es -extremadamente- simple, he creado un par de scripts para facilitar y automatizar el proceso de creación del puente SSH y de conexión a la base de datos a través de línea de comando.

Los scripts pueden ser descargados de aqui y configurados utilizando cualquier editor de texto.  tunssh_connection se encarga de establecer la conexión del túnel SSH mientras que tunssh_mysql realiza la conexión a la base de datos MySQL remota a través del túnel SSH.

Enlaces.

2 thoughts on “Crear un tunel SSH para la conexión a un servidor MySQL detrás de un firewall con Linux Debian 5”

  1. _ Espectacular post, era lo que estaba buscando pero, mi duda es que tan lenta se haria mi aplicación, en el servidor de base de datos tengo mysql 5 sobre Linux Centos, y el servidor externo Apache lo uso como contenedor de la aplicacion web de pago online, que va a usar HTTPS, te agradecería mucho una luz, gracias por estos post.

    1. Saludos @Norant. Se aprecia un ligero retardo en la conexión si lo comparas con la conexión directa. Sin embargo considero que el beneficio es mucho mayor.

Leave a Reply

Your email address will not be published. Required fields are marked *