半瓶子酱油

身是菩提树 心如明镜台 时时勤拂拭 莫使惹尘埃

  • 博客访问: 363755
  • 博文数量: 67
  • 用 户 组: 普通用户
  • 注册时间: 2014-07-02 09:20
个人简介

不忘初心,方得始终

ITPUB论坛APP

ITPUB论坛APP



APP发帖 享双倍积分

文章分类

全部博文(67)

文章存档

2016年(9)

2015年(45)

2014年(13)

我的朋友
微信关注

IT168企业级官微



微信号:IT168qiye



系统架构师大会



微信号:SACC2013

订阅
热词专题
友情链接
MySQL审计功能 2015-04-27 00:30:14

分类: MySQL

MySQL审计功能介绍

之前有同事发现数据丢失,由于MySQL自身没有提供审计功能,查找binlog可以看到操作时间与连接IP,并不显示哪个用户做的操作,询问开发同事都说没有做删除操作,也没办法定位操作的人员证据,无奈只能恢复数据。

general log会记录详细的SQL执行记录,但是生产环境如果业务量大,会产生大量的磁盘IO操作,严重降低数据库性能,所以生产环境一般不会开启general log。后来发现可以使用init-connect + binlog的方法进行mysql的操作审计。由于mysql binlog记录了所有对数据库长生实际修改的sql语句,及其执行时间,和connection_id但是却没有记录connection_id对应的详细用户信息。在后期审计进行行为追踪时,根据binlog记录的行为及对应的connection-id 结合 之前连接记录进行分析,得出最后的结论。

设置init-connect

1、创建用于存放连接信息的表

mysql> create database AuditDB default charset utf8;
mysql> use AuditDB;
mysql> create table accesslog (
  ID int primary key auto_increment,
  ConnectionID int, 
  ConnUser varchar(30), 
  MatchUser varchar(30), 
  LoginTime datetime
);

2、保证所有链接用户对此表有写入权限

mysql> insert into mysql.db (Host,Db,User,Insert_priv) values ('%','AuditDB','','Y');
Query OK, 1 row affected (0.03 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

3、设置init-connect

在[mysqld]下添加以下设置:
#设置初始化连接操作
init-connect='Insert into AuditDB.accesslog(ConnectionID, ConnUser, MatchUser, LoginTime) values(connection_id(),user(),current_user(),now());'
#开启binlog
log-bin=xxx

4、重启数据库生效

shell> /etc/init.d/mysql restart

连接测试查询
mysql> select * from AuditDB.accesslog;
+----+--------------+--------------------+-----------------+---------------------+
| ID | ConnectionID | ConnUser           | MatchUser       | LoginTime           |
+----+--------------+--------------------+-----------------+---------------------+
|  1 |            1 | svoid@localhost    | svoid@localhost | 2015-04-24 14:16:18 |
|  2 |            3 | svoid@192.168.56.1 | svoid@%         | 2015-04-24 14:16:53 |
+----+--------------+--------------------+-----------------+---------------------+
2 rows in set (0.00 sec)

查找操作记录

1、 进行模拟操作,下列操作可由多个连接进行

mysql> use test;
Database changed

mysql> create table t (id int ,name varchar(20));
Query OK, 0 rows affected (0.06 sec)

mysql> insert into t values(1,'a');
Query OK, 1 row affected (0.16 sec)

mysql> insert into t values(2,'b');
Query OK, 1 row affected (0.03 sec)

mysql> truncate table t ;
Query OK, 0 rows affected (0.03 sec)

2、根据binlog,确认操作truncate的thread_id

mysqlbinlog --start-datetime='2015-04-24 14:10:00' --stop-datetime='2015-04-24 14:25:00' /db/mysql/data/mysql_info.000007 | grep -B 5 truncate
# at 1223
#150424 14:23:36 server id 1  end_log_pos 1302     Query    thread_id=3    exec_time=0    error_code=0
SET TIMESTAMP=1429856616/*!*/;
/*!\C gbk *//*!*/;
SET @@session.character_set_client=28,@@session.collation_connection=28,@@session.collation_server=33/*!*/;
truncate table t

根据上面的提示可以看到操作的thread_id=3

3、确认操作的用户

mysql> select * from AuditDB.accesslog where ConnectionID=3;
+----+--------------+--------------------+-----------+---------------------+
| ID | ConnectionID | ConnUser           | MatchUser | LoginTime           |
+----+--------------+--------------------+-----------+---------------------+
|  2 |            3 | svoid@192.168.56.1 | svoid@%   | 2015-04-24 14:16:53 |
+----+--------------+--------------------+-----------+---------------------+
1 row in set (0.00 sec)

补充

  1. init-connect 是不会在super用户登录时执行, 所以最好不使用超级用户
  2. 如多人使用同一用户可能无法区分,最好一个人分配一个数据库操作用户
  3. 理论上,用户每次连接时往数据库里插入一条记录,不会对数据库产生很大影响,考虑降低连接频率及accesslog插入效率优化

参考:
http://www.cnblogs.com/cenalulu/archive/2012/05/09/2491736.html

整理自网络

Svoid
2015-04-24
阅读(6423) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册