La seguridad de los datos es una de las principales prioridades en estos días. A veces se impone por regulaciones externas como PCI-DSS o HIPAA, a veces es porque le importan los datos de sus clientes y su reputación. Hay numerosos aspectos de la seguridad que debe tener en cuenta:acceso a la red, seguridad del sistema operativo, concesiones, encriptación, etc. En esta publicación de blog, le daremos 10 consejos sobre lo que debe tener en cuenta al proteger su configuración de MySQL o MariaDB.
1. Eliminar usuarios sin contraseña
MySQL solía venir con un conjunto de usuarios creados previamente, algunos de los cuales pueden conectarse a la base de datos sin contraseña o, peor aún, usuarios anónimos. Esto ha cambiado en MySQL 5.7 que, de manera predeterminada, viene solo con una cuenta raíz que usa la contraseña que elija en el momento de la instalación. Aún así, hay instalaciones de MySQL que se actualizaron de versiones anteriores y estas instalaciones mantienen a los usuarios heredados. Además, MariaDB 10.2 en Centos 7 viene con usuarios anónimos:
MariaDB [(none)]> select user, host, password from mysql.user where user like '';
+------+-----------------------+----------+
| user | host | password |
+------+-----------------------+----------+
| | localhost | |
| | localhost.localdomain | |
+------+-----------------------+----------+
2 rows in set (0.00 sec)
Como puede ver, están limitados solo al acceso desde localhost pero, independientemente, no desea tener usuarios así. Si bien sus privilegios son limitados, aún pueden ejecutar algunos comandos que pueden mostrar más información sobre la base de datos; por ejemplo, la versión puede ayudar a identificar otros vectores de ataque.
[[email protected] ~]# mysql -uanonymous_user
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 19
Server version: 10.2.11-MariaDB MariaDB Server
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> SHOW GRANTS\G
*************************** 1. row ***************************
Grants for @localhost: GRANT USAGE ON *.* TO ''@'localhost'
1 row in set (0.00 sec)
MariaDB [(none)]> \s
--------------
mysql Ver 15.1 Distrib 10.2.11-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 19
Current database:
Current user: [email protected]
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 10.2.11-MariaDB MariaDB Server
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/lib/mysql/mysql.sock
Uptime: 12 min 14 sec
Threads: 7 Questions: 36 Slow queries: 0 Opens: 17 Flush tables: 1 Open tables: 11 Queries per second avg: 0.049
--------------
Tenga en cuenta que los usuarios con contraseñas muy simples son casi tan inseguros como los usuarios sin contraseña. Las contraseñas como "contraseña" o "qwerty" no son realmente útiles.
2. Acceso remoto estricto
En primer lugar, acceso remoto para superusuarios:esto se soluciona de forma predeterminada al instalar la última versión de MySQL (5.7) o MariaDB (10.2), solo está disponible el acceso local. Aún así, es bastante común ver a los superusuarios disponibles por varias razones. El más común, probablemente porque la base de datos está administrada por humanos que quieren facilitar su trabajo, por lo que agregarían acceso remoto a sus bases de datos. Este no es un buen enfoque, ya que el acceso remoto facilita la explotación de vulnerabilidades de seguridad potenciales (o verificadas) en MySQL; no es necesario conectarse primero al host.
Otro paso:asegúrese de que cada usuario pueda conectarse a MySQL solo desde hosts específicos. Siempre puede definir varias entradas para el mismo usuario ([email protected], [email protected]), esto debería ayudar a reducir la necesidad de comodines ([email protected]'%').
3. Eliminar base de datos de prueba
La base de datos de prueba, por defecto, está disponible para todos los usuarios, especialmente para los usuarios anónimos. Dichos usuarios pueden crear tablas y escribir en ellas. Esto puede convertirse potencialmente en un problema por sí mismo:cualquier escritura agregaría algunos gastos generales y reduciría el rendimiento de la base de datos. Actualmente, después de la instalación predeterminada, solo MariaDB 10.2 en Centos 7 se ve afectado por esto:Oracle MySQL 5.7 y Percona Server 5.7 no tienen el esquema de "prueba" disponible.
[[email protected] ~]# mysql -uanonymous_user
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 13
Server version: 10.2.11-MariaDB MariaDB Server
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> SHOW GRANTS\G
*************************** 1. row ***************************
Grants for @localhost: GRANT USAGE ON *.* TO ''@'localhost'
1 row in set (0.00 sec)
MariaDB [(none)]> USE test;
Database changed
MariaDB [test]> CREATE TABLE testtable (a INT);
Query OK, 0 rows affected (0.01 sec)
MariaDB [test]> INSERT INTO testtable VALUES (1), (2), (3);
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [test]> SELECT * FROM testtable;
+------+
| a |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
Por supuesto, aún puede suceder que su MySQL 5.7 se haya actualizado desde versiones anteriores en las que no se eliminó el esquema de "prueba"; debe ocuparse de esto y verificar si lo ha creado.
4. Ofuscar el acceso a MySQL
Es bien sabido que MySQL se ejecuta en el puerto 3306 y su superusuario se llama 'root'. Para hacer las cosas más difíciles, es bastante simple cambiar esto. Hasta cierto punto, este es un ejemplo de seguridad a través de la oscuridad, pero al menos puede detener los intentos automáticos de obtener acceso al usuario "raíz". Para cambiar el puerto, debe editar my.cnf y establecer la variable 'puerto' en algún otro valor. En cuanto a los usuarios, después de instalar MySQL, debe crear un nuevo superusuario (CONCEDER A TODOS... CON LA OPCIÓN DE CONCEDER) y luego eliminar las cuentas '[email protected]' existentes.
5. Seguridad de la red
Idealmente, MySQL no estaría disponible a través de la red y todas las conexiones se manejarían localmente, a través del socket de Unix. En algunas configuraciones, esto es posible; en ese caso, puede agregar la variable 'skip-networking' en my.cnf. Esto evitará que MySQL use cualquier comunicación TCP/IP, solo el socket de Unix estaría disponible en Linux (tuberías con nombre y memoria compartida en hosts de Windows).
Sin embargo, la mayoría de las veces, una seguridad tan estricta no es factible. En ese caso, debe encontrar otra solución. Primero, puede usar su firewall para permitir el tráfico solo desde hosts específicos al servidor MySQL. Por ejemplo, los hosts de aplicaciones (aunque deberían estar de acuerdo con llegar a MySQL a través de proxies), la capa de proxy y tal vez un servidor de administración. Otros hosts en su red probablemente no necesiten acceso directo al servidor MySQL. Esto limitará las posibilidades de ataque a su base de datos, en caso de que algunos hosts de su red se vean comprometidos.
Si usa proxies que permiten la coincidencia de expresiones regulares para consultas, puede usarlos para analizar el tráfico de SQL y bloquear consultas sospechosas. Lo más probable es que los hosts de su aplicación no deban ejecutar "DELETE * FROM your_table"; sobre una base regular. Si es necesario eliminar algunos datos, se puede ejecutar a mano, localmente, en la instancia de MySQL. Puede crear tales reglas usando algo como ProxySQL:bloquee, reescriba, redirija tales consultas. MaxScale también le brinda la opción de bloquear consultas basadas en expresiones regulares.
6. Complementos de auditoría
Si está interesado en recopilar datos sobre quién ejecutó qué y cuándo, hay varios complementos de auditoría disponibles para MySQL. Si usa MySQL Enterprise, puede usar MySQL Enterprise Audit, que es una extensión de MySQL Enterprise. Percona y MariaDB también tienen su propia versión de complementos de auditoría. Por último, el complemento de McAfee para MySQL también se puede usar con diferentes versiones de MySQL. En términos generales, esos complementos recopilan más o menos los mismos datos:eventos de conexión y desconexión, consultas ejecutadas, tablas a las que se accede. Todo esto contiene información sobre qué usuario participó en dicho evento, desde qué host se conectó, cuándo sucedió, etc. El resultado puede ser XML o JSON, por lo que es mucho más fácil analizarlo que analizar el contenido general del registro (aunque los datos son bastante similares). Dicha salida también se puede enviar a syslog y, además, a algún tipo de servidor de registro para su procesamiento y análisis.
7. Deshabilitar CARGAR ARCHIVO LOCAL DE DATOS
Si tanto el servidor como el cliente tienen la capacidad de ejecutar LOAD DATA LOCAL INFILE, un cliente podrá cargar datos desde un archivo local a un servidor MySQL remoto. Esto, potencialmente, puede ayudar a leer los archivos a los que el cliente tiene acceso; por ejemplo, en un servidor de aplicaciones, uno podría acceder a cualquier archivo al que tenga acceso el servidor HTTP. Para evitarlo, debe establecer local-infile=0 en my.cnf
8. Privilegios de archivo
Debe tener en cuenta que la seguridad de MySQL también depende de la configuración del sistema operativo. MySQL almacena datos en forma de archivos. El servidor MySQL escribe mucha información en los registros. A veces, esta información contiene datos:registro de consultas lentas, registro general o registro binario, por ejemplo. Debe asegurarse de que esta información sea segura y accesible solo para los usuarios que tienen que acceder a ella. Por lo general, significa que solo el root y el usuario bajo cuyos derechos se ejecuta MySQL deben tener acceso a todos los archivos relacionados con MySQL. La mayoría de las veces es un usuario dedicado llamado 'mysql'. Debe verificar los archivos de configuración de MySQL y todos los registros generados por MySQL y verificar que otros usuarios no puedan leerlos.
9. SSL y Cifrado de Datos en Tránsito
Evitar que las personas accedan a los archivos de configuración y de registro es una cosa. El otro problema es asegurarse de que los datos se transfieran de forma segura a través de la red. Con la excepción de las configuraciones en las que todos los clientes son locales y usan un socket Unix para acceder a MySQL, en la mayoría de los casos, los datos que forman un conjunto de resultados para una consulta, abandonan el servidor y se transfieren al cliente a través de la red. Los datos también se pueden transferir entre servidores MySQL, por ejemplo, a través de la replicación MySQL estándar o dentro de un clúster de Galera. El tráfico de la red se puede rastrear y, a través de esos medios, sus datos estarían expuestos.
Para evitar que esto suceda, es posible utilizar SSL para cifrar el tráfico, tanto del lado del servidor como del cliente. Puede crear una conexión SSL entre un cliente y un servidor MySQL. También puede crear una conexión SSL entre su maestro y sus esclavos, o entre los nodos de un clúster de Galera. Esto asegurará que todos los datos que se transfieran estén seguros y no puedan ser rastreados por un atacante que obtuvo acceso a su red.
La documentación de MySQL cubre en detalle cómo configurar el cifrado SSL. Si lo encuentra demasiado engorroso, ClusterControl puede ayudarlo a implementar un entorno seguro para la replicación de MySQL o el clúster de Galera con un par de clics:
10. Cifrado de datos en reposo
Proteger los datos en tránsito mediante el cifrado SSL solo resuelve parcialmente el problema. También debe cuidar los datos en reposo:todos los datos almacenados en la base de datos. El cifrado de datos en reposo también puede ser un requisito para las normas de seguridad como HIPAA o PCI DSS. Dicho cifrado se puede implementar en varios niveles:puede cifrar todo el disco en el que se almacenan los archivos. Puede cifrar solo la base de datos MySQL a través de la funcionalidad disponible en las últimas versiones de MySQL o MariaDB. El cifrado también se puede implementar en la aplicación, de modo que cifre los datos antes de almacenarlos en la base de datos. Cada opción tiene sus pros y sus contras:el cifrado de disco puede ayudar solo cuando los discos se roban físicamente, pero los archivos no se cifrarían en un servidor de base de datos en ejecución. El cifrado de la base de datos MySQL resuelve este problema, pero no puede evitar el acceso a los datos cuando la cuenta raíz está comprometida. El cifrado a nivel de aplicación es el más flexible y seguro, pero luego pierde el poder de SQL:es bastante difícil usar columnas cifradas en las cláusulas WHERE o JOIN.
Todas las versiones de MySQL proporcionan algún tipo de cifrado de datos en reposo. MySQL de Oracle utiliza el cifrado de datos transparente para cifrar los espacios de tablas de InnoDB. Está disponible en la oferta comercial de MySQL Enterprise. Proporciona una opción para cifrar los espacios de tabla de InnoDB; otros archivos que también almacenan datos de alguna forma (por ejemplo, registros binarios, registro general, registro de consultas lentas) no están cifrados. Esto permite que la cadena de herramientas (MySQL Enterprise Backup pero también xtrabackup, mysqldump, mysqlbinlog) funcione correctamente con dicha configuración.
A partir de MySQL 5.7.11, la versión comunitaria de MySQL también obtuvo soporte para el cifrado de espacios de tabla InnoDB. La principal diferencia en comparación con la oferta empresarial es la forma en que se almacenan las claves:las claves no se encuentran en una bóveda segura, lo cual es necesario para el cumplimiento normativo. Esto significa que a partir de Percona Server 5.7.11, también es posible cifrar el tablespace de InnoDB. En Percona Server 5.7.20, publicado recientemente, se ha agregado compatibilidad con el cifrado de registros binarios. También es posible integrarse con el servidor Hashicorp Vault a través de un complemento keyring_vault, haciendo coincidir (e incluso ampliando el cifrado de registro binario) las funciones disponibles en la edición MySQL Enterprise de Oracle.
MariaDB agregó soporte para el cifrado de datos en 10.1.3:es una implementación separada y mejorada. Le brinda la posibilidad no solo de cifrar los espacios de tabla de InnoDB, sino también los archivos de registro de InnoDB. Como resultado, los datos están más seguros, pero algunas de las herramientas no funcionarán en esa configuración. Xtrabackup no funcionará con registros de rehacer cifrados:MariaDB creó una bifurcación, MariaDB Backup, que agrega compatibilidad con el cifrado de MariaDB. También hay problemas con mysqlbinlog.
Independientemente del tipo de MySQL que utilice, siempre que sea una versión reciente, tendrá opciones para implementar el cifrado de datos en reposo a través del servidor de la base de datos, asegurándose de que sus datos estén protegidos adicionalmente.
Proteger MySQL o MariaDB no es trivial, pero esperamos que estos 10 consejos te ayuden en el camino.
Resumen
En el panorama actual, la seguridad de los datos es una prioridad principal para todos los administradores de bases de datos. Ya sea que su motivación sea cumplir con los requisitos reglamentarios o proteger a sus clientes y la reputación de su empresa, estos diez consejos para proteger sus bases de datos MySQL y MariaDB lo ayudarán a proteger aún más su infraestructura y brindarle tranquilidad.
Existen numerosas medidas a tener en cuenta para garantizar que la infraestructura de su base de datos sea segura. En esta publicación, cubrimos los aspectos básicos, como el cifrado de datos, los controles de acceso a la red, la autenticación y los privilegios del usuario, la seguridad del sistema operativo y más.
El software de automatización de administración de bases de datos, como ClusterControl, puede ser una gran herramienta para ayudarlo en sus esfuerzos generales de seguridad de la base de datos. Si está buscando una inmersión más profunda en cada paso que debe seguir para proteger sus bases de datos MySQL, asegúrese de consultar la Parte 1 y la Parte 2 de nuestra serie sobre Cómo proteger MySQL. Para mantenerse informado sobre otras mejores prácticas de administración de bases de datos, síganos en Twitter, LinkedIn y suscríbase a nuestro boletín para recibir actualizaciones.