Administración de Usuarios y Seguridad en MySQL: Gestión de Contraseñas y Privilegios

Enviado por Programa Chuletas y clasificado en Informática y Telecomunicaciones

Escrito el en español con un tamaño de 11,65 KB

Gestión de Usuarios y Seguridad en MySQL

Este documento detalla una serie de procedimientos y consideraciones clave para la administración de usuarios, contraseñas y permisos en un entorno MySQL. Se abordan desde la creación básica de usuarios hasta la gestión avanzada de privilegios y la comprensión de la seguridad de las contraseñas.

1. Creación de Usuario y Asignación de Contraseña con mysqladmin

Para crear un usuario y asignarle una contraseña desde la línea de comandos utilizando el comando mysqladmin, sigue los siguientes pasos:

SET SESSION sql_mode=0;
GRANT ALL ON *.* TO 'ASIR1'@'localhost';
mysqladmin -u ASIR1 -h localhost password 'asir'

Nota: El comando mysqladmin password es una forma legacy de establecer contraseñas y puede no ser la más segura o recomendada en versiones modernas de MySQL. Es preferible usar ALTER USER o SET PASSWORD.

2. Creación de Usuario y Asignación de Contraseña con SET PASSWORD

Para crear un usuario y asignarle una contraseña mediante el comando SET PASSWORD, que es una práctica más moderna y segura:

SET SESSION sql_mode=0;
GRANT ALL ON *.* TO 'ASIR2'@'localhost';
SET PASSWORD FOR 'ASIR2'@'%' = PASSWORD('asir');

Importante: La función PASSWORD() ha sido deprecada en MySQL 8.0. En versiones recientes, se recomienda usar SET PASSWORD FOR 'usuario'@'host' = 'nueva_contraseña'; o ALTER USER 'usuario'@'host' IDENTIFIED BY 'nueva_contraseña';, ya que el servidor se encarga automáticamente del hashing.

3. Gestión de Contraseñas y Permisos con GRANT USAGE

3.1. Cambio de Contraseña Propia

Para cambiar tu propia contraseña de usuario:

SET PASSWORD FOR 'usuario2'@'localhost' = PASSWORD('asir2');

Al igual que en el punto anterior, la función PASSWORD() es obsoleta en MySQL 8.0. Se recomienda ALTER USER 'usuario2'@'localhost' IDENTIFIED BY 'asir2'; o SET PASSWORD = 'asir2'; si estás conectado como ese usuario.

3.2. Asignación de Contraseña a una Cuenta sin Afectar Permisos (GRANT USAGE)

Para crear una cuenta sin permisos iniciales y asignarle una contraseña, se utiliza CREATE USER seguido de GRANT USAGE. GRANT USAGE crea la cuenta si no existe y no otorga ningún privilegio específico, solo la capacidad de conectarse.

CREATE USER 'usuario3'@'localhost';
GRANT USAGE ON *.* TO 'usuario3'@'localhost' IDENTIFIED BY 'ASIR';

Nota: La cláusula IDENTIFIED BY en GRANT USAGE es la forma estándar de establecer la contraseña al crear o modificar un usuario sin otorgar permisos adicionales.

4. Creación de Usuario con Contraseña mediante INSERT en la Tabla mysql.user

Establecer una contraseña al crear una nueva cuenta especificando un valor directamente para la columna Password en la tabla mysql.user mediante INSERT:

INSERT INTO user (Host, User, Password, Ssl_type, Ssl_cipher, X509_issuer, X509_subject)
VALUES ('localhost', 'USUARIO4', 'oscure', '', '', '', '');

Advertencia: La manipulación directa de la tabla mysql.user mediante INSERT o UPDATE es altamente desaconsejada en la mayoría de los casos. Puede llevar a inconsistencias, problemas de seguridad y no es compatible con las funciones de hashing de contraseñas modernas de MySQL. Siempre se deben usar los comandos DDL (CREATE USER, ALTER USER) y DCL (GRANT, REVOKE) para gestionar usuarios y permisos.

5. Cambio de Contraseña Existente con UPDATE en la Tabla mysql.user

Para cambiar la contraseña en una cuenta existente utilizando UPDATE para especificar el valor de la columna Password:

UPDATE user SET Password = PASSWORD('oscure4') WHERE User='usuario4';

Advertencia: Al igual que con INSERT, la modificación directa de la tabla mysql.user es desaconsejada. Utiliza ALTER USER 'usuario4'@'host' IDENTIFIED BY 'oscure4'; o SET PASSWORD FOR 'usuario4'@'host' = 'oscure4';. Además, la función PASSWORD() es obsoleta en MySQL 8.0.

6. Comportamiento de Contraseñas con INSERT Directo en mysql.user

Ejecuta las siguientes sentencias y analiza los resultados a nivel de contraseña:

C:\> mysql -u root mysql
mysql> INSERT INTO user VALUES('%','usuario2','tu_pass','Y','Y','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','','','','',0,0,0,0);
mysql> FLUSH PRIVILEGES;
C:\> mysql -u usuario2 -ptu_pass

Análisis de Resultados:

