Gestión de Usuarios y Permisos en MySQL
Gestión de Usuarios y Permisos en MySQL
Gestión de Usuarios y Permisos en MySQL
2
2 GESTIÓN INTERNA DE USUARIOS Y PERMISOS EN MYSQL...................................................................2
2.1 EJEMPLOS DE ACCIÓN DIRECTA SOBRE TABLAS DE MYSQL....................................................................................4
3 GESTIÓN DE USUARIOS......................................................................................................................................5
3.1 CREACIÓN DE USUARIOS.........................................................................................................................................5
3.2 BORRADO DE USUARIOS.........................................................................................................................................7
3.3 OTRAS OPERACIONES SOBRE USUARIOS.................................................................................................................7
4 GESTIÓN DE PERMISOS......................................................................................................................................8
4.1 CONCESIÓN DE PRIVILEGIOS...................................................................................................................................8
4.2 REVOCAR PRIVILEGIOS.........................................................................................................................................10
4.3 OTRAS OPERACIONES SOBRE PRIVILEGIOS...........................................................................................................11
5 GESTIÓN DE ROLES...........................................................................................................................................11
5.1 CREACIÓN DE ROLES Y ASIGNACIÓN DE SUS PRIVILEGIOS...................................................................................11
5.2 ROLES OBLIGATORIOS..........................................................................................................................................12
5.3 CHEQUEAR LOS ROLES Y PRIVILEGIOS ASIGNADOS..............................................................................................13
5.4 ACTIVACIÓN DE ROLES........................................................................................................................................14
5.5 Eliminando roles y privilegios.............................................................................................................................15
1 Gestión de usuarios y permisos en MySQL
El sistema de permisos de MySQL se encarga de establecer quién puede establecer conexión con el
servidor y qué operaciones puede realizar sobre el mismo.
Cuando un usuario se conecta al servidor MySQL, su identidad queda determinada por el nombre
de usuario y por la dirección del equipo desde el que realizamos la conexión. Una vez que el
usuario está conectado, el servidor debe comprobar que ese usuario dispone de los permisos
necesarios para realizar las operaciones que requiera.
El acceso al servidor tiene lugar por tanto en dos etapas, en la primera se comprueba nuestra
identidad y en la segunda los permisos para hacer operaciones sobre los objetos del sistema.
Como se trata de una base de datos gestionada por el propio servidor, un usuario con los permisos
adecuados (normalmente el root), podrá acceder directamente a su contenido e incluso modificarlo
directamente.
Para gestionar los usuarios y sus permisos se utilizan básicamente las siguientes tablas de la base de
datos mysql:
User: Se utiliza para determinar qué usuarios pueden conectarse al sistema. Además, los
permisos definidos en esta tabla son globales, es decir, si tenemos un permiso a ‘Y’ sobre un
determinado permiso de esta tabla, podremos hacer esa operación sobre cualquier tabla de
cualquier base de datos. Es aconsejable otorgar privilegios en esta tabla sólo a los
administradores. Para otros usuarios, deberíamos dejar los privilegios de la tabla user con el
valor ‘N’ y otorgar los privilegios únicamente a niveles más específicos.
Db: En ella se definen los permisos a nivel de base de datos de los usuarios.
Host: Se usa en conjunción con la tabla Db cuando queremos que un registro de la tabla Db
se aplique a varios equipos. Por ejemplo, si queremos que un usuario pueda usar una base de
datos desde varios equipos en nuestra red. Un valor vacío del campo host en un registro de
la tabla Db, significa que los privilegios de dicho registro deben ser combinados con
aquellos que se encuentren en la tabla Host (a través de la operación AND).
Tables_priv: En ella se definen los permisos a nivel de tabla de los usuarios.
Columns_priv: En ella se definen los permisos a nivel de columnas de los usuarios.
El servidor mysqld carga los contenidos de las tablas de permisos en memoria al arrancar. Podemos
hacer que lo vuelva a hacer en cualquier momento invocando al comando FLUSH PRIVILEGES.
La gestión de usuarios y permisos actuando directamente sobre estas tablas está recomendada sólo
en ocasiones muy puntuales. Lo normal es trabajar con herramientas gráficas como el MySQL
Administrator, o a través de los comandos SQL para gestionar usuarios y permisos. No obstante, es
bueno que el administrador de una base de datos MySQL conozca cómo se gestiona internamente
este tipo de información y pueda en casos muy puntuales trabajar directamente sobre estas tablas.
2.1 Ejemplos de acción directa sobre tablas de mysql
3) La práctica propuesta en el tema anterior que consistía en cambiar la contraseña del usuario root
en un sistema en el que no nos acordamos de la contraseña del root sería así:
Iniciamos el servidor pidiéndole que no tenga en cuenta los privilegios otorgados a los usuarios:
mysqld --skip-grant-tables --skip-networking
mysqladmin shutdown
De nada sirve controlar los privilegios de los usuarios dentro del servidor de bases de datos si
fuera del servidor, en el entorno del sistema operativo, estos usuarios tienen libre acceso al
sistema de ficheros. Para evitarlo debemos vigilar los permisos de acceso de los siguientes
archivos: las bases de datos y sus tablas, ficheros de logs y de estado, ficheros de
configuración, programas ejecutables como mysqld y scripts.
USE mysql;
UPDATE user SET Password = PASSWORD('nuevapasswd') WHERE User = 'pepito' AND Host = 'localhost';
FLUSH PRIVILEGES;
USE mysql;
DELETE FROM user WHERE Password = '';
FLUSH PRIVILEGES;
6) Crear un usuario que tenga todos los permisos a nivel global y que pueda acceder desde
cualquier equipo:
USE mysql;
INSERT INTO user VALUES('%','monty',PASSWORD('some_pass'),'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
FLUSH PRIVILEGES;
La razón de usar FLUSH PRIVILEGES al crear cuentas con INSERT es decirle al servidor que vuelva a
leer las tablas de permisos. De otro modo, los cambios no se tienen en cuenta hasta que se reinicie
el servidor. Con GRANT, FLUSH PRIVILEGES no es necesario.
La razón para usar la función PASSWORD() con INSERT es cifrar las contraseñas. El comando GRANT
cifra la contraseña, así que PASSWORD() no es necesario.
7) Crear un usuario que sólo tenga permiso de acceso al servidor, pero no para realizar otras
operaciones:
USE mysql;
INSERT INTO user (Host,User,Password) VALUES('localhost','dummy','');
FLUSH PRIVILEGES;
8) Crear un usuario que tenga los permisos de RELOAD y PROCESS a nivel global:
USE mysql;
INSERT INTO user SET Host='localhost',User='admin',Reload_priv='Y', Process_priv='Y';
FLUSH PRIVILEGES;
9) Crear un usuario llamado ‘custom’ que pueda acceder desde ciertos equipos, pero que no tenga
privilegios globales.
USE mysql;
INSERT INTO user (Host,User,Password) VALUES('localhost','custom',PASSWORD('obscure'));
INSERT INTO user (Host,User,Password) VALUES('whitehouse.gov','custom',PASSWORD('obscure'));
INSERT INTO user (Host,User,Password) VALUES('server.domain','custom',PASSWORD('obscure'));
Para otorgar ciertos privilegios al usuario ‘custom’ sobre ciertas bases de datos:
INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv)
VALUES('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv)
VALUES('whitehouse.gov','expenses','custom', 'Y','Y','Y','Y','Y','Y');
INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv)
VALUES('server.domain','customer','custom', 'Y','Y','Y','Y','Y','Y');
FLUSH PRIVILEGES;
3 Gestión de usuarios.
3.1 Creación de usuarios
Cuando creamos un nuevo usuario en MySQL, éste queda identificado por su nombre de usuario
más el nombre o IP del ordenador desde el cual hemos dicho que accederá (podemos utilizar el
carácter comodín '%' para representar varios ordenadores). La sintaxis es:
usuario@ordenador
Ejemplos de usuarios:
pepito
pepito@'%'
pepito@localhost
pepito@'192.168.0.%'
pepito@'192.168.1.0/255.255.255.0'
pepito@'%.midominio.org'
Utilizando la sentencia GRANT podemos crear un usuario a la par que otorgarle uno o varios
privilegios sobre los objetos de una base de datos, o la base de datos completa. Al encontrarse una
sentencia de tipo GRANT, el motor de MySQL revisa si el usuario existe previamente para el
contexto que estamos asignándole permisos, y si dicho usuario no está presente en el sistema, lo
crea.
Si creamos un usuario para una máquina o conjunto de máquinas determinado, ese usuario no podrá
conectar desde otras máquinas. Por ejemplo:
Un usuario que se identifique como 'anónimo' sólo podrá entrar desde el mismo ordenador donde se
está ejecutando el servidor.
En este otro ejemplo, el usuario 'anonimo' sólo puede conectarse desde un ordenador cuyo IP sea
'10.28.56.15'.:
A partir de la versión MySQL 5.0.2 existe la posibilidad de crear usuarios sin necesidad de
asignarles privilegios, utilizando la sentencia CREATE USER.
El usuario recién creado no tiene privilegio alguno, por lo que deberemos asignarle permisos
utilizando sentencias GRANT (esta vez sin la cláusula IDENTIFIED BY).
Si quiero que el usuario sólo pueda acceder desde la máquina donde está el servidor:
Si quiero que el usuario sólo pueda acceder desde una máquina con una dirección IP concreta puedo
utilizar la sintaxis:
Si quiero que el usuario sólo pueda acceder desde cualquier máquina de una red:
CREATE USER monty@192.168.1.% IDENTIFIED BY 'some_pass';
También es posible especificar una dirección con una máscara de red determinada:
Este es el método visto en el primer apartado del tema. Sólo es recomendado en circunstancias muy
concretas.
Existen varias herramientas de administración del servidor MySQL. Estas herramientas utilizan un
interfaz gráfico normalmente, así programas como MySQL Administrator, PHPMyAdmin o
MySQL Manager, permiten gestionar de forma muy sencilla e intuitiva todo lo relacionado con
usuarios y permisos dentro de nuestro sistema y además sin tener que conocer la sintaxis de los
comandos a utilizar.
Hasta la llegada de la versión 5.0.2, DROP USER borra sólo cuentas que no tienen permisos. A
partir de MySQL 5.0.2, se modificó para eliminar permisos de cuenta también. Esto significa que el
procedimiento para borrar una cuenta depende en su versión de MySQL.
Hasta MySQL 5.0.2, se puede borrar una cuenta y sus permisos como sigue:
El comando RENAME USER renombra cuentas de usuario MySQL existentes. Para usarlo, debemos
tener el permiso CREATE USER global o el permiso UPDATE para la base de datos MySQL. Fue
añadido a partir de la versión 5.0.2. La sintaxis del comando para cambiar el nombre de un
usuario es:
Ejemplo:
El comando SET PASSWORD asigna una contraseña a una cuenta de usuario MySQL existente.
Puede utilizarse de dos formas:
Para cambiar la contraseña del usuario actual que tiene abierta la conexión. En este caso
cualquier usuario podría cambiar su contraseña. La sintaxis sería:
Para cambiar la contraseña de un usuario cualquiera del sistema. Sólo los clientes con el
permiso UPDATE para la base de datos mysql pueden hacerlo. La sintaxis en este caso sería:
Cuando se crea un usuario o posteriormente con Alter User, se pueden establecer ciertos aspectos
relativos a la duración y caducidad de las contraseñas:
El comando GRANT permite a los administradores de sistemas crear cuentas de usuario MySQL y
darles permisos.
Nivel global. Se aplican a todas las bases de datos de un servidor dado. Se almacenan en la
tabla mysql.user. Se utiliza GRANT ALL ON *.* para otorgarlos.
Nivel Base de datos. Se aplican a todos los objetos de una base de datos dada. Estos
permisos se almacenan en las tablas mysql.db y mysql.host. Se utiliza GRANT ALL ON
db_name.* para otorgarlos.
Nivel de tabla. Se aplican a todas las columnas de una tabla dada. Se almacenan en la tabla
mysql.tables_priv. Se utiliza GRANT ALL ON db_name.tbl_name para otorgarlos.
Nivel de columna. Se aplican a ciertas columnas en una tabla dada. Se almacenan en la tabla
mysql.columns_priv. Se utiliza GRANT UPDATE(col1,col2,…coln)ON
db_name.tbl_name para otorgarlos. Los únicos valores priv_type que puede especificar
para una columna son select, insert, y update.
La siguiente sentencia concede al usuario 'anonimo' el privilegio de ejecutar consultas sobre la tabla
'gente' de la base de datos 'prueba'.
Para conceder privilegios globales se usa ON *.*. En este caso los privilegios se conceden en todas
las tablas de todas las bases de datos:
Para conceder privilegios sobre todas las tablas de una base de datos determinada se usa ON
nombre_db.*:
En el ejemplo anterior el usuario anónimo podrá consultar e insertar registros en cualquier tabla de
la base de datos Prueba.
En la siguiente sentencia concedemos una gran cantidad de permisos al usuario julia sobre las tablas
de la base de datos películas.
GRANT SELECT, INSERT, UPDATE, DELETE, INDEX, ALTER, CREATE, DROP ON peliculas.* TO julia;
Cuando un permiso se concede with grant option, se le permite al usuario correspondiente delegar
un permiso que posee sobre otro usuario.
Además de la opción de poder asignar los permisos a otros usuarios, es posible definir otras
opciones dentro de la claúsula WITH:
Por ejemplo:
Para borrar todos los privilegios a un usuario sobre una base de datos concreta utilizaríamos:
SHOW PRIVILEGES;
5 Gestión de roles
Los roles en MySQL son un conjunto de privilegios identificados mediante un nombre. Al igual que
ocurre con las cuentas de usuario es posible añadir y quitar privilegios dentro de un rol con las
sentencias Grant y Revoke.
A las cuentas de usuario se les puede asociar roles, lo que garantizará a esa cuenta los privilegios
que se incluyan dentro de ellos.
Trabajar con roles puede facilitar significativamente la gestión de la seguridad dentro del servidor
de bases de datos de la organización, sobre todo en aquellas organizaciones con gran número de
usuarios y con funciones y perfiles claramente definidos. En las antiguas versiones del servidor
MySQL no estaban implementados..
La siguiente lista resume los comandos utilizados en MySQL para trabajar con roles:
CREATE ROLE y DROP ROLE permiten su creación y borrado.
GRANT y REVOKE permiten añadir o quitar privilegios dentro de un rol.
SHOW GRANTS muestra los privilegios y roles asignados a los usuarios y a los roles.
SET DEFAULT ROLE establece qué roles de cuenta están activos por defecto cuando la
cuenta inicie sesión.
SET ROLE cambia los roles que están activos dentro de la sesión actual.
La función CURRENT_ROLE() muestra los roles que están activos en la sesión actual.
Las variables MANDATORY_ROLES y ACTIVATE_ALL_ROLES_ON_LOGIN se
pueden utilizar en el fichero de configuración para definir roles obligatorios para todos los
usuarios y para activar automáticamente todos los roles que los usuarios tengan asignados.
Los nombres de los roles siguen la misma nomenclatura que los nombres de cuentas de usuario, es
decir, el formato nombre@host. Si la parte del host es omitida, se asigna automáticamente a '%'. La
parte del nombre y del host podrían ir sin comillas, siempre y cuando no contengan caracteres
especiales.
Para asignar privilegios a un rol podemos utilizar la sentencia GRANT como lo hemos venido
haciendo hasta ahora, con la diferencia de que en la parte del TO se referencia al rol en lugar de al
usuario:
GRANT ALL ON app_db.* TO 'app_developer';
GRANT SELECT ON app_db.* TO 'app_read';
GRANT INSERT, UPDATE, DELETE ON app_db.* TO 'app_write';
Una vez que los roles están creados, es posible asignárselos a las cuentas de usuario:
CREATE USER 'dev1'@'localhost' IDENTIFIED BY 'dev1pass';
CREATE USER 'read_user1'@'localhost' IDENTIFIED BY 'read_user1pass';
CREATE USER 'read_user2'@'localhost' IDENTIFIED BY 'read_user2pass';
CREATE USER 'rw_user1'@'localhost' IDENTIFIED BY 'rw_user1pass';
Como vemos, la sentencia GRANT para asignar roles difiere de la de asignación de privilegios, ya
que no tiene cláusula ON. Por ello, no se pueden mezclar roles y privilegios dentro de la misma
sentencia. Es posible asignar indistintamente roles y privilegios a un usuario, pero con sentencias
separadas.
Es posible especificar roles como obligatorios para todos los usuarios, si los incluimos en la
variable del sistema MANDATORY_ROLES. El servidor asigna automáticamente los roles
obligatorios a los usuarios sin necesidad de asignárselos explícitamente.
Los roles incluidos en mandatory_roles no pueden ser quitados a un usuario con REVOKE o
borrados con DROP ROLE.
Los roles obligatorios, al igual que los asignados explícitamente, no tienen efecto real, mientras no
estén activados. La activación de roles tiene lugar si la variable
ACTIVATE_ALL_ROLES_ON_LOGIN está habilitada, o si los usuarios los tienen habilitados por
defecto. Para activar roles en tiempo de ejecución debemos utilizar la sentencia SET ROLE.
5.3 Chequear los roles y privilegios asignados
Para verificar los privilegios y roles asignados a una cuenta, usaremos la sentencia SHOW
GRANTS. Por ejemplo:
Sin embargo, escrito así, no podríamos saber qué privilegios incluirían los roles. Si quisiéramos
mostrar también los privilegios asignados a los roles, deberíamos utilizar la cláusula USING con el
nombre o nombres de los roles:
SHOW GRANTS también se puede utilizar para mostrar los privilegios asignados a un determinado
rol:
Los roles asignados a una cuenta de usuario pueden estar activos o inactivos dentro de la sesión
abierta por ese usuario en el servidor. Si un rol está activo, sus privilegios se aplicarán y si no, no.
Para determinar qué roles están activos dentro de la actual sesión, podemos usar la función
CURRENT_ROLE(). Por ejemplo:
SELECT CURRENT_ROLE();
Por defecto, los roles asignados a una cuenta explícitamente o nombrados en la variable
mandatory_roles no se activan automáticamente, a no ser que la variable
activate_all_roles_on_login esté definida. Por defecto, esta variable está deshabilitada.
Para especificar qué roles deben estar activos cada vez que un usuario se conecta al servidor,
deberíamos utilizar la sentencia SET DEFAULT ROLE.
Por ejemplo, para activar por defecto todos los roles asignados a ciertos usuarios, podríamos
utilizar el comando:
SET DEFAULT ROLE ALL TO
dev1@localhost, read_user1@localhost, read_user2@localhost,rw_user1@localhost;
Para conocer cuáles son los roles por defecto que tiene asignado en un momento dado un usuario,
podemos hacer un select a la tabla del diccionario de datos MYSQL.DEFAULT_ROLES.
Dentro de una sesión, un usuario puede ejecutar SET ROLE para cambiar el conjunto de roles
activos:
REVOKE se puede utilizar también para modificar los privilegios que se incluyen en un rol:
REVOKE INSERT, UPDATE, DELETE ON app_db.* FROM 'app_write';
Si modificamos los privilegios de un rol, ese cambio afectará a todos los usuarios que tuvieran
asignado y activo ese rol.