16 agosto 2010

Fortificación de MySQL - 2/3

Parte 1 de 3
Parte 2 de 3
Parte 3 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 y root. 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:

5 comments :

bpun dijo...

Genial explicado!
Gracias :)

damontero dijo...

Muy buen curro. Y lo mejor de todo es que queda un tercer post :)

Cristián Rojas "Injeniero Barsa™" dijo...

¿Y cuándo la tercera parte muchachos?

Cristián Rojas "Injeniero Bars dijo...

¿Y cuándo la tercera parte muchachos?

damontero dijo...

Muy buen curro. Y lo mejor de todo es que queda un tercer post :)