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

11

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

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

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

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

Ответы:

6

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

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

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

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

Gaius
источник
О, круто, узнай что-то новое каждый день :-)
Гай
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 различными входами в систему.

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

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

RolandoMySQLDBA
источник
Отличная статья! Просто делюсь своим тестированием. Я попытался переименовать таблицу 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

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

Бинь Нгуен
источник