5.7. Gestión de la cuenta de usuario MySQL

MySQL 5.0

5.7. Gestión de la cuenta de usuario MySQL

Esta sección describe cómo preparar cuentas para clientes en su servidor MySQL. Se discuten los siguientes tópicos:

  • El significado de los nombres de cuenta y contraseñas usados en MySQL y cómo se compara con los nombres y contraseñas usadas por su sistema operativo.

  • Cómo preparar una nueva cuenta y borrar una existente

  • Cómo camviar contraseñas

  • Guías para usar contraseñas de forma segura

  • Cómo usar conexiones seguras mediante SSL

5.7.1. Nombres de usuario y contraseñas de MySQL

Una cuenta MySQL se define en términos de un nombre de usuario y el equipo o equipos desde los que el usuario puede conectar al servidor. La cuenta también tiene una contraseña. Hay varias diferencias entre cómo se usan los nombres de usuario y contraseñas en MySQL y cómo los usa el sistema operativo:

  • Los nombres de usuario, tal como los usa MySQL para autentificación, no tienen nada que ver con los nombres de usuario (nombres de logueo) tal y como los usa Windows o Unix. En Unix, la mayoría de clientes MySQL por defecto tratan de loguear usando el nombre de usuario Unix como el nombre de usuario MySQL, pero eso es sólo como conveniencia. El comportamiento por defecto puede cambiarse fácilmente, ya que el programa clienet permite especificar cualquier nombre de usuario con la opción o . Como esto significa que cualquiera puede intentar conectar al servidor usando cualquier nombre de usuario, no puede hacer una base de datos segura de ninguna forma a no ser que todas las cuentas MySQL tengan contraseña. Cualquiera que especifique un nombre de usuario para una cuenta que no tenga contraseña puede conectar al servidor.

  • Nombre de usuarios en MySQL pueden tener como máximo 16 carácteres de longitudo. Este límite está hard-codeado en los servidores y clientes MySQL, y tratar de evitarlo mediante la modificación de las tablas en la base de datos no funciona .

    Nota: Nunca debe alterar ninguna de las tablas en la base de datos de ninguna forma excepto mediante la ejecución de los scpripts proporcionados expresamente para este propósito con la distribución MySQL. Tratar de redefinir las tablas de sistema MySQL de cualquier otra forma da como resultado un comportamiento indefinido (y no soportado).

    Nombres de usuario en el sistema operativo están completamente desligados de los nombres de usuario de MySQL y pueden tener longitud máxima diferente. Por ejemplo, los nombres de usuario Unix típicamente están limitados a 8 carácteres.

  • Las contraseñas MySQL no tienen nada que ver con las contraseñas para loguear en el sistema operativo. No hay una conexión necesaria entre la contraseña que usa para entrar en una máquina Windows o Unix y la contraseña usada para acceder al servidor MySQL en esa máquina.

  • MySQL encripta contraseñas usando su propio algoritmo. Esta encriptación es diferente de la usada durante el proceso de logueo de Unix. La encriptación de contraseña es la misma que la implementada en la función . La encriptación de contraseñas Unix es la misma que la implementada por la función SQL . Consulte la descripción de las funciones y en Sección 12.9.2, “Funciones de encriptación”. Desde la versión 4.1, MySQL usa un método más fuerte de autenticación que tiene una mejor protección de contraseña durante el proceso de conexión que en versiones anteriores. Es seguro incluso si los paquetes TCP/IP se esnifan o la base de datos se captura. (En versiones anteriores , incluso aunque las contraseñas se guardan encriptadas en la tabla , se podía usar conocimiento de la contraseña encriptada para conectar al servidor MySQL.)

Cuando instala MySQL, las tablas de permisos se inicializan con un conjunto inicial de cuentas. Estas cuentas tienen nombres y privilegios de acceso descritos en Sección 2.9.3, “Hacer seguras las cuentas iniciales de MySQL”, que discute cómo asignarles contraseñas. Así mismo, normalmente inicialice, modifique y borre cuentas mediante los comandos y . Consulte Sección 13.5.1.3, “Sintaxis de y .

Cuando conecta a un servidor MySQL con un cliente de líneas de comando, puede especificar el nombre de usuario y contraseña para la cuenta que desea usar:

shell> mysql --user=monty --password= 

Si prefiere opciones cortas, el comando es así:

shell> mysql -u monty -p 

No deben haber espacios entre la opción y el valor de contraseña a continuación. Consulte Sección 5.6.4, “Conectarse al servidor MySQL”.

