Auditar inicios de sesión en la base de datos MySQL

11

¿Hay alguna forma de auditar los inicios de sesión en MySQL? Me gustaría poder crear un nombre de usuario para cada empleado y así crear una pista de auditoría de inicios de sesión. Sin embargo, googlear no ha dado buenos resultados.

Cuanto más podamos auditar, mejor. Por lo menos, sería bueno saber quién inició sesión y cuándo. Sería aún mejor ver quién ejecutó qué consulta cuando. Los registros están allí principalmente para decirles a los clientes que los tenemos, ya que hay información potencialmente confidencial en la base de datos.

Obviamente, poder auditar las consultas ejecutadas por cada usuario (y cuándo) también nos daría la capacidad de identificar mejor quién es la causa de un problema de seguridad si surgiera uno.

statichippo
fuente
1
¿Qué es exactamente lo que estás buscando auditar? Supongo que quiere decir que usará los nombres de usuario de MySQL, no los nombres de usuario del sistema. ¿Cómo piensa utilizar los datos de auditoría más tarde? (Lo que significa qué detalles son importantes aquí, sería suficiente el registro del sistema en lugar del registro de MySQL). Cuanta más información pueda proporcionar en su pregunta, más exactamente podemos darle una respuesta y arrancar rápidamente. Me imagino que quiere una respuesta mejor que "hacer que su aplicación haga una llamada específica de sproc antes de la operación de cada uno" ~ En resumen, ¿qué detalles necesitaría de mí si le estuviera preguntando esto?
jcolebrand

Respuestas:

6

Probablemente desee utilizar el registro de consultas generales .

El registro de consultas generales es un registro general de lo que está haciendo mysqld. El servidor escribe información en este registro cuando los clientes se conectan o desconectan, y registra cada instrucción SQL recibida de los clientes.

Una cosa importante con el registro de seguridad es que un atacante no puede acceder al registro para borrar rastros de su presencia, por lo tanto, considere agregar archivos solo para agregar .

FWIW en Oracle podemos enviar registros automáticamente a un syslog remoto , pero no creo que MySQL tenga esta característica todavía. Quizás puedas fingirlo con SNMP, pero no lo he probado.

Gayo
fuente
Genial, aprende algo nuevo todos los días :-)
Gaius
5

La respuesta de @Gauis es excelente. Para agregarle más, puede hacer lo siguiente:

MySQL 5.1 ahora permite almacenar el registro general y el registro de consultas lentas como tablas SQL.

Agregue esto a /etc/my.cnf:

[mysqld]
log-output=TABLE
log

Reiniciar mysql

Luego, cuando mysqld crea el registro general, en lugar de un archivo de texto, creará la tabla como una tabla CSV en la carpeta / var / lib / mysql / mysql (base de datos de esquema mysql).

Solo haz esto para verlo:

SHOW CREATE TABLE mysql.general_log\G

Todas las conexiones se acumularán en él.

Para usted, eso no es muy útil cuando se trata de consultarlo. Solo sería un escaneo completo de la tabla cada vez.

Qué hacer ??? ¡CONVIÉTALO A MyISAM e INDICE LA TABLA !!!!

SET @old_log_state = @@global.general_log;
SET GLOBAL general_log = 'OFF';
ALTER TABLE mysql.general_log ENGINE = MyISAM;
ALTER TABLE mysql.general_log ADD INDEX (event_time);
SET GLOBAL general_log = @old_log_state;

Opcionalmente, es posible que desee poner un índice de texto completo en el campo de argumento.

Acabo de configurar MySQL 5.5.9 en un servidor y probé esto. Aquí está el resultado:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.9-log MySQL Community Server (GPL)

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

iml-db10:3306 (DB (none)) :: show create table mysql.general_log\G
*************************** 1. row ***************************
       Table: general_log
Create Table: CREATE TABLE `general_log` (
  `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `user_host` mediumtext NOT NULL,
  `thread_id` int(11) NOT NULL,
  `server_id` int(10) unsigned NOT NULL,
  `command_type` varchar(64) NOT NULL,
  `argument` mediumtext NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'
1 row in set (0.01 sec)

iml-db10:3306 (DB (none)) :: SET @old_log_state = @@global.general_log;
Query OK, 0 rows affected (0.00 sec)

iml-db10:3306 (DB (none)) :: SET GLOBAL general_log = 'OFF';
Query OK, 0 rows affected (0.00 sec)

iml-db10:3306 (DB (none)) :: ALTER TABLE mysql.general_log ENGINE = MyISAM;
Query OK, 9 rows affected (0.02 sec)
Records: 9  Duplicates: 0  Warnings: 0

iml-db10:3306 (DB (none)) :: ALTER TABLE mysql.general_log ADD INDEX (event_time);
Query OK, 9 rows affected (0.00 sec)
Records: 9  Duplicates: 0  Warnings: 0

iml-db10:3306 (DB (none)) :: SET GLOBAL slow_query_log = @old_log_state;
Query OK, 0 rows affected (0.00 sec)

iml-db10:3306 (DB (none)) :: select * from mysql.general_log;
+---------------------+-----------------------------+-----------+-----------+--------------+-------------------------------------------+
| event_time          | user_host                   | thread_id | server_id | command_type | argument                                  |
+---------------------+-----------------------------+-----------+-----------+--------------+-------------------------------------------+
| 2011-02-24 14:42:18 | [lwdba] @  [127.0.0.1]      |         3 | 106451130 | Connect      | lwdba@127.0.0.1 on                        |
| 2011-02-24 14:42:18 | lwdba[lwdba] @  [127.0.0.1] |         3 | 106451130 | Query        | select @@version_comment limit 1          |
| 2011-02-24 14:42:18 | lwdba[lwdba] @  [127.0.0.1] |         3 | 106451130 | Query        | SHOW VARIABLES LIKE 'hostname'            |
| 2011-02-24 14:42:18 | lwdba[lwdba] @  [127.0.0.1] |         3 | 106451130 | Quit         |                                           |
| 2011-02-24 14:42:18 | [lwdba] @  [127.0.0.1]      |         4 | 106451130 | Connect      | lwdba@127.0.0.1 on                        |
| 2011-02-24 14:42:18 | lwdba[lwdba] @  [127.0.0.1] |         4 | 106451130 | Query        | select @@version_comment limit 1          |
| 2011-02-24 14:42:30 | lwdba[lwdba] @  [127.0.0.1] |         4 | 106451130 | Query        | show create table mysql.general_log       |
| 2011-02-24 14:43:54 | lwdba[lwdba] @  [127.0.0.1] |         4 | 106451130 | Query        | SET @old_log_state = @@global.general_log |
| 2011-02-24 14:44:00 | lwdba[lwdba] @  [127.0.0.1] |         4 | 106451130 | Query        | SET GLOBAL general_log = 'OFF'            |
+---------------------+-----------------------------+-----------+-----------+--------------+-------------------------------------------+
9 rows in set (0.00 sec)

iml-db10:3306 (DB (none)) :: show create table mysql.general_log\G
*************************** 1. row ***************************
       Table: general_log
Create Table: CREATE TABLE `general_log` (
  `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `user_host` mediumtext NOT NULL,
  `thread_id` int(11) NOT NULL,
  `server_id` int(10) unsigned NOT NULL,
  `command_type` varchar(64) NOT NULL,
  `argument` mediumtext NOT NULL,
  KEY `event_time` (`event_time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='General log'
1 row in set (0.00 sec)

Ahora, puede consultar por marca de tiempo y buscar tokens específicos en el campo de argumento.

Por ejemplo, observe la línea 4 de SELECT que hice. Mi inicio de sesión se registró en el campo de argumento como[email protected] on . Puedes rastrear estos.

¿Qué pasa si el general se hace demasiado grande (Créeme, se hará demasiado grande muy rápido)

Qué hacer ???

  1. apagado mysql
  2. mueva general_log.frm, general_log.MYD y general_log.MYI a un soporte de disco diferente (y mucho más grande).
  3. Cree tres enlaces simbólicos a general_log.frm, general_log.MYD y general_log.MYI desde / var / lib / mysql / mysql
  4. chown mysql: mysql general_log.frm general_log.MYD general_log.MYI en el nuevo soporte de disco
  5. chown mysql: mysql general_log.frm general_log.MYD general_log.MYI enlaces simbólicos en / var / lib / mysql / mysql
  6. iniciar mysql copia de seguridad

Por cierto, una vez que haya desconectado el registro general, puede ejecutarlos para recopilar los inicios de sesión distintos que hicieron algo en mysqld:

SET SQL_LOG_BIN=0;
use mysql
DROP TABLE IF EXISTS audit_user_host;
CREATE TABLE audit_user_host
(
    user_host VARCHAR(32),
    PRIMARY KEY (user_host)
) ENGINE=MyISAM;
SHOW CREATE TABLE audit_user_host\G
INSERT IGNORE INTO mysql.audit_user_host SELECT user_host FROM mysql.general_log;
SELECT COUNT(1) FROM mysql.audit_user_host;

Tengo un cliente con 3 servidores de base de datos. Cada uno con DB Server tiene más de 1,000,000,000 (1 billón [miles de millones]) de líneas. El guión anterior tardó aproximadamente 2.5 horas en completarse. La tabla audit_user_host terminó con 27 inicios de sesión distintos.

Usted debe ser bueno para ir.

Diviértete con este, todos !!!

RolandoMySQLDBA
fuente
¡Gran articulo! Solo compartiendo mis pruebas. Intenté cambiar el nombre de la tabla mysql.general_log y particionar la tabla para purgarla, pero no inicie sesión en la tabla. Entonces lo cambio de nuevo a la tabla MyIsam no particionada. ¡Gracias!
1

En lugar de hacer tantas cosas manualmente, solo instale el complemento de Auditoría que brinda más información a nivel de usuario

http://www.mysql.com/products/enterprise/audit.html

Sin embargo, está disponible en ediciones comerciales seleccionadas de MySQL. Hubiera sido excelente si alguna bifurcación de MySQL agregara en la edición comunitaria también para que la mayoría de las personas se beneficien de esta característica, de lo contrario, tenemos que confiar en la solución provista por @RolandoMySQLDBA.

Mahesh Patil
fuente
0

@statichippo
Cómo instalar el registro de auditoría en MySQL.
+ El registro de auditoría solo es compatible con MySQL Enterprise
+ Puede instalar el registro de auditoría en la Comunidad MySQL:
1. Copie el archivo audit_log.so por Puede instalar MySQL Enterprise Trial, luego copie el archivo audit_log.so en la Comunidad MySQL.
2. Copie audit_log.so a plugin_dir como / usr / lib64 / mysql / plugin o puede mostrar el directorio de complementos de la siguiente manera:
Vaya a la consola de mysql: mysql> muestre variables globales como '% plugin%';
3. Instale el registro de auditoría como:
mysql> INSTALL PLUGIN audit_log SONAME 'audit_log.so';
mysql> MOSTRAR VARIABLES COMO 'audit_log%';
4. Registro de auditoría de salida:
Registro de tail -f /var/lib/mysql/audit.log

Muchas gracias.

Binh Nguyen
fuente