2001: Segurizando el acceso a un servidor MySQL sin odiseas

By on
'2001: Una odisea en el espacio'

Hace unos días, desplegando un servidor MySQL para un cliente, recordaba una de mis escenas favoritas de esa película de culto que es para mí “2001: Una odisea en el espacio”.

La escena discurre con Dave Bowman desprovisto de su casco espacial y desde la nave auxiliar EVA pidiéndole encarecidamente a HAL que abriese la puerta de la cámara de las cápsulas para regresar con el cadáver de Frank Poole, que había muerto tras intentar arreglar una avería ficticia en el sistema de comunicaciones generada por el propio HAL.

Tras un breve intento de ignorar las órdenes de Dave, HAL responde de forma negativa, alegando que quiere demasiado a esta máquina (él mismo) como para permitir que se le ponga en peligro.

Aunque quede lejos de este post hablar sobre la capacidad de HAL de tomar conciencia de sí mismo (sentir miedo ante la desconexión) y, sobre todo, la decisión de proteger la misión que está por encima incluso de los integrantes humanos que la componen, en nuestro trabajo diario a veces perjudicamos los servicios en pos de segurizarlos. Esto es, cerramos la puerta de la cámara de las cápsulas pese a que nuestro querido piloto Dave quiere entrar.

Teniendo siempre en cuenta la recomendación de que, a menor superficie de exposición, menor probabilidad de intrusión, tenemos que encontrar un punto medio (o un conjunto de medidas técnicas) que permita que nuestro servicio no sea una caja cerrada completamente inaccesible que, por definición, dejaría de ser considerado ya un servicio.

Divagado ya por el espacio exterior del mundo del cine y enlazada nuestra historia, os paso a contar cómo segurizar un servidor MySQL para no tener que cerrar nuestra cámara de las cápsulas.

Pasos Previos

Partimos de un entorno de dos máquinas virtuales con Ubuntu 16.04 instalado. Una tendrá el servidor MySQL 5.7 instalado y la otra, el cliente de MySQL (mysql-client) de la misma versión.

Verificando el estado de la conexión

Hemos creado un usuario secure dentro del servidor MySQL para no conectar directamente con el usuario root en el servidor.

Verificaremos si nuestro servidor tiene soporte de SSL y nuestro cliente hace uso de él de la siguiente forma:

Como podemos ver, nuestra conexión no está usando el protocolo seguro SSL.

Generando certificados y claves SSL/TLS

Para habilitar las conexiones seguras mediante SSL tenemos que generar en primera instancia un conjunto de certificados y claves que configuraremos en el motor MySQL. En Ubuntu existe un script ya preparado para esta tarea que se llama mysql_ssl_rsa_setup.

Estos ficheros se crearán en el path /var/lib/mysql, donde reside el directorio de datos de MySQL, y el usuario mysql que corre el motor debe poder acceder a ellas.

Habilitando el soporte SSL en el servidor MySQL

En la versión actual de MySQL para Ubuntu el motor trata de buscar los ficheros necesarios para habilitar SSL en su directorio de datos, donde nosotros los hemos generado.

De esta manera, reiniciando el servidor MySQL quedaría configurado para habilitar el soporte SSL.

Uso obligatorio de SSL en MySQL

Ahora hemos habilitado el soporte SSL pero las conexiones al motor aún se pueden realizar de forma insegura.

Para obligar a que el motor MySQL sólo acepte conexiones seguras tendremos que editar el fichero my.cnf para agregar las siguientes líneas.

Probando la conexión no cifrada para verificar el soporte

Ahora, y después de reiniciar el motor mediante sudo systemctl restart mysql, nuestro motor MySQL sólo aceptará conexiones cifradas.

Podemos probarlo intentando conectar nuestro usuario sin soporte ssl de la siguiente manera:

Como podemos ver, si obligamos a que nuestro cliente se intente conectar sin soporte SSL la conexión no se realiza.

Validando el certificado de cliente

Hasta ahora hemos configurado el motor MySQL para que use exclusivamente conexiones cifradas, pero esto no valida que el cliente utilice un certificado que lo identifique exclusivamente.

Para proceder con esta validación lo primero que haremos será modificar nuestro usuario secure para que tenga dicha limitación en el motor.

La parte importante del ALTER USER es el REQUIRE x509, esto obliga al usuario secure a utilizar un certificado validado por nuestra CA para conectar.

Necesitamos transferir ahora nuestro certificado y nuestra CA para que el cliente pueda utilizarlos en su conexión.

Crearemos un directorio mysql-ssl en nuestro equipo cliente y guardaremos allí los ficheros ca.pem y client-cert.pem que están alojados en el directorio de datos del motor MySQL (/var/lib/mysql).

Ya disponemos de los ficheros necesarios para configurar el acceso validado desde el cliente, ahora necesitamos configurar el fichero de conexión del cliente que se alojará en ~/my.cnf.

Y podemos probar la conexión:

De esta manera, validamos que el certificado de cliente que acabamos de configurar permite la conexión de nuestro cliente exclusivamente.

Aunque puede parecer un poco complejo, esta configuración nos permite segurizar el acceso al motor MySQL mediante SSL y validando el certificado utilizado que hemos configurado previamente.