Audyt logowania do bazy danych MySQL

11

Czy istnieje sposób na kontrolę logowania do MySQL? Chciałbym móc utworzyć nazwę użytkownika dla każdego pracownika, a tym samym utworzyć ścieżkę audytu logowania. Jednak googling nie przyniósł dobrych rezultatów.

Im więcej możemy skontrolować, tym lepiej. Przynajmniej miło byłoby wiedzieć, kto się zalogował. Jeszcze lepiej byłoby zobaczyć, kto wykonał jakie zapytanie. Dzienniki służą głównie do informowania klientów, że je mamy, ponieważ w bazie danych znajdują się potencjalnie poufne informacje.

Oczywiście, możliwość sprawdzenia zapytań wykonanych przez każdego użytkownika (i kiedy) dałoby nam także możliwość lepszego wskazania, kto jest przyczyną problemu z bezpieczeństwem, jeśli taki się pojawi.

statichippo
źródło
1
Co dokładnie chcesz przeprowadzić audyt? Zakładam, że masz na myśli, że będziesz używać nazw użytkowników MySQL, a nie nazw użytkowników systemu? Jak zamierzasz później wykorzystać dane z audytu (co oznacza, że ​​jakie szczegóły są tutaj ważne, czy rejestrowanie w systemie byłoby wystarczające zamiast rejestrowania w MySQL)? Im więcej informacji podasz w swoim pytaniu, tym dokładniej udzielimy Ci odpowiedzi i szybko się uruchomimy. Wyobrażam sobie, że chcesz lepszej odpowiedzi niż „czy twoja aplikacja wykona konkretne połączenie przed każdą operacją” ~ W skrócie, jakich szczegółów potrzebowałbyś ode mnie, gdybym o to pytał?
jcolebrand

Odpowiedzi:

6

Prawdopodobnie chciałbyś skorzystać z ogólnego dziennika zapytań .

Ogólny dziennik zapytań jest ogólnym zapisem tego, co robi mysqld. Serwer zapisuje informacje w tym dzienniku, gdy klienci łączą się lub rozłączają, i rejestruje każdą instrukcję SQL otrzymaną od klientów.

Jedną ważną rzeczą związaną z logowaniem dla bezpieczeństwa jest to, że osoba atakująca nie może uzyskać dostępu do dziennika, aby usunąć ślady swojej obecności, dlatego rozważ pliki tylko do dołączania .

FWIW w Oracle możemy automatycznie wysyłać dzienniki do zdalnego dziennika systemowego , ale nie sądzę, aby MySQL miał tę funkcję. Być może mógłbyś sfałszować go za pomocą SNMP, ale nie próbowałem tego.

Gajusz
źródło
Och, spoko, ucz się czegoś nowego każdego dnia :-)
Gajusz
5

Odpowiedź @Gauis jest doskonała. Aby dodać do tego, możesz:

MySQL 5.1 umożliwia teraz przechowywanie dziennika ogólnego i dziennika powolnych zapytań jako tabel SQL.

Dodaj to do /etc/my.cnf:

[mysqld]
log-output=TABLE
log

Uruchom ponownie mysql

Następnie, gdy mysqld utworzy dziennik ogólny, zamiast pliku tekstowego utworzy tabelę jako tabelę CSV w folderze / var / lib / mysql / mysql (baza danych schematów mysql).

Po prostu zrób to, aby to zobaczyć:

SHOW CREATE TABLE mysql.general_log\G

Wszystkie połączenia się w nim zgromadzą.

Dla ciebie nie jest to bardzo przydatne, jeśli chodzi o zapytania. Byłby to po prostu pełny skan tabeli za każdym razem.

Co robić ??? KONWERSJA TO DO MyISAM i INDEKS TABELI !!!!

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;

Opcjonalnie możesz chcieć umieścić indeks pełnotekstowy w polu argumentu.

Właśnie skonfigurowałem MySQL 5.5.9 na serwerze i wypróbowałem to. Oto wynik:

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)

Teraz możesz wyszukiwać według znacznika czasu i wyszukiwać określone tokeny w polu argumentu.

Na przykład zauważ linię 4 instrukcji SELECT, którą zrobiłem. Moje logowanie zostało zarejestrowane w polu argumentu jako [email protected] on. Możesz je śledzić.

Co jeśli generał stanie się zbyt duży (Uwierz mi, stanie się zbyt duży bardzo szybko)

Co robić ???

  1. zamknij mysql
  2. przenieś plik general_log.frm, general_log.MYD i general_log.MYI na inne (i o wiele większe) miejsce na dysku.
  3. Utwórz trzy dowiązania symboliczne do general_log.frm, general_log.MYD i general_log.MYI z / var / lib / mysql / mysql
  4. chown mysql: mysql dziennik_ogólny.frm dziennik_ogólny.MYD dziennik_ogólny.MYI na nowym dysku
  5. chown mysql: mysql dziennik_ogólny.frm dziennik_ogólny.MYD dziennik_ogólny.Mylink dowiązania symboliczne w / var / lib / mysql / mysql
  6. uruchom ponownie mysql

BTW Po przejściu ogólnego dziennika do trybu offline, możesz go uruchomić, aby zebrać różne loginy, które zrobiły coś w 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;

Mam klienta z 3 serwerami DB. Eeach z DB Server zawiera ponad 1 000 000 000 (1 miliard [tysiące milionów]) linii. Wykonanie powyższego skryptu zajęło około 2,5 godziny. Tabela audit_user_host zakończyła się 27 różnymi logowaniami.

Powinieneś być gotowy do drogi.

Baw się z tym wszystkim!

RolandoMySQLDBA
źródło
Świetny artykuł! Po prostu udostępniam moje testy. Próbowałem zmienić nazwę tabeli mysql.general_log i podzielić tabelę na partycje w celu wyczyszczenia, ale nie zaloguję się w tabeli. Więc przełączam go z powrotem na niepodzieloną na partycje tabelę MyIsam. Dzięki!
1

Zamiast robić tyle rzeczy ręcznie, po prostu zainstaluj wtyczkę Audit, która daje więcej wglądu na poziomie użytkownika

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

Jest dostępny w wybranych komercyjnych wersjach MySQL. Byłoby wspaniale, gdyby jakikolwiek widelec MySQL dodał również w wersji społecznościowej, aby większość ludzi mogła skorzystać z tej funkcji, w przeciwnym razie musimy polegać na rozwiązaniu dostarczonym przez @RolandoMySQLDBA.

Mahesh Patil
źródło
0

@statichippo
Jak zainstalować rejestrowanie kontroli na MySQL.
+ Rejestrowanie inspekcji obsługuje tylko MySQL Enterprise
+ Możesz zainstalować rejestrowanie audytu w społeczności MySQL:
1. Skopiuj plik audit_log.so przez Możesz zainstalować MySQL Enterprise Trial, a następnie skopiować plik audit_log.so do społeczności MySQL.
2. Skopiuj plik audit_log.so do katalogu wtyczki jako / usr / lib64 / mysql / plugin lub możesz wyświetlić katalog wtyczek poprzez:
Przejdź do konsoli mysql: mysql> pokaż zmienne globalne, takie jak „% plugin%”;
3. Zainstaluj rejestrowanie kontroli jako:
mysql> ZAINSTALUJ WTYCZKĘ audit_log SONAME 'audit_log.so';
mysql> POKAŻ ZMIENNE JAK 'audit_log%';
4. Rejestrowanie wyników audytu:
tail -f /var/lib/mysql/audit.log

Wielkie dzięki.

Binh Nguyen
źródło