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


11

Чи є спосіб перевірити вхід до MySQL? Я хотів би мати можливість створити ім’я користувача для кожного співробітника і тим самим створити аудиторський слід входу. Однак Google не виявив хороших результатів.

Чим більше ми можемо перевірити, тим краще. Як мінімум, було б непогано знати, хто коли входив. Ще краще було б побачити, хто виконав який запит, коли. Журнали існують здебільшого, щоб повідомити клієнтам, що ми їх маємо, оскільки в базі даних є потенційно чутлива інформація.

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


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

Відповіді:


6

Ймовірно, ви хочете використовувати загальний журнал запитів .

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

Однією з важливих речей при реєстрації даних для безпеки є те, що зловмисник не може отримати доступ до журналу, щоб стерти сліди своєї присутності, тому врахуйте файли, що додаються лише для додавання .

FWIW в Oracle ми можемо автоматично надсилати журнали у віддалений syslog , але я не вірю, що 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

Усі з'єднання будуть накопичуватися в ньому.

Для вас це не дуже корисно, коли мова йде про його запит. Це було б просто сканування повного столу кожного разу.

Що робити ??? ПОВЕРНУЙТЕ ЇЇ МІЙСАМУ І ВКАЖИТИ СТОЛИ !!!!

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 I. Мій вхід був записаний у полі аргументу як 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

BTW Після того, як загальний журнал буде знято в автономному режимі, ви можете запустити їх, щоб зібрати різні входи, які зробили щось у 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 серверами БД. Eeach з DB Server має в ньому понад 1 000 000 000 (1 мільярд [тисяч мільйонів]) ліній. Виконання сценарію зайняло близько 2,5 годин. Таблиця audit_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 або ви можете показати плагін dir:
Перейдіть до консолі mysql: mysql> покажіть глобальні змінні, такі як '% plugin%';
3. Встановити журнал аудиту як:
mysql> ВСТАНОВИТИ ПЛУГІН audit_log SONAME 'audit_log.so';
mysql> SHOW VARIABLES LIKE 'audit_log%';
4. Журнал виводу аудиту:
tail -f /var/lib/mysql/audit.log

Дуже дякую.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.