Audit-Anmeldungen in der MySQL-Datenbank

11

Gibt es eine Möglichkeit, Anmeldungen bei MySQL zu überwachen? Ich möchte in der Lage sein, für jeden Mitarbeiter einen Benutzernamen und damit einen Prüfpfad für Anmeldungen zu erstellen. Googeln hat jedoch keine guten Ergebnisse gebracht.

Je mehr wir prüfen können, desto besser. Zumindest wäre es schön zu wissen, wer sich wann angemeldet hat. Es wäre sogar noch besser zu sehen, wer wann welche Abfrage ausgeführt hat. Die Protokolle dienen hauptsächlich dazu, den Kunden mitzuteilen, dass wir sie haben, da die Datenbank potenziell vertrauliche Informationen enthält.

Wenn wir in der Lage sind, die von jedem Benutzer ausgeführten Abfragen (und wann) zu prüfen, können wir natürlich auch besser bestimmen, wer die Ursache für ein Sicherheitsproblem ist, falls eines auftreten sollte.

statichippo
quelle
1
Was genau möchten Sie prüfen? Ich nehme an, Sie meinen, Sie verwenden die MySQL-Benutzernamen, nicht die System-Benutzernamen? Wie wollen Sie die Überwachungsdaten später verwenden (dh welche Details hier wichtig sind, würde die Systemprotokollierung anstelle der MySQL-Protokollierung ausreichen)? Je mehr Informationen Sie in Ihrer Frage angeben können, desto genauer können wir Ihnen eine Antwort geben und schnell booten. Ich stelle mir vor, Sie möchten eine bessere Antwort als "Lassen Sie Ihre App vor jeder Operation einen bestimmten Anruf tätigen" ~ Kurz gesagt, welche Details würden Sie von mir benötigen, wenn ich dies fragen würde?
Jcolebrand

Antworten:

6

Sie möchten wahrscheinlich das allgemeine Abfrageprotokoll verwenden .

Das allgemeine Abfrageprotokoll ist eine allgemeine Aufzeichnung dessen, was mysqld tut. Der Server schreibt Informationen in dieses Protokoll, wenn Clients eine Verbindung herstellen oder trennen, und protokolliert jede von Clients empfangene SQL-Anweisung.

Eine wichtige Sache bei der Protokollierung aus Sicherheitsgründen ist, dass ein Angreifer nicht auf das Protokoll zugreifen kann, um Spuren seiner Anwesenheit zu löschen. Ziehen Sie daher nur Dateien zum Anhängen in Betracht .

FWIW in Oracle können wir Protokolle automatisch an ein Remote-Syslog senden , aber ich glaube nicht, dass MySQL diese Funktion noch hat. Vielleicht könnten Sie es mit SNMP vortäuschen, aber ich habe es nicht versucht.

Gaius
quelle
Oh cool, lerne jeden Tag etwas Neues :-)
Gaius
5

Die Antwort von @Gauis ist ausgezeichnet. Um es weiter zu ergänzen, können Sie Folgendes tun:

In MySQL 5.1 können jetzt das allgemeine Protokoll und das langsame Abfrageprotokoll als SQL-Tabellen gespeichert werden.

Fügen Sie dies zu /etc/my.cnf hinzu:

[mysqld]
log-output=TABLE
log

Starten Sie MySQL neu

Wenn mysqld dann das allgemeine Protokoll erstellt, wird anstelle einer Textdatei die Tabelle als CSV-Tabelle im Ordner / var / lib / mysql / mysql (mysql-Schemadatenbank) erstellt.

Tun Sie dies einfach, um es zu sehen:

SHOW CREATE TABLE mysql.general_log\G

Alle Verbindungen werden sich darin stapeln.

Für Sie ist das nicht sehr nützlich, wenn Sie es abfragen möchten. Es wäre jedes Mal nur ein vollständiger Tabellenscan.

Was ist zu tun ??? Wandle es in Myisam um und indiziere die Tabelle!

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;