Cuando se inserta directamente 'tu_pass' en la columna Password de la tabla mysql.user sin usar la función PASSWORD() (o sin que el servidor la aplique automáticamente, como ocurre con CREATE USER ... IDENTIFIED BY), el valor se almacena tal cual (o con un hashing básico si la versión de MySQL lo aplica por defecto a esa columna). Sin embargo, al intentar iniciar sesión con -ptu_pass, el cliente MySQL aplica internamente una función de hashing a 'tu_pass' antes de enviarla al servidor para comparación.

El problema radica en que el valor almacenado en la tabla user ('tu_pass') no es el resultado de la función de hashing que el cliente aplica a 'tu_pass'. Por lo tanto, el hash generado por el cliente nunca coincidirá con el valor almacenado en la tabla user, lo que hace imposible iniciar sesión como ese usuario. En versiones modernas de MySQL, la columna Password ha sido reemplazada por authentication_string, y el servidor gestiona el hashing de forma más robusta.

7. Creación de Usuario con Permisos Globales

Para crear un nuevo usuario local llamado admin, asignarle una contraseña y otorgarle permisos globales sobre todas las bases de datos, incluyendo la opción de conceder permisos a otros:

CREATE USER 'admin'@'localhost' IDENTIFIED BY 'admin';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;

Recomendación: Otorgar ALL PRIVILEGES y WITH GRANT OPTION a un usuario que no sea root debe hacerse con extrema precaución, ya que le confiere un control casi total sobre el servidor.

8. Revocación de Permisos Específicos (SUPER y GRANT OPTION)

Para eliminar los permisos SUPER y GRANT OPTION del usuario admin, se pueden utilizar dos métodos:

8.1. Revocación con REVOKE

Esta es la forma preferida y segura de revocar permisos:

REVOKE SUPER, GRANT OPTION ON *.* FROM 'admin'@'localhost';

8.2. Revocación Manual (Modificación Directa de mysql.user)

Aunque es posible, la modificación directa de la tabla mysql.user es desaconsejada y debe usarse solo en situaciones de recuperación o depuración muy específicas, y siempre seguida de FLUSH PRIVILEGES.

USE mysql;
UPDATE user SET Grant_priv='N', Super_priv='N' WHERE User='admin';
SELECT Grant_priv FROM user WHERE User='admin';
FLUSH PRIVILEGES;

Nota: En versiones modernas de MySQL, las columnas de privilegios en mysql.user pueden variar, y la columna authentication_string es la que almacena el hash de la contraseña.

9. Comportamiento de Contraseñas al Crear Usuarios sin PASSWORD()

¿Qué ocurre si intentamos crear un usuario con contraseña con el comando CREATE USER sin utilizar explícitamente la función PASSWORD()? ¿Podemos conocer la contraseña original del usuario?

En versiones modernas de MySQL (desde 5.7.6), cuando se utiliza CREATE USER 'usuario'@'host' IDENTIFIED BY 'contraseña';, el servidor aplica automáticamente la función de hashing adecuada a la contraseña proporcionada antes de almacenarla en la columna authentication_string (o Password en versiones muy antiguas). Por lo tanto, la contraseña nunca se almacena en texto plano.

En versiones muy antiguas de MySQL, si se insertaba directamente en la columna Password de mysql.user sin usar PASSWORD(), la contraseña podía almacenarse en texto plano o con un hashing muy básico. Sin embargo, con CREATE USER, el hashing siempre ha sido el comportamiento estándar.

¿Podemos conocer la contraseña original del usuario?

No, si la contraseña se ha almacenado correctamente mediante un algoritmo de hashing (como es el caso con CREATE USER ... IDENTIFIED BY), es un proceso unidireccional. No se puede "deshashear" para obtener la contraseña original. La única forma de "conocer" la contraseña sería si, por algún error de configuración o versión muy antigua, se hubiera almacenado en texto plano. En ese caso, se podría consultar directamente:

SELECT authentication_string FROM mysql.user WHERE User='usuario';

O, para versiones muy antiguas con la columna Password:

SELECT Password FROM mysql.user WHERE User='usuario';

Pero esto solo revelaría el hash o el texto plano si se almacenó así, no la contraseña original si se usó un hashing seguro.

10. Permisos Críticos en MySQL: Precauciones al Concederlos

Existen cinco permisos que requieren especial cautela al ser concedidos debido a su potencial impacto en la seguridad y estabilidad del servidor:

  • GRANT OPTION: Permite a los usuarios otorgar y revocar sus propios privilegios a otros usuarios. Dos usuarios con diferentes privilegios y con GRANT OPTION pueden combinar sus privilegios, escalando así sus capacidades.
  • ALTER: Puede ser utilizado de manera inadecuada para sabotear el sistema de privilegios mediante el renombrado de tablas (por ejemplo, renombrar mysql.user para manipularla).
  • SHUTDOWN: Permite cerrar el servidor MySQL. Puede utilizarse maliciosamente para denegar el servicio a otros usuarios de manera total, causando una interrupción.
  • PROCESS: Permite ver el texto de todas las consultas que se estén ejecutando actualmente en el servidor, incluyendo consultas que establecen o modifican contraseñas, lo que podría exponer información sensible.
  • SUPER: Otorga una amplia gama de capacidades administrativas, como cerrar conexiones de otros clientes, cambiar el funcionamiento del servidor (variables de sistema), o ejecutar comandos que de otro modo estarían restringidos. Es un permiso muy potente y debe concederse con extrema precaución.

Entradas relacionadas: