Аудит входов в базу данных MySQL


11

Есть ли способ аудита входов в MySQL? Я хотел бы иметь возможность создать имя пользователя для каждого сотрудника и, таким образом, создать журнал аудита для входа. Однако поиск в Google не принес хороших результатов.

Чем больше мы можем провести аудит, тем лучше. По крайней мере, было бы неплохо узнать, кто вошел в систему, когда. Было бы еще лучше увидеть, кто и когда выполнил какой запрос. Журналы в основном предназначены для того, чтобы сообщить клиентам, что они у нас есть, поскольку в базе данных содержится потенциально конфиденциальная информация.

Очевидно, что возможность аудита запросов, выполняемых каждым пользователем (и когда), также даст нам возможность лучше определить, кто является причиной проблемы безопасности, если она возникнет.


1
Что именно вы ищете для аудита? Я полагаю, вы имеете в виду, что вы будете использовать имена пользователей MySQL, а не системные имена пользователей? Как вы собираетесь использовать данные аудита позже (имея в виду, какие детали здесь важны, будет ли системное ведение журнала достаточным, а не ведение журнала MySQL). Чем больше информации вы можете предоставить в своем вопросе, тем точнее мы сможем дать вам ответ и быстро загрузиться. Я полагаю, что вы хотите получить лучший ответ, чем "ваше приложение должно вызывать определенный вызов sproc перед каждой другой операцией". Короче, какие подробности вам понадобятся от меня, если я задам этот вопрос?
Jcolebrand

Ответы:


6

Возможно, вы захотите использовать общий журнал запросов .

Общий журнал запросов - это общая запись того, что делает mysqld. Сервер записывает информацию в этот журнал, когда клиенты подключаются или отключаются, и регистрирует каждый оператор SQL, полученный от клиентов.

Одна важная вещь при ведении журнала для безопасности - то, что злоумышленник не может получить доступ к журналу, чтобы стереть следы своего присутствия, поэтому рассмотрите файлы только для добавления .

В Oracle мы можем автоматически отправлять журналы в удаленный системный журнал , но я не верю, что MySQL пока имеет эту функцию. Возможно, вы могли бы подделать его с SNMP, но я не пробовал.



О, круто, узнай что-то новое каждый день :-)
Гай

5

Ответ @Gauis превосходен. Чтобы добавить к этому дальше, вы можете следующее:

MySQL 5.1 теперь позволяет хранить общий журнал и журнал медленных запросов в виде таблиц SQL.

Добавьте это в /etc/my.cnf:

[mysqld]
log-output=TABLE
log

Перезапустите MySQL

Затем, когда mysqld создает общий журнал, вместо текстового файла он создает таблицу в виде таблицы CSV в папке / var / lib / mysql / mysql (база данных схемы mysql).

Просто сделайте это, чтобы увидеть это:

SHOW CREATE TABLE mysql.general_log\G

Все соединения будут накапливаться в нем.

Для вас это не очень полезно, когда речь заходит об этом. Это будет просто полное сканирование таблицы каждый раз.

Что делать ??? Преобразуйте это в MyISAM и УКАЗАТЬ СТОЛ !!!!

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;

При желании вы можете поместить полнотекстовый индекс в поле аргумента.

Я только что установил MySQL 5.5.9 на сервере и попробовал это. Вот результат:

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)

Теперь вы можете выполнять запрос по метке времени и искать специальные токены в поле аргумента.

Например, обратите внимание на строку 4 SELECT, которую я сделал. Мой вход был записан в поле аргумента как lwdba@127.0.0.1 on. Вы можете отслеживать это.

Что делать, если генерал становится слишком большим (поверьте мне, он станет слишком большим очень быстро)

Что делать ???

  1. отключение mysql
  2. переместите general_log.frm, general_log.MYD и general_log.MYI на другое (и, надеюсь, больше) монтирование диска.
  3. Создайте три символические ссылки на general_log.frm, general_log.MYD и general_log.MYI из / var / lib / mysql / mysql
  4. chown mysql: mysql general_log.frm general_log.MYD general_log.MYI на новом монтировании диска
  5. chown mysql: mysql general_log.frm general_log.MYD general_log.MYI символические ссылки в / var / lib / mysql / mysql
  6. начать MySQL резервное копирование

Кстати, как только вы перевели общий журнал в автономный режим, вы можете запустить его, чтобы собрать отличительные логины, которые что-то сделали в 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;

У меня есть клиент с 3-мя серверами БД. Каждый из них с DB Server содержит более 1 000 000 000 (1 миллиардов [тысяч миллионов]) строк. Сценарий, описанный выше, занял около 2,5 часов. Таблица aud_user_host закончилась 27 различными входами в систему.

Тебе должно быть хорошо идти.

Веселитесь с этим, все!


Отличная статья! Просто делюсь своим тестированием. Я попытался переименовать таблицу mysql.general_log и разбить ее на части для очистки, но не войду в нее. Поэтому я переключаю его обратно на однораздельную таблицу MyIsam. Спасибо!

1

Вместо того, чтобы делать так много вещей вручную, просто установите плагин Audit, который дает более глубокое понимание на уровне пользователя

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

Однако он доступен в некоторых коммерческих выпусках MySQL. Было бы замечательно, если бы любой MySQL ветвь добавлялся и в общедоступную версию, чтобы большинство людей получало выгоду от этой функции, в противном случае мы должны полагаться на решение, предоставленное @RolandoMySQLDBA.


0

@statichippo
Как установить ведение журнала аудита на MySQL.
+ Ведение журнала аудита поддерживает только MySQL Enterprise
+ Вы можете установить ведение журнала аудита в MySQL Community:
1. Скопируйте файл audit_log.so, установив MySQL Enterprise Trial, а затем скопируйте файл audit_log.so в MySQL Community.
2. Скопируйте audit_log.so в plugin_dir как / usr / lib64 / mysql / plugin или вы можете показать каталог плагина следующим образом:
Перейдите в консоль mysql: mysql> покажите глобальные переменные, такие как «% plugin%»;
3. Установите ведение журнала аудита как:
mysql> INSTALL PLUGIN audit_log SONAME 'audit_log.so';
mysql> ПОКАЗАТЬ ПЕРЕМЕННЫЕ НРАВИТСЯ 'audit_log%';
4. Выходной журнал аудита:
tail -f /var/lib/mysql/audit.log

Огромное спасибо.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.