Optional können Sie dem Argumentfeld einen Volltextindex hinzufügen.

Ich habe gerade MySQL 5.5.9 auf einem Server eingerichtet und dies ausprobiert. Hier ist das Ergebnis:

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)

Jetzt können Sie nach Zeitstempel abfragen und im Argumentfeld nach bestimmten Token suchen.

Beachten Sie beispielsweise Zeile 4 von SELECT I. Meine Anmeldung wurde im Argumentfeld als aufgezeichnet[email protected] on . Sie können diese verfolgen.

Was ist, wenn der General zu groß wird? (Glauben Sie mir, es wird sehr schnell zu groß.)

Was ist zu tun ???

  1. Herunterfahren MySQL
  2. Verschieben Sie die Dateien general_log.frm, general_log.MYD und general_log.MYI auf einen anderen (und hoffentlich größeren) Festplatten-Mount.
  3. Erstellen Sie drei Symlinks zu general_log.frm, general_log.MYD und general_log.MYI aus / var / lib / mysql / mysql
  4. chown mysql: mysql general_log.frm general_log.MYD general_log.MYI auf dem neuen Disk Mount
  5. chown mysql: mysql general_log.frm general_log.MYD general_log.MYI symlinks in / var / lib / mysql / mysql
  6. starte mysql wieder

Übrigens: Sobald Sie das allgemeine Protokoll offline geschaltet haben, können Sie diese ausführen, um die unterschiedlichen Anmeldungen zu sammeln, die in mysqld etwas bewirkt haben:

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;

Ich habe einen Client mit 3 DB-Servern. Eeach with DB Server verfügt über mehr als 1.000.000.000 (1 Milliarde [Tausende Millionen]) Leitungen. Das obige Skript dauerte ungefähr 2,5 Stunden. Die Tabelle audit_user_host endete mit 27 unterschiedlichen Anmeldungen.

Du solltest gut gehen.

Viel Spaß mit diesem, alle !!!

RolandoMySQLDBA
quelle
Großartiger Artikel! Ich teile nur meine Tests. Ich habe versucht, die Tabelle mysql.general_log umzubenennen und die Tabelle zum Löschen zu partitionieren, aber ich habe mich nicht in der Tabelle angemeldet. Also schalte ich es zurück zu einer nicht partitionierten MyIsam-Tabelle. Vielen Dank!
1

Anstatt so viele Dinge manuell zu erledigen, installieren Sie einfach das Audit-Plugin, das mehr Einblick auf Benutzerebene bietet

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

Es ist jedoch für ausgewählte kommerzielle MySQL-Editionen verfügbar. Es wäre großartig gewesen, wenn eine MySQL-Gabel auch in der Community-Edition hinzugefügt worden wäre, damit die meisten Benutzer von dieser Funktion profitieren. Andernfalls müssen wir uns auf die von @RolandoMySQLDBA bereitgestellte Lösung verlassen.

Mahesh Patil
quelle
0

@statichippo
So installieren Sie die Überwachungsprotokollierung unter MySQL.
+ Die Überwachungsprotokollierung unterstützt nur MySQL Enterprise.
+ Sie können die
Überwachungsprotokollierung in der MySQL Community installieren : 1. Kopieren Sie die Datei audit_log.so von Sie können die MySQL Enterprise-Testversion installieren und dann die Datei audit_log.so in die MySQL Community kopieren.
2. Kopieren Sie audit_log.so als / usr / lib64 / mysql / plugin nach plugin_dir, oder Sie können das Plugin-Verzeichnis folgendermaßen anzeigen:
Gehen Sie zur mysql-Konsole: mysql> show global variables wie '% plugin%';
3. Installieren
Sie die Überwachungsprotokollierung wie folgt : mysql> INSTALL PLUGIN audit_log SONAME 'audit_log.so';
mysql> SHOW VARIABLES LIKE 'audit_log%';
4. Ausgabe-Audit-Protokollierung:
tail -f /var/lib/mysql/audit.log

Danke vielmals.

Binh Nguyen
quelle