Аудит MySQL с помощью различных плагинов

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

Зачем вообще проводить аудит ваших баз данных?

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

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

Какие плагины аудита доступны для MySQL?

Начиная с версии 5.5.3 в MySQL стало доступно Audit Plugin API, которое можно использовать для создания плагинов аудита. Данное API предоставляет следующие события:

  • сообщения, записанные в общий журнал (GENERAL LOG);
  • сообщения, записанные в журнал ошибок (ERROR LOG);
  • результаты запроса, отправленные клиенту (RESULT);
  • события подключения (включая сбойные) и отключения (CONNECT);

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

    Перечислим основные доступные на текущий момент плагины аудита для MySQL:

  • MySQL Enterprise Audit Plugin — данный плагин разработан компанией Oracle и является самым стабильным и надежным. Он предоставляет обширные функции аудита: мощные механизмы фильтрации событий, ведение лога в формате JSON, компрессия и шифрование данных, динамическое изменение конфигурации без перезагрузки БД, интеграция с другими продуктами Oracle, вывод информации в формате для аудита в соответствии со стандартами PCI, HIPAA, FERPA, SOX и т.д. Единственное, но заключается в том, что плагин платный и является частью Oracle MySQL Enterprise;
  • Percona Audit Log Plugin — плагин аудита от компании Percona, плагин абсолютно бесплатный и имеет открытый исходный код. Поставляется вместе с Percona Server for MySQL 5.5 и выше. Плагин позволяет вести логи в формате XML (OLD, NEW), JSON, CSV, а так же отправлять логи на syslog-сервер. В плагине можно гибко настроить ведение логов по определенным группам команд (с версии 5.7.14-7) (например: set_option, create_db, drop_db), ведение логов только по определенным пользователям или наоборот исключить из лога определенные группы команд и определенных пользователей, так же плагин поддерживает ротацию логов. Плагин идет в составе Percona Server for MySQL и не подразумевает использование с другими клонами MySQL т.к. использует некоторые доработки в MySQL от Percona. Более подробно о настройке плагина можно почитать в документации, а так же в полезной статье о практике его применения;
  • McAfee MySQL Audit Plugin — плагин аудита от компании McAfee, плагин абсолютно бесплатный и имеет открытый исходный код. Плагин довольно популярный, был создан в 2012 году, его работа проверена на Oracle MySQL, Percona Server for MySQL и MariaDB. К сожалению плагин не поддерживает работу через Audit Plugin API, а читает информацию об операциях из блоков памяти, что ставит его в зависимость от конкретной версии MySQL. В последнее время в данном плагине не добавляется новый функционал, хотя поддержка новых версий Oracle MySQL, Percona Server for MySQL и MariaDB в нем присутствует и этот функционал поддерживается в актуальном состоянии. Для установки необходимо скачать нужную версию плагина под конкретную версию MySQL (Oracle, Percona, MariaDB). Плагин позволяет вести логи в формате JSON, так же в плагине есть фильтры по типам команд (например: CONNECT,QUERY,TABLE), фильтры по конкретным командам (например: insert,update,delete), так же есть фильтры по пользователям и объектам (например можно логировать обращения только к определенным БД или таблицам), плагин позволяет маскировать пароли указанные в таких командах как CREATE USER, GRANT и других командах чтобы они не попадали в лог аудита, что положительно сказывается на безопасности. Так же стоит отметить, что плагин позволяет создавать unix-сокет через который программа-приемник логов может получать информацию от плагина при этом данные не будет оседать на диске, что очень актуально при больших нагрузках на БД когда число логируемых операций может достигать нескольких тысяч в секунду. Более подробную информацию по установке плагина и его настройке Вы можете найти на страничке Wiki.
  • MariaDB Audit Plugin — плагин аудита от компании MariaDB. Данный плагин так же абсолютно бесплатный и имеет открытый исходный код, поставляется в составе MariaDB, а так же поддерживает работу через Audit Plugin API, что выгодно отличает его от McAfee MySQL Audit Plugin. Плагин позволяет вести логи в текстовом формате, так же в плагине есть возможность ротации логов и отправки логов на syslog-сервер. В плагине есть фильтры по типам команд (например: CONNECT,QUERY,QUERY_DDL,QUERY_DML), а так же есть фильтры по пользователям (можно указать для каких пользователей будем логировать события или наоборот, каких пользователей исключить). Плагин MariaDB Audit Plugin можно использовать не только с БД MariaDB, но и с Percona Server for MySQL и Oracle MySQL.

    Выбор конкретного плагина будет зависеть от того какой версией MySQL и от какого производителя (Oracle, Percona или MariaDB) Вы пользуетесь. Т.к. у меня используется MariaDB, то в первую очередь мой выбор пал на MariaDB Audit Plugin, т.к. он идет в составе MariaDB.

    Итак,
    Исходные данные: ОС Debian 9.4 (Stretch), MariaDB 10.2.13;
    Задача: Установить MariaDB Audit Plugin с минимум телодвижений и произвести базовую настройку плагина;

    1. Проверка наличия плагина:

    Первым делом выясним где у нас находится каталог с плагинами:

    # mysql -u root -p mysql
    MariaDB [mysql]> SHOW GLOBAL VARIABLES LIKE 'plugin_dir';
    +---------------+------------------------+
    | Variable_name | Value                  |
    +---------------+------------------------+
    | plugin_dir    | /usr/lib/mysql/plugin/ |
    +---------------+------------------------+
    1 row in set (0.00 sec)
    

    Проверим наличие нужного плагина:

    # ls -l /usr/lib/mysql/plugin | grep server_audit
    -rw-r--r-- 1 root root   59480 Feb 12 20:02 server_audit.so
    

    Отлично, плагин есть.

    2. Установка плагина:

    Плагины можно устанавливать 2 способами:
    1) При работающем сервере без его перезапуска с помощью команды INSTALL PLUGIN
    2) При запуске mysql с помощью указания опции plugin_load= в секции [mysqld] файла my.cnf

    Я воспользуюсь первым способом установки:

    # mysql -u root -p mysql
    MariaDB [mysql]> install plugin server_audit soname 'server_audit.so';
    

    Проверим список установленных плагинов:

    MariaDB [mysql]> show plugins;
    +-------------------------------+----------+--------------------+--------------------+---------+
    | Name                          | Status   | Type               | Library            | License |
    +-------------------------------+----------+--------------------+--------------------+---------+
    | binlog                        | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
    ......
    | SERVER_AUDIT                  | ACTIVE   | AUDIT              | server_audit.so    | GPL     |
    +-------------------------------+----------+--------------------+--------------------+---------+
    

    И посмотрим полную информацию о плагине:

    MariaDB [mysql]> select * from information_schema.plugins where plugin_name='SERVER_AUDIT'\G;
    *************************** 1. row ***************************
               PLUGIN_NAME: SERVER_AUDIT
            PLUGIN_VERSION: 1.4
             PLUGIN_STATUS: ACTIVE
               PLUGIN_TYPE: AUDIT
       PLUGIN_TYPE_VERSION: 3.2
            PLUGIN_LIBRARY: server_audit.so
    PLUGIN_LIBRARY_VERSION: 1.13
             PLUGIN_AUTHOR: Alexey Botchkov (MariaDB Corporation)
        PLUGIN_DESCRIPTION: Audit the server activity
            PLUGIN_LICENSE: GPL
               LOAD_OPTION: FORCE_PLUS_PERMANENT
           PLUGIN_MATURITY: Stable
       PLUGIN_AUTH_VERSION: 1.4.3
    1 row in set (0.00 sec)
    

    Плагин установлен. При перезапуске MariaDB плагин будет загружен автоматически, поэтому в my.cnf добавлять ничего не нужно, но если способ с установки помощью команды INSTALL PLUGIN Вам не подходит, то Вы можете прописать в секции [mysqld] файла my.cnf строку:

    plugin-load=server_audit=server_audit.so
    

    И тогда при перезапуске mysqld плагин будет загружен и готов к использованию.

    Для того, чтобы защитить плагин от возможности его выгрузки (UNINSTALL PLUGIN) необходимо прописать в секции [mysqld] файла my.cnf строку:

    server_audit=FORCE_PLUS_PERMANENT
    

    И перезапустить mysqld:

    /etc/init.d/mysql restart
    

    Теперь выгрузить плагин не получиться:

    MariaDB [mysql]> UNINSTALL PLUGIN server_audit;
    ERROR 1702 (HY000): Plugin 'server_audit' is force_plus_permanent and can not be unloaded
    

    3. Настройка плагина:

    Посмотрим список доступных настроек:

    MariaDB [mysql]> show global variables like 'server_audit%';
    +-------------------------------+-----------------------+
    | Variable_name                 | Value                 |
    +-------------------------------+-----------------------+
    | server_audit_events           |                       |
    | server_audit_excl_users       |                       |
    | server_audit_file_path        | server_audit.log      |
    | server_audit_file_rotate_now  | OFF                   |
    | server_audit_file_rotate_size | 1000000               |
    | server_audit_file_rotations   | 9                     |
    | server_audit_incl_users       |                       |
    | server_audit_logging          | OFF                   |
    | server_audit_mode             | 0                     |
    | server_audit_output_type      | file                  |
    | server_audit_query_log_limit  | 1024                  |
    | server_audit_syslog_facility  | LOG_USER              |
    | server_audit_syslog_ident     | mysql-server_auditing |
    | server_audit_syslog_info      |                       |
    | server_audit_syslog_priority  | LOG_INFO              |
    +-------------------------------+-----------------------+
    15 rows in set (0.00 sec)
    

    По умолчанию плагин находится в отключенном состоянии, об этом нам говорит строка server_audit_logging = OFF

    Включим его и проверим:

    MariaDB [mysql]> set global server_audit_logging=on;
    Query OK, 0 rows affected (0.00 sec)
    
    MariaDB [mysql]> show global variables like 'server_audit_logging%';
    +----------------------+-------+
    | Variable_name        | Value |
    +----------------------+-------+
    | server_audit_logging | ON    |
    +----------------------+-------+
    1 row in set (0.00 sec)
    

    Плагин начал вести аудит, каталог для хранения лога аудита определяется настройкой server_audit_file_path и по умолчанию лог лежит в каталоге определенном в директиве datadir, посмотрим и проверим это:

    MariaDB [mysql]> show global variables like 'datadir';
    +---------------+-----------------+
    | Variable_name | Value           |
    +---------------+-----------------+
    | datadir       | /var/lib/mysql/ |
    +---------------+-----------------+
    1 row in set (0.00 sec)
    

    Проверим каталог /var/lib/mysql

    # ls -la /var/lib/mysql | grep server_audit.log
    -rw-rw----  1 mysql mysql     9943 Mar 20 18:02 server_audit.log
    

    Файл присутствует и в него уже начали идти данные.

    Теперь давайте проведем настройку некоторых параметров:

    MariaDB [mysql]> set global server_audit_events='CONNECT,QUERY,QUERY_DDL';
    Query OK, 0 rows affected (0.00 sec)
    

    Данной настройкой мы определили для каких типов событий мы будем вести аудит.

    Следующей настройкой мы исключим из аудита все действия пользователя root:

    MariaDB [mysql]> set global server_audit_excl_users='root';
    Query OK, 0 rows affected (0.00 sec)
    

    Проверим все установленные параметры плагина:

    MariaDB [mysql]> show global variables like 'server_audit_%';
    +-------------------------------+-------------------------+
    | Variable_name                 | Value                   |
    +-------------------------------+-------------------------+
    | server_audit_events           | CONNECT,QUERY,QUERY_DDL |
    | server_audit_excl_users       | root                    |
    | server_audit_file_path        | server_audit.log        |
    | server_audit_file_rotate_now  | OFF                     |
    | server_audit_file_rotate_size | 1000000                 |
    | server_audit_file_rotations   | 9                       |
    | server_audit_incl_users       |                         |
    | server_audit_logging          | ON                      |
    | server_audit_mode             | 0                       |
    | server_audit_output_type      | file                    |
    | server_audit_query_log_limit  | 1024                    |
    | server_audit_syslog_facility  | LOG_USER                |
    | server_audit_syslog_ident     | mysql-server_auditing   |
    | server_audit_syslog_info      |                         |
    | server_audit_syslog_priority  | LOG_INFO                |
    +-------------------------------+-------------------------+
    15 rows in set (0.00 sec)
    

    Следующим обязательным шагом необходимо прописать все наши настройки плагина в секцию [mysqld] файла my.cnf, чтобы при перезапуске mysqld наши настройки не потерялись:

    # vi /etc/mysql/my.cnf
    
    server_audit_logging=ON
    server_audit_events='CONNECT,QUERY,QUERY_DDL'
    server_audit_excl_users='root'
    server_audit=FORCE_PLUS_PERMANENT
    

    4. Проверка работы плагина:

    Теперь давайте проверим работу плагина на реальных запросах к БД, для этого очистим лог аудита server_audit.log, далее создадим пользователя audit, создадим отдельную БД audit_test, создадим простую таблицу и выполним ряд запросов по вставке, обновлению, удалению и выборке данных, после этого посмотрим лог аудита:

    # echo>/var/lib/mysql/server_audit.log
    # mysql -u root -p mysql
    
    MariaDB [mysql]> CREATE DATABASE audit_test;
    Query OK, 1 row affected (0.31 sec)
    
    MariaDB [mysql]> CREATE USER 'audit'@'localhost' IDENTIFIED BY 'auditpwd';
    Query OK, 0 rows affected (0.00 sec)
    
    MariaDB [mysql]> GRANT ALL PRIVILEGES ON audit_test.* TO 'audit'@'localhost';
    Query OK, 0 rows affected (0.00 sec)
    
    MariaDB [mysql]> exit
    Bye
    
    # mysql -u audit -pauditpwd audit_test
    
    MariaDB [audit_test]>
    CREATE TABLE `users` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` CHAR(30) NOT NULL,
    `age` SMALLINT(6) NOT NULL,
    PRIMARY KEY(`id`)
    );
    Query OK, 0 rows affected (0.30 sec)
    
    MariaDB [audit_test]> INSERT INTO users (name,age) VALUES ('Vasua', 12),('Katya', 18),('Misha', 16),('Sasha', 20);
    Query OK, 4 rows affected (0.30 sec)
    Records: 4  Duplicates: 0  Warnings: 0
    
    MariaDB [audit_test]> SELECT name,age FROM users WHERE age<18;
    +-------+-----+
    | name  | age |
    +-------+-----+
    | Vasua |  12 |
    | Misha |  16 |
    +-------+-----+
    2 rows in set (0.00 sec)
    
    MariaDB [audit_test]> DELETE FROM users WHERE name='Vasua';
    Query OK, 1 row affected (0.30 sec)
    
    MariaDB [audit_test]> UPDATE users SET age=17 WHERE name='Misha';
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    MariaDB [audit_test]> SELECT name,age FROM users WHERE age<18;
    +-------+-----+
    | name  | age |
    +-------+-----+
    | Misha |  17 |
    +-------+-----+
    1 row in set (0.00 sec)
    
    MariaDB [audit_test]> DROP TABLE users;
    Query OK, 0 rows affected (0.27 sec)
    
    MariaDB [mysql]> exit
    Bye
    

    Мы выполнили все операции, проверим лог аудита:

    # cat /var/lib/mysql/server_audit.log
    
    20180321 12:39:48,mariadb,root,localhost,16,0,CONNECT,mysql,,0
    20180321 12:41:14,mariadb,root,localhost,16,0,DISCONNECT,mysql,,0
    20180321 12:41:22,mariadb,audit,localhost,17,0,CONNECT,audit_test,,0
    20180321 12:41:22,mariadb,audit,localhost,17,239,QUERY,audit_test,'show databases',0
    20180321 12:41:22,mariadb,audit,localhost,17,240,QUERY,audit_test,'show tables',0
    20180321 12:41:22,mariadb,audit,localhost,17,241,QUERY,audit_test,'select @@version_comment limit 1',0
    20180321 12:41:39,mariadb,audit,localhost,17,242,QUERY,audit_test,'CREATE TABLE `users` (\n`id` INT(11) NOT NULL AUTO_INCREMENT,\n`name` CHAR(30) NOT NULL,\n`age` SMALLINT(6) NOT NULL,\nPRIMARY KEY(`id`)\n)',0
    20180321 12:41:47,mariadb,audit,localhost,17,243,QUERY,audit_test,'INSERT INTO users (name,age) VALUES (\'Vasua\', 12),(\'Katya\', 18),(\'Misha\', 16),(\'Sasha\', 20)',0
    20180321 12:41:53,mariadb,audit,localhost,17,244,QUERY,audit_test,'SELECT name,age FROM users WHERE age<18',0
    20180321 12:41:59,mariadb,audit,localhost,17,245,QUERY,audit_test,'DELETE FROM users WHERE name=\'Vasua\'',0
    20180321 12:42:04,mariadb,audit,localhost,17,246,QUERY,audit_test,'UPDATE users SET age=17 WHERE name=\'Misha\'',0
    20180321 12:42:09,mariadb,audit,localhost,17,247,QUERY,audit_test,'SELECT name,age FROM users WHERE age<18',0
    20180321 12:42:12,mariadb,audit,localhost,17,248,QUERY,audit_test,'DROP TABLE users',0
    20180321 12:42:15,mariadb,audit,localhost,17,0,DISCONNECT,audit_test,,0
    

    Как мы видим по логу у нас запротоколированы все операции производимые под пользователем audit в БД audit_test.

    Формат лога описан в документации и выглядит так:

    [timestamp],[serverhost],[username],[host],[connectionid],[queryid],[operation],[database],[object],[retcode]

    Я думаю он не нуждается в объяснениях.

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


  • Хотите оставить комментарий?