审核MySQL数据库上的登录


11

有没有办法审核MySQL的登录信息?我希望能够为每个员工创建一个用户名,从而创建登录的审计线索。但是,谷歌搜索并没有取得好的结果。

我们可以审核的越多越好。至少,很高兴知道谁何时登录。最好查看谁在何时执行什么查询。因为数据库中存在潜在的敏感信息,所以那里的日志主要是告诉客户我们拥有它们。

显然,能够审核每个用户(和何时)执行的查询也将使我们能够更好地确定如果出现安全问题的原因是谁。


1
您到底要审核什么?我想您是说您将使用MySQL用户名,而不是系统用户名?您打算以后如何使用审核数据(这意味着什么细节很重要,系统日志记录足以代替MySQL日志记录)。您可以在问题中提供的信息越多,我们就可以为您提供更准确的答案,并迅速启动。我想您比“让您的应用在进行其他操作之前先进行特定的sproc调用”更好地回答吗?简而言之,如果我要问这个问题,您需要我提供哪些详细信息?
jcolebrand

Answers:


6

您可能希望使用常规查询日志

常规查询日志是mysqld在做什么的常规记录。当客户端连接或断开连接时,服务器会将信息写入此日志,并记录从客户端收到的每个SQL语句。

日志记录的安全性很重要的一点是,攻击者无法访问日志以清除其存在的痕迹,因此请考虑仅追加文件

在Oracle的FWIW中,我们可以将日志自动发送到远程syslog,但是我不相信MySQL具备此功能。也许您可以使用SNMP伪造它,但我还没有尝试过。



太好了,每天都学点新东西:-)
Gaius

5

@Gauis的回答非常好。要进一步添加它,您可以执行以下操作:

MySQL 5.1现在允许将常规日志和慢速查询日志存储为SQL表。

将此添加到/etc/my.cnf:

[mysqld]
log-output=TABLE
log

重启mysql

然后,当mysqld创建常规日志而不是文本文件时,它将在/ var / lib / mysql / mysql文件夹(mysql模式数据库)中创建该表作为CSV表。

只需执行以下操作即可查看:

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)

现在,您可以按时间戳查询并在参数字段中查找特定的标记。

例如,请注意我所做的SELECT的第4行。我的登录记录为参数字段为lwdba@127.0.0.1 on。您可以跟踪这些。

如果将军太大,该怎么办(相信我,它将很快变得太大)

该怎么办 ???

  1. 关闭mysql
  2. 将general_log.frm,general_log.MYD和general_log.MYI移到另一个(并且希望更大)的磁盘装载中。
  3. 从/ var / lib / mysql / mysql创建到general_log.frm,general_log.MYD和general_log.MYI的三个符号链接
  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服务器的客户端。使用DB Server的Eeach中有超过10亿(十亿[千亿]]行。上面的脚本花费了大约2.5个小时来完成。audit_user_host表以27个不同的登录名结束。

你应该很好。

大家都玩这个!!!


很棒的文章!只是分享我的测试。我尝试重命名该表mysql.general_log并对该表进行分区以进行清除,但不会登录该表。因此,我将其切换回未分区的MyIsam表。谢谢!


0

@statichippo
如何在MySQL上安装审核日志记录。
+审核日志仅支持MySQL Enterprise
+您可以在MySQL社区上安装审核日志:
1.复制文件audit_log.so可以安装MySQL Enterprise Trial,然后将文件audit_log.so复制到MySQL社区。
2.复制audit_log.so到PLUGIN_DIR为在/ usr / lib64下/ mysql的/插件,或者您可以显示插件目录是:
转到mysql的控制台:MySQL的>显示全局变量LIKE '%插件%';
3.将审计日志安装为:
mysql> INSTALL PLUGIN audit_log SONAME'audit_log.so';
mysql>显示变量,如“ audit_log%”;
4.输出审核日志记录:
tail -f /var/lib/mysql/audit.log

非常感谢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.