El comando precedente incluye el valor de la contraseña en la línea de comando, lo que puede ser un riesgo de seguridad. Consulte Sección 5.7.6, “Guardar una contraseña de forma segura”. Para evitarlo, especifique la opción o sin ningún valor de contraseña:

shell> mysql --user=monty --password 
shell> mysql -u monty -p 

A continuación, el programa cliente muestra un prompt y espera a que introduzca la contraseña. (En estos ejemplos, no se interpreta como contraseña, ya que está separado de la precedente opción de contraseña con un espacio.)

En algunos sistemas, la llamada que MySQL usa para pedir una contraseña automáticamente limita la contraseña a ocho carácteres. Este es un problema con la librería de sistema, no con MySQL. Internamente, MySQL no tienen ningún límite para la longitud de la contraseña. Para solventar este problema, cambie su contraseña MySQL a un valor que tenga ocho o menos carácteres, o ponga su contraseña en un fichero de opciones.

5.7.2. Añadir nuevas cuentas de usuario a MySQL

Puede crear cuentas MySQL de dos formas:

  • Usando comandos

  • Manipulando las tablas de permisos MySQL directamente

El método preferido es usar comandos , ya que son más concisos y menos propenso a errores. . está disponible desde MySQL 3.22.11; su sintaxis se describe en Sección 13.5.1.3, “Sintaxis de y .

Otra opción para crear cuentas es usar uno de los diversos programas proporcionados por terceras partes que ofrecen capacidades para administradores de MySQL. es una de ellos.

Los siguientes ejemplos muestran cómo usar el programa cliente mysql para añadir nuevos usuarios. Estos ejemplos asumen que los permisos se inicializan según las pautas descritas en Sección 2.9.3, “Hacer seguras las cuentas iniciales de MySQL”. Esto significa que para realizar cambios, debe conectar al servidor MySQL como el usuario , y la cuenta debe tener el privilegio para la base de datos y el permiso administrativo .

En primer lugar, use el programa mysql para conectar al servidor como el usuario :

shell> mysql --user=root mysql

Si ha asignado una contraseña a la cuenta , necesitará la opción o para este comando mysql y también para los mostrados a continuación en esta sección.

Tras la conexión al servidor como , puede añadir nuevas cuentas. El siguiente comando usa para inicializar nuevas cuentas:

mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'
    ->     IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'
    ->     IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost';
mysql> GRANT USAGE ON *.* TO 'dummy'@'localhost';

Las cuentas creadas con estos comandos tienen las siguientes propiedades:

  • Dos de las cuentas tienen un nombre de usuario de y una contraseña de . Ambas cuentas son cuentas de superusuario con plenos permisos para hacer cualquier cosa. Una cuenta () puede usarse sólo cuando se conecte desde el equipo local. La otra () puede usarse para conectarse desde cualquier otro equipo. Note que es necesario tener ambas cuentas para que sea capaz de conectarse desde cualquier sitio como . Sin la cuenta , la cuenta anónima para creada por mysql_install_db tendría precedencia cuando conecte desde el equipo local. Como resultado, se trataría como un usuario anónimo. La razón para ello es que el usuario anónimo tiene un valor más específico en la columna que la cuenta y por lo tanto toma precedencia en la ordenación de la tabla . (La ordenación de la tabla se discute en Sección 5.6.5, “Control de acceso, nivel 1: Comprobación de la conexión”.)

  • Una cuenta tiene un nombre de usuario de y no tiene contraseña. Esta cuenta puede usarse sólo desde el equipo local. Tiene los privilegios administrativos y . Éstos permiten al usuario ejecutar los comandos mysqladmin reload, mysqladmin refresh, y mysqladmin flush- , así como mysqladmin processlist . No se dan permisos para acceder a ninguna base de datos. Puede añadir tal privilegio posteriormente mediante un comando adicional.

  • Una cuenta tiene un nombre de usuario de sin contraseña. Esta cuenta puede usarse sólo desde el equipo local. No tiene ningún privilegio. El permiso en el comando permite crear una cuenta sin darle ningún privilegio. Tiene el efecto de inicializar todos los privilegios globales a . Se asume que se otorgarán privilegios específicos posteriormente.

Como alternativa a , puede crear la misma cuenta directamente mediante comandos y después diciendo al servidor que recargue las tablas de permisos usando :

shell> mysql --user=root mysql
mysql> INSERT INTO user
    ->     VALUES('localhost','monty',PASSWORD('some_pass'),
    ->     'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user
    ->     VALUES('%','monty',PASSWORD('some_pass'),
    ->     'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user SET Host='localhost',User='admin',
    ->     Reload_priv='Y', Process_priv='Y';
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('localhost','dummy','');
mysql> FLUSH PRIVILEGES;

La razón de usar al crear cuantas con es decir 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 , no es necesario.

La razón para usar la función con es encriptar las contraseñas. El comando encripta la contraseña, así que no es necesario.

El valor activa permisos para las cuentas. Para la cuenta , puede emplear la sintaxis más clara extendida usando .

En el comando para la cuenta account, sólo las columnas , , y en el registro de la tabla tienen valores asignados. Ninguna de las columnas de permisos se asignan explícitamente, así que MySQL les asigna a todas el valor por defecto de . Esto es equivalente al funcionamiento de .

Para inicializar una cuenta de super usuario, sólo es necesario crear una entrada en la tabla con las columnas de permisos inicializadas a . Los privilegios de la tabla son globales, así que no se necesitan registros en ninguna de las otras tablas de permisos.

Los siguientes ejemplos crean tres cuentas y les dan acceso a bases de datos específicas. Cada una de ellas tiene un nombre de usuario y contraseña .

Para crear las cuentas con , use los siguientes comandos:

shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON bankaccount.*
    ->     TO 'custom'@'localhost'
    ->     IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON expenses.*
    ->     TO 'custom'@'whitehouse.gov'
    ->     IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON customer.*
    ->     TO 'custom'@'server.domain'
    ->     IDENTIFIED BY 'obscure';

Las tres cuentas pueden usarse de la siguiente manera:

  • La primera cuenta puede acceder a la base de datos , pero sólo desde el equipo local.

  • La segunda cuenta puede acceder la base de datos , pero sólo desde el equipo .

  • La tercera cuenta puede acceder la base de datos , pero sólo desde el equipo .

Para inicializar las cuentas sin usar , use los comandos como se explica para modificar las tablas de permisos directamente:

shell> mysql --user=root mysql
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('localhost','custom',PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('whitehouse.gov','custom',PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('server.domain','custom',PASSWORD('obscure'));
mysql> 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');
mysql> 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');
mysql> 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');
mysql> FLUSH PRIVILEGES;

Los primeros tres comandos añaden registros en la tabla que permiten al usuario conectar desde los equipos con la contraseña dada, pero no otorga privilegios blobales (todos los privilegios se inicializan al valor por defecto ). Los siguientes tres comandos añaden registros en la tabla que otorgan privilegios a para las bases de datos , , y , pero sólo cuando se accede desde los equipos apropiados. Como siempre, cuando modifique las tablas de permisos directamente, debe decirle al servidor que las recargue con para que los cambios en los permisos tengan efecto.

Si quiere dar a un usuario específico acceso desde todas las máquinas dentro de un dominio dado (por ejemplo, ), puede realizar un comando que use el carácter comodín '' en la parte del equipo del nombre de cuenta:

mysql> GRANT ...
    ->     ON *.*
    ->     TO 'myname'@'%.mydomain.com'
    ->     IDENTIFIED BY 'mypass';

Para hacer lo mismo modificando las tablas de permisos directamente, haga lo siguiente:

mysql> INSERT INTO user (Host,User,Password,...)
    ->     VALUES('%.mydomain.com','myname',PASSWORD('mypass'),...);
mysql> FLUSH PRIVILEGES;

5.7.3. Eliminar cuentas de usuario de MySQL

Para eliminar una cuenta, use el comando , descrito en Sección 13.5.1.2, “Sintaxis de .

5.7.4. Limitar recursos de cuentas

Una forma de limitar los recursos de los servidores MySQL es asignar a la variable de sistema un valor distinto de cero. Sin embargo,este método es estrictamente global, y no está permitido para la administración de cuentas individuales. Además, limita sólo el número de conexiones simultáneas hechas usando una sóla cuenta, y no lo que un cliente puede hacer una vez conectado. Ambos tipos de control son interesantes para muchos administradores de MySQL, particularmente aquéllos que trabajan en ISPs.

En MySQL 5.0, puede limitar los siguientes recursos de servidor para cuentas individuales:

  • El número de consultas que una cuenta puede realizar por hora

  • El número de actualizaciones que una cuenta puede hacer por hora

  • El número de veces que una cuenta puede conectar con el servidor por hora

Cualquier comando que un cliente puede realizar cuenta en el límite de consultas. Sólo los comandos que modifiquen la base de datos o las tablas cuentan en el límite de actualizaciones.

Desde MySQL 5.0.3, es posible limitar el número de conexiones simultáneas al servidor por cuenta.

Una cuenta en este contexto es un registro en la tabla . Cada cuenta se identifica unívocamente por los valores de las columnas y .

Como prerrequisito para usar esta característica, la tabla en la base de datos debe contener las columnas relacionadas con el recurso. Los límites de recursos se guardan en las columnas , , , y . Si su tabla no tiene estas columnas, debe actualizarla; consulte Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.

Para cambiar el límite de recursos con un comando use la cláusula que nombra cada recurso a ser limitado y un contador por hora indicando el valor límite. Por ejemplo, para crear una nueva cuenta que pueda acceder a la base de datos , pero sólo de forma limitada, utilice este comando:

mysql> GRANT ALL ON customer.* TO 'francis'@'localhost'
    ->     IDENTIFIED BY 'frank'
    ->     WITH MAX_QUERIES_PER_HOUR 20
    ->          MAX_UPDATES_PER_HOUR 10
    ->          MAX_CONNECTIONS_PER_HOUR 5
    ->          MAX_USER_CONNECTIONS 2;

No todos los tipos de límites necesitan nombrarse en la cláusula , pero los nombrados pueden presentarse en cualquier orden. El valor para cada límite por hora debe ser un entero representando el contador por hora. Si el comando no tiene cláusula , los límites se inicializan con el valor por defecto de cero (o sea, sin límite). Para , el límite es un entero indicando el máximo número de conexiones simultáneas que la cuenta puede hacer en cualquier momento. Si el límite asignado es el valor por defecto de cero, la variable de sistema determina el número de conexiones simultáneas para la cuenta.

Para inicializar o cambiar los límites de una cuenta existente, use un comando a nivel global (). El siguiente comando cambia el límite de consultas para a 100:

mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
    ->     WITH MAX_QUERIES_PER_HOUR 100;

Este comando deja los permisos existentes de la cuenta inalterados y modifica sólo los valores cuyo límite se especifica.

Para eliminar un límite existente, ponga su valor a cero. Por ejemplo, para eliminar el límite de cuántas veces por hora puede conectar , use este comando:

mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
    ->     WITH MAX_CONNECTIONS_PER_HOUR 0;

El conteo del uso de recursos toma lugar cuando una cuenta tiene un límite distinto a cero para el uso de cualquier recurso.

Mientras el servidor está en ejecución, cuenta el número de veces que cada cuenta usa los recursos. Si una cuenta llega a su límite en el número de conexiones en la última hora, se rechazan cualquier intento de conexión mientras dure la hora. De forma similar, si la cuenta llega a su límite de consultas o actualizaciones, consultas o actualizaciones adicionales se rechazan mientras dure la hora. En cualquier caso, se muestra el mensaje de error apropiado

El conteo de recursos se hace por cuenta, no por cliente. Por ejemplo, si una cuenta tiene un límite de 50 consultas, no puede incrementar el límite a 100 haciendo dos conexiones simultáneas al servidor. Las consultas de ambas conexiones se cuentan juntas.

El contador actual por hora de uso de recursos puede reiniciarse globalmente para todas las cuentas, o individualmente para una cuenta dada:

  • Para reiniciar los contadores actuales a cero para todas las cuentas, ejecute el comando . Los contadores también pueden reiniciarse recargando las tablas de permisos (por ejemplo,k con un comando o mysqladmin reload).

  • Los contadores para una cuenta individual pueden ponerse a cero cambiando cualquiera de sus límites. Para hacerlo, use como se ha descrito anteriormente y especifique un valor límtite igual al valor que tiene la cuenta en ese momento.

Los reinicios de contadores no afectan el límite .

Todos los contadores empiezan a cero cuando el servidor arranca; los contadores no se guardan al reiniciar.

5.7.5. Asignar contraseñas a cuentas

Se pueden asignar contraseñas desde la línea de comandos usando el comando mysqladmin :

shell> mysqladmin -u  -h  password ""

La cuenta para la que este comando cambia la contraseña es la que tiene un registro en la tabla que coincida el con la columna y un equipo cliente desde el que se conecta en la columna .

Otra forma de asignar una contraseña en una cuenta es con el comando :

mysql> SET PASSWORD FOR 'jeffrey'@'%' = PASSWORD('biscuit');

Sólo los usuarios tales como con acceso de modificación para la base de datos puede cambiar la contraseña de otro usuario. Si no está conectado como un usuario anónimo, puede cambiar su propia contraseña omitiendo la cláusula :

mysql> SET PASSWORD = PASSWORD('biscuit');

Puede usar el comando globalmente () para asignar una contraseña a una cuenta sin afectar los permisos actuales de la cuenta:

mysql> GRANT USAGE ON *.* TO 'jeffrey'@'%' IDENTIFIED BY 'biscuit';

Aunque generalmente es peferible asignar contraseñas usando uno de los métodos precedentes, puede hacerlo modificando la tabla directamente:

  • Para establecer una contraseña al crear una nueva cuenta, especifique un valor para la columna :

    shell> mysql -u root mysql
    mysql> INSERT INTO user (Host,User,Password)
        -> VALUES('%','jeffrey',PASSWORD('biscuit'));
    mysql> FLUSH PRIVILEGES;
    
  • Para cambiar la contraseña en una cuenta existente, use para especificar el valor de la columna :

    shell> mysql -u root mysql
    mysql> UPDATE user SET Password = PASSWORD('bagel')
        -> WHERE Host = '%' AND User = 'francis';
    mysql> FLUSH PRIVILEGES;
    

Cuando especifique una contraseña en una cuenta mediante , , o , debe usar la función para encriptarlo. (La única excepción es que no necesita usar si la contraseña está vacía .) es necesario ya que la tabla guarda las contraseñas encriptadas, no en texto plano. Si olvida este hecho, es posible que guarde contraseñas así:

shell> mysql -u root mysql
mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('%','jeffrey','biscuit');
mysql> FLUSH PRIVILEGES;

El resultado es que el valor literal se guarda como contraseña en la tabla , no el valor encriptado. Cuando trate de conectar al servidor usando esta contraseña, el valor se encripta y se compara con el valor guardado en la tabla . Sin embargo, el valor guardado es la cadena de carácteres literal , así que la comparación falla y el servidor rechaza la conexión:

shell> mysql -u jeffrey -pbiscuit test
Access denied

Si inicializa la contraseña usando el comando o mysqladmin password , ambos encriptan la contraseña. En estos casos, el uso de la función no es necesario.

Nota: La encriptación de es diferente a la encriptación de contraseñas Unix. Consulte Sección 5.7.1, “Nombres de usuario y contraseñas de MySQL”.

5.7.6. Guardar una contraseña de forma segura

A nivel administrativo, nunca debería otorgar acceso para la tabla a ninguna cuenta no administrativa.

Cuando ejecuta un programa cliente para conectarse al servidor MySQL, es desaconsejable especificar la clave de manera que sea visible o posible de averiguar para otros usuarios. Los métodos que debe utilizar para especificar su clave cuando ejecuta programas clientes son enumerados aquí, junto con una valoración de los riesgos de cada método:

  • Utilice la opción o en la línea de comandos. Por ejemplo:

    shell> mysql -u francis -pfrank 
    

    Esto es conveniente pero inseguro, porque la clave se vuelve visible para programas de consulta del estado del sistema, como ps que pueden ser invocados por otros usuarios para mostrar líneas de comando. Los clientes de MySQL normalmente sobreescriben el parámetro de la clave en la línea de comandos con ceros durante la secuencia de inicialización, pero aún así hay un breve intervalo de tiempo en que el valor es visible.

  • Utilice la opción o sin especificar ningún valor para la clave. En este caso, el programa cliente solicita la clave desde el terminal:

    shell> mysql -u francis -p 
    Enter password: ********
    

    Los carácteres '' indican donde se introduce la clave. La clave no se muestra mientras se está introduciendo.

    Es más seguro introducir la clave de esta manera que especificarla en la línea de comandos, porque así no es visible a otros usuarios. No obstante, este método es tan solo aplicable para programas que se ejecutan de manera interactiva. Si quiere invocar un programa cliente desde un script que no se ejecute interactivamente, no hay oportunidad de introducir la clave mediante el terminal. En algunos sistemas, incluso podría darse que la primera línea del script sea leida e interpretada (incorrectamente) como la clave.

  • Almacene su clave en un archivo de opciones. Por ejemplo, en Unix puede introducir su clave en la sección del archivo de su directorio personal.

    [client]
    password=your_pass
    

    Si almacena su calve en , el archivo no debería ser accesible para nadie más que usted. Para asegurarse de esto, establezca el modo de acceso del archivo a o . Por ejemplo:

    shell> chmod 600 .my.cnf
    

    Sección 4.3.2, “Usar ficheros de opciones” habla sobre los archivos de opciones con más detalle.

  • Almacene su clave en la variable de entorno . Este método de especificar su clave MySQL debe ser considerado extremadamente inseguro y no debería ser utilizado. Algunas versiones de ps incluyen una opción para mostrar las varialbes de entorno de los procesos en ejecución. Si establece , su clave estará expuesta a cualquier otro usuario que ejecute ps. Aún en sistemas con una versión tal de ps, no es inteligente asumir que no habrá cualquier otro método mediante el cual los usuarios puedan examinar las variables de entorno. Consulte Apéndice E, Variables de entorno.

De todas maneras, la manera más segura de hacerlo es, o bien hacer que el programa cliente pregunte por la clave, o especificarla en un archivo de opciones protegido.

5.7.7. Usar conexiones seguras

MySQL 5.0 incluye soporte para conexiones seguras (cifradas) entre los clientes MySQL y el servidor, utilizando el protocolo SSL (Secure Sockets Layer). Esta sección explica como utilizar conexiones SSL. También explica una manera de configurar SSH en Windows.

La configuración estándard de MySQL tiene la misión de ser tan rápida como sea posible, así que no se usan las conexiones cifradas por defecto. Hacerlo, haría que el protocolo cliente/servidor fuese mucho más lento. Cifrar datos es una operación que requiere un uso intensivo de CPU, y por tanto obliga a la máquina a realizar trabajo adicional que retrasa otras tareas de MySQL. Para aplicaciones que requieran la seguridad que proveen las conexiones cifradas, el trabajo de computación extra está justificado.

MySQL permite que el cifrado sea activado para conexiones individuales. Puede escoger entre una conexión normal sin cifrar, o una segura cifrada mediante SSL dependiendo de los requerimientos de las aplicaciones individuales.

5.7.7.1. Conceptos básicos de SSL

Para entender como MySQL utiliza SSL, es necesario explicar algunos conceptos básicos sobre SSL y X509. Aquellos ya familiarizados con ellos, pueden saltarse esta parte.

Por defecto, MySQL utiliza conexiones sin cifrar entre el cliente y el servidor. Esto significa que cualquiera con acceso a la red podría ver el tráfico y mirar los datos que están siendo enviados o recibidos. Incluso podría cambiar los datos mientras están aún en tránsito entre el cliente y el servidor. Para mejor la seguridad un poco, puede comprimir el tráfico entre el cliente y el servidor utilizando la opción cuando ejecute programas cliente. No obstante, esto parará a un atacante con determinación.

Cuando necesita mover información sobre una red de una manera segura, una conexión sin cifrar es inaceptable. El cifrado es la manera de hacer que cualquier dato sea ilegible. De hecho, hoy en día la prácitca requiere muchos elementos adicionales de seguridad en los algoritmos de cifrado. Deben resistir muchos tipos de ataques conocidos.

El protocolo SSL utiliza diferentes algoritmos de cifrado para asegurarse de que los datos recibidos a través de una red pública son seguros. Tiene mecanismos para detectar cambios de datos, pérdidas, o reenvíos. SSL también incorpora algoritmos que proveen de verificación de identidad, utilizando el estándard X509.

X509 hace posible identificar a alguien en Internet. Es utilizado comúnmente en aplicaciones de comercio electrónico. En resumen, debe haber alguna compañía, llamada ``Autoridad Certificada'' (CA) que asigna certificados electrónicos a cualquiera que los necesita. Los certificados se basan en algoritmos de cifrado asimétricos que tienen dos claves de cifrado (una pública, y otra secreta). El propietario de un certificado puede enseñarselo a otra entidad como prueba de su identidad. Un certificado consiste en la clave pública de su propietario. Cualquier dato cifrado con esta clave pública puede ser solo cifrada utilizando la clave secreta correspondiente, que está en posesión del propietario del certificado.

Si necesita más información sobre SSL, X509, o cifrado, utilice su buscador de Internet favorito para buscar las palabras clave en que esté interesado.

5.7.7.2. Requisitos (OpenSSL)

Para utilizar conexiones SSL entre el servidor MySQL y los programas cliente, su sistema debe tener la capacidad de ejecutar OpenSSL y su versión de MySQL debe ser la 4.0.0 o superior.

Para conseguir que las conexiones seguras funcionen con MySQL, debe hacer lo siguiente:

  1. Instale la librería OpenSSL. MySQL ha sido comprobado con OpenSSL 0.9.6. Si necesita OpenSSL, visite http://www.openssl.org.

  2. Cuando configure MySQL, ejecute el script configure con las opciones y .

  3. Asegúrese de que ha actualizado sus tablas grant para que las columnas relacionadas con SSL de la tabla se hayan agregado. Esto es necesario si las tablas grant provienen de una versión de MySQL anterior a la 4.0.0. El procedimiento de actualización se explica en Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.

  4. Para comprobar si un servidor mysqld que se está ejecutando tiene soporte para OpenSSL, examine el valor de la variable de sistema :

    mysql> SHOW VARIABLES LIKE 'have_openssl';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | have_openssl  | YES   |
    +---------------+-------+
    

    Si el valor es , el servidor tiene soporte para conexiones OpenSSL.

5.7.7.3. Montar certificados SSL para MySQL

Aquí tiene un ejemplo para configurar certificados SSL para MySQL:

DIR=`pwd`/openssl
PRIV=$DIR/private

mkdir $DIR $PRIV $DIR/newcerts
cp /usr/share/ssl/openssl.cnf $DIR
replace ./demoCA $DIR -- $DIR/openssl.cnf

# Create necessary files: $database, $serial and $new_certs_dir
# directory (optional)

touch $DIR/index.txt
echo "01" > $DIR/serial

#
# Generation of Certificate Authority(CA)
#

openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/cacert.pem \
    -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ................++++++
# .........++++++
# writing new private key to '/home/monty/openssl/private/cakey.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL admin
# Email Address []:

#
# Create server request and key
#
openssl req -new -keyout $DIR/server-key.pem -out \
    $DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ..++++++
# ..........++++++
# writing new private key to '/home/monty/openssl/server-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL server
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:

#
# Remove the passphrase from the key (optional)
#

openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem

#
# Sign server cert
#
openssl ca  -policy policy_anything -out $DIR/server-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/server-req.pem

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL admin'
# Certificate is to be certified until Sep 13 14:22:46 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated

#
# Create client request and key
#
openssl req -new -keyout $DIR/client-key.pem -out \
    $DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# .....................................++++++
# .............................................++++++
# writing new private key to '/home/monty/openssl/client-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL user
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:

#
# Remove a passphrase from the key (optional)
#
openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem

#
# Sign client cert
#

openssl ca  -policy policy_anything -out $DIR/client-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/client-req.pem

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL user'
# Certificate is to be certified until Sep 13 16:45:17 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated

#
# Create a my.cnf file that you can use to test the certificates
#

cnf=""
cnf="$cnf [client]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/client-cert.pem"
cnf="$cnf ssl-key=$DIR/client-key.pem"
cnf="$cnf [mysqld]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/server-cert.pem"
cnf="$cnf ssl-key=$DIR/server-key.pem"
echo $cnf | replace " " '
' > $DIR/my.cnf

Para comprobar las conexiones SSL, inicie el servidor de la siguiente manera, donde es la ruta a el directorio donde está el archivo de opciones de ejemplo :

shell> mysqld --defaults-file=$DIR/my.cnf &

Entonces ejecute un programa cliente utilizando el mismo archivo de opciones:

shell> mysql --defaults-file=$DIR/my.cnf

Si tiene una distribución de código fuente de MySQL, usted puede tambier comprobar su configuración modificando el archivo precedente para que se refiera al certificado y los archivos de claves en el directorio de la distribución.

5.7.7.4. Opciones SSL de

MySQL puede comprobar los atributos de un certificado X509 además de la autentificación usual que se basa en nombre de usuario y clave. Para especificar las opciones relacionadas con SSL para una cuenta MySQL, utilice la clausula de la sentencia . Consulte Sección 13.5.1.3, “Sintaxis de y .

Hay diferentes maneras de limitar los tipos de conexión para una cuenta:

  • Si una cuenta no tiene requerimientos de SSL o X509, las conexiones sin cifrar se permiten siempre que el nombre de usuario y la clave sean válidas. De cualquier manera, se pueden también utilizar conexiones cifradas, si el cliente tiene los certificados y archivos de claves apropiados.

  • La opción limita al servidor para que acepte únicamente conexiones cifradas SSL para la cuenta. Tenga en cuenta que esta opción puede pasarse por alto si hay algún registro ACL que permite conexiones no-SSL.

    mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
        -> IDENTIFIED BY 'goodsecret' REQUIRE SSL;
    
  • significa que el cliente debe tener un certificado pero que el certificado exacto, entidad certificadora y sujeto no importan. El único requerimiento es que debería ser posible verificar su firma con uno de los certificados CA.

    mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
        -> IDENTIFIED BY 'goodsecret' REQUIRE X509;
    
  • coloca una restricción en la conexión mediante la cual el cliente debe presentar un certificado X509 válido, emitido por la CA . Si el cliente presenta un certificado que es valido pero tiene un emisor diferente, el servidor rechaza la conexión. La utilización de certificados X509 siempre implica cifrado, así que la opción no es necesaria.

    mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/
           O=MySQL Finland AB/CN=Tonu Samuel/[email protected]';
    

    Nótese que el valor de debe introducirse como una única cadena de carácteres.

  • establece la restricción a los intentos de conexión de que el cliente debe presentar un certificado X509 válido con sujeto . Si el cliente presenta un certificado que, aunque válido, tiene un sujeto diferente, el servidor rechaza la conexión.

    mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
           O=MySQL demo client certificate/
           CN=Tonu Samuel/[email protected]';
    

    Nótese qeu el valor de debe ser introducido como una única cadena de carácteres.

  • es necesario para asegurar que se utilizan longitudes de cifra y claves suficientemente fuertes. El protocolo SSL por sí mismo puede ser débil si se utilizan viejos algorimots con claves de cifrado cortas. Utilizando esta opción, podemos pedir un método exacto de cifrado para permitir una conexión.

    mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
    

Las opciones , , y pueden combinarse en la sentencia de la siguiente manera:

mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
       O=MySQL demo client certificate/
       CN=Tonu Samuel/[email protected]'
    -> AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/
       O=MySQL Finland AB/CN=Tonu Samuel/[email protected]'
    -> AND CIPHER 'EDH-RSA-DES-CBC3-SHA';

Nótese qeu los valores de e deben ser introducidos cada uno como una única cadena de carácteres.

En MySQL 5.0, la palabra clave es opcional entre las opciones de .

El orden de las opciones no importa, pero ninguna opción puede ser especificada dos veces.

5.7.7.5. Opciones relativas a SSL

La siguiente lista explica las opciones que se utilizan para especificar la utilización de SSL, y archivos de certificados y calves. Se pueden introducir en línea de comandos, o mediante un archivo de opciones.

  • Para el servidor, esta opción especifica que el servidor permite conexiones SSL. Para un programa cliente, permite al cliente que se conecte al servidor utilizando SSL. Esta opción no es suficiente por si sola para causar que se utilice una conexión SSL. También se deben especificar las opciones , , y .

    Esta opción se utiliza más frecuentemente en su forma contraria para indicar que SSL no debe utilizarse. Para hacer esto, especifique la opción como o .

    Nótese que el uso de no requiere una conexión SSL. Por ejemplo, si el servidor o el cliente han sido compilados sin soporte para conexiones SSL, se utilizará una conexión normal sin cifrar.

    La manera más confiable de asegurarse de que se utiliza una conexión SSL es crear una cuenta en el servidor que incluya la clausula en la sentencia . Then use this account to connect to the server, with both a server and client that have SSL support enabled.

  • La ruta a un archivo con una lista de CAs SSL en las que se confía.

  • La ruta a un direcotrio que contiene certificados de CA confiables en formato pem.

  • El nombre del archivo de certificado SSL a utilizar para establecer una conexión segura.

  • Una lista de cifras permisibles para usar en el cifrado SSL. tiene el mismo formato que el comando .

    Ejemplo:

  • El nombre del archivo de clave SSL utilizado para establecer una conexión segura.

5.7.7.6. Conectarse desde Windows a MySQL remotamente con SSH

Aquí hay una nota sobre como conectar para obtener una conexión segura a un servidor MySQL remoto mediante SSH (por David Carlson ):

  1. Instale un cliente SSH en su máquina Windows. Como usuario, el mejor cliente no-libre que he encontrado es el de http://www.vandyke.com/. Otra opción es de http://www.f-secure.com/. También puede encontrar algunos libres mediante en http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/.

  2. Ejecute su cliente SSH Windows. Establezca . Establezca para entrar al servidor. Este nombre de usuario podría no ser el mismo que el de su cuenta MySQL.

  3. Establezca la redirección de puertos. Ya sea una redirección remota (Estableciendo , , ) o una redirección local (Estableciendo , , ).

  4. Guarde todo, si no es así, tendrá que rehacerlo la próxima vez.

  5. Entre en su servidor con la sesión SSH que acaba de crear.

  6. En su máquina Windows, ejecute alguna aplicación ODBC (como Access).

  7. Cree un nuevo archivo en Windows y enlácelo a MySQL utilizando el driver ODBC de la misma manera que lo haría normalmente, excepto que debe escribir para el nombre de servidor MySQL, no .

Debería tener una conexión ODBC a MySQL, cifrada utilizando SSH.