Fortificación de MySQL (2 de 3)
Continuamos con la segunda entrada sobre fortificación de MySQL.
7.- Uso de los mínimos privilegios: aplicable a versiones anteriores del motor 5.x. Las bases de datos se han de almacenar propiedad del usuario mysql u otro creado para tal propósito sin privilegios de administración del sistema operativo.
Para comprobar los permisos:
shell> ls -l /var/lib/mysql
Todos los directorios deberían mostrarse como usuario mysql y grupo mysql, con permisos 700 o lo que es lo mismo: "drwx------". Para modificar el usuario y grupo de un directorio y posteriormente sus permisos:
shell> chown mysql:mysql /var/lib/mysql/mibbdd
shell> chmod 700 /var/lib/mysql/mibbdd
El servicio ha de ser ejecutado con este usuario, que además no puede tener permisos para conectarse localmente. En sistemas Unix, el usuario ha de tener como shell el binario /sbin/nologin
Para comprobar la shell:
shell> grep mysql /etc/passwd
mysql:x:27:491:MySQL Server:/var/lib/mysql:/bin/bash
Para cambiar la shell:
shell> chsh -s /sbin/nologin mysql
En el caso de Windows, el usuario ha de estar incluido en los Deny log on locally y ejecutado como usuario NETWORK_SERVICE
8.- Permisos de administración en usuarios: la base de datos dispone de usuarios al igual que el sistema operativo, root es el administrador y únicamente debería ser utilizado para tareas de gestión como altas y bajas de otros usuarios, modificación de permisos, etcétera. Es importante que no se use al usuario root para el acceso a datos. Al igual que los usuarios que tratan datos (selects, inserts o updates) no han de tener habilitados permisos especiales, ya que en caso de encontrarse una inyección de código podrían ejecutarse tareas con privilegios mayores.
Para consultar la lista de usuarios y sus permisos:
mysql> use mysql;
mysql; select * from user;
Para ver los permisos de un usuario en concreto:
mysql> show grants for ‘root’@’localhost’;
El siguiente ejemplo muestra la modificación del usuario "miuser" en la base de datos "mibbdd", dejando únicamente INSERT, SELECT, UPDATE y DELETE:
mysql> show grants for miuser@localhost;
+--------------------------------------------------------------------------------------+
| Grants for miuser@localhost |
+--------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'miuser'@'localhost' IDENTIFIED BY PASSWORD '6212cdea5883c099' |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX,
ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW,
CREATE ROUTINE, ALTER ROUTINE ON `mibbdd`.* TO 'miuser'@'localhost' |
+--------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> revoke all privileges on mibbdd.* from 'miuser'@'localhost';
Query OK, 0 rows affected (0.11 sec)
mysql> show grants for miuser@localhost;
+--------------------------------------------------------------------------------------+
| Grants for miuser@localhost |
+--------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'miuser'@'localhost' IDENTIFIED BY PASSWORD '6212cdea5883c099' |
+--------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> grant select,insert,update,delete on mibbdd.* to 'miuser'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> show grants for miuser@localhost;
+--------------------------------------------------------------------------------------+
| Grants for miuser@localhost |
+--------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'miuser'@'localhost' IDENTIFIED BY PASSWORD '6212cdea5883c099' |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `mibbdd`.* TO 'miuser'@'localhost' |
+--------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
9.- Eliminación de visualización de base de datos: con esta medida se pretende que los usuarios no puedan conocer que otras bases de datos se encuentran en el servidor, eliminando el acceso comando SHOW DATABASES. Para aplicar esta opción, se puede arrancar el servicio mysqld con el parámetro "--skip-show-database" o añadir al archivo de configuración este mismo nombre:
[mysqld]
skip-show-database
Si por algún motivo se desea asignar este privilegio a un usuario, se puede llevar a cabo mediante el GRANT correspondiente.
10.- Configuración de los registros: siempre y cuando el sistema no haga demasiadas peticiones, se pueden almacenar todas las peticiones que reciba el servicio. Esta opción no es recomendable si la base de datos tiene mucho tráfico ya que genera mucha carga e información en disco. Para activarla, modificar el archivo my.cnf con:
[mysqld]
log=/var/log/mylogfile
Este fichero log, al igual que el de registro, como el de errores, el archivo binario, o el de consultas lentas solo han de tener permisos para los usuarios mysql yroot. Puede causar problemas importantes de confidencialidad si otros usuarios del sistema tienen acceso.
11.- Almacenar los datos de la base de datos en una partición distinta al sistema operativo: evitando que la base de datos sufra pérdidas por ataques de denegación de servicio que llenen el disco duro libre del sistema operativo.
[mysqld]
datadir=/path/dir
12.- Eliminación del historial del cliente de MySQL: que almacena los comandos ejecutados por el cliente mysql y puede facilitar información crítica. Para configurarlo, añadir la siguiente línea al /etc/profile:
declare -r MYSQL_HISTFILE=/dev/null
Además es recomendable crear un enlace de los ficheros a /dev/null también.
shell> ln -s /dev/null $HOME/.mysql_history
13.- Comprobación de contraseñas almacenadas en texto claro: que se guardan en la variable de entorno MYSQL_PWD y en el archivo de configuración, bajo la directiva password.
Para evitar que se use la variable de entorno añadir al archivo /etc/profile:
declare -r MYSQL_PWD
En el archivo de configuración comprobar que no existe la linea "password":
[client]
password=TuContraseña
Referencias:
Fortificación de MySQL (3 de 3)
Continuamos con la tercera y última entrada sobre fortificación de MySQL.
14.- Comprobación de permisos de ficheros de registros, de configuración y archivos SSL: para que únicamente el usuario que ejecuta la base de datos tenga permisos de lectura y escritura. Estos ficheros se encuentran generalmente en /var/log/mysql y /etc/mysql/my.cnf. Los archivos SSL son especificados en las variables: ssl_ca, ssl_cert, ssl_key
shell> ls -l /var/log/mysql
shell> ls -l /etc/mysql/my.cnf
mysql> show variables like "%ssl%";
15.-Actualizar tablas de privilegios mediante el uso de los scripts "mysql_upgrade" y "mysql_fix_privilege_tables" cuando se actualice la base de datos a una nueva versión.
shell> ls -l /var/log/mysql
shell> mysql_fix_privilege_tables --password=ecm2sux
This script updates all the mysql privilege tables to be usable by
the current version of MySQL
done
16.-Verificacar las contraseñas para que todas utilicen el nuevo sistema de hash y asegurar que no existen usuarios sin contraseña. El antiguo hash tenía una longitud de 16 caracteres y el nuevo de 42, por lo tanto la siguiente consulta no debería mostrar resultados:
mysql> select User, Password from mysql.user where length(password) < 41;
Otra opción es habilitar la variable "secure_auth", para deshabilitar directamente estos usuarios, para consultar el estado:
mysql> show variables like "secure_auth"
Los usuarios con contraseñas en blanco se pueden localizar con la consulta:
mysql> select User, Password from mysql.user where length(password) = 0 or password is null;
17.- Comprobación de los hosts permitidos para los usuarios con el objetivo de que no existan usuarios que puedan realizar la conexión desde cualquier dirección IP. Todos aquellos usuarios que devuelva la siguiente consulta han de ser revisados:
mysql> select user from mysql.user where host = '%';
18.- Búsqueda de usuarios con privilegios especiales, que no deberían tener habilitados para usos normales. Los permisos a comprobar son: FILE, PROCESS, SUPER, SHUTDOWN, CREATE USER y RELOAD:
mysql> select user, host from mysql.user where File_priv = 'Y';
mysql> select user, host from mysql.user where Process_priv = 'Y';
mysql> select user, host from mysql.user where Super_priv = 'Y';
mysql> select user, host from mysql.user where Shutdown_priv = 'Y';
mysql> select user, host from mysql.user where Create_user_priv = 'Y';
mysql> select user, host from mysql.user where Reload_priv = 'Y';
19.- Deshabilitar la fusión (MERGE) de tablas que permite acceder a datos incluso si no hay permisos sobre ellas. Para llevar a cabo esta configuración se puede consultar el estado en la variable "have_merge_engine" y para implantarlo, añadir el parámetro --skip-merge
20.- Deshabilitar el uso de enlaces simbólicos que pueden ser peligrosos especialmente si el usuario que ejecuta la base de datos es root y puede sobrescribir otros ficheros. Para aplicar la medida se define la variable "have_symlink" o el parámetro --skip-symbolic-links
[mysqld]
skip-symbolic-links=on
Referencias: