在MYSQL中,每个连接都会先执行init-connect,进行连接的初始化。我们可以在这里获取用户的登录名称和thread的ID值。然后配合binlog,就可以追踪到每个操作语句的操作时间,操作人等。实现审计。
实验过程:
1:创建登录日志库,登录日志表
1:创建登录日志库,登录日志表
1 2 3 4 5 6 7 8 9 10 11 | CREATE DATABASE `accesslog`; USE `accesslog`; CREATE TABLE `accesslog` ( `id` int (11) NOT NULL AUTO_INCREMENT, `thread_id` int (11) DEFAULT NULL , #线程ID,这个值很重要 `log_time` timestamp NOT NULL DEF AULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP , #登录时间 `localname` varchar (30) DEFAULT NULL , #登录名称 `matchname` varchar (30) DEFAULT NULL , #登录用户 PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; |
2:在配置文件中配置init-connect参数。登录时插入日志表。如果这个参数是个错误的SQL语句,登录就会失败。
1 | init- connect = 'insert into accesslog.accesslog values(null,connection_id(),now(),user(),current_user());' |
3:创建普通用户,不能有super权限。init-connect对具有super权限的用户不起作用。同时此用户必须要有INSERT权限,如果没有,登录后的任何操作都会导致MYSQL登录失败。
1 2 | grant insert , select , update on *.* to 'user1' @ 'localhost' ; #带 INSERT 权限 grant select , update on *.* to 'user2' @ 'localhost' ; #不带 INSERT 权限 |
4:SESSION1登录,并查看日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | D:\mysql6\bin>mysql -uuser1 -p Enter password : Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 65 Server version: 5.1.45-community-log MySQL Community Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> select * FROM accesslog.accesslog; + ----+-----------+---------------------+-----------------+-----------------+ | id | thread_id | log_time | localname | matchname | + ----+-----------+---------------------+-----------------+-----------------+ | 1 | 65 | 2011-03-11 19:18:25 | user1@localhost | user1@localhost | + ----+-----------+---------------------+-----------------+-----------------+ 1 row in set (0.00 sec) mysql> show processlist; + ----+-------+----------------+------+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | + ----+-------+----------------+------+---------+------+-------+------------------+ | 65 | user1 | localhost:1339 | NULL | Query | 0 | NULL | show processlist | + ----+-------+----------------+------+---------+------+-------+------------------+ 1 row in set (0.00 sec) mysql> |
5:再用user2登录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | D:\mysql6\bin>mysql -uuser2 -p Enter password : Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 76 Server version: 5.1.45-community-log Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> select * FROM accesslog.accesslog; ERROR 2006 (HY000): MySQL server has gone away No connection . Trying to reconnect... Connection id: 77 Current database : *** NONE *** ERROR 2013 (HY000): Lost connection to MySQL server during query mysql> select * FROM accesslog.accesslog; ERROR 2006 (HY000): MySQL server has gone away No connection . Trying to reconnect... Connection id: 78 Current database : *** NONE *** |
看下错误日志
1 2 3 4 | 110311 19:23:47 [Warning] Aborted connection 77 to db: 'unconnected' user : 'user2' host: 'localhost' (init_connect command failed) 110311 19:23:47 [Warning] INSERT command denied to user 'user2' @ 'localhost' for table 'accesslog' 110311 19:23:53 [Warning] Aborted connection 78 to db: 'unconnected' user : 'user2' host: 'localhost' (init_connect command failed) 110311 19:23:53 [Warning] INSERT command denied to user 'user2' @ 'localhost' for table 'accesslog' |
6:下面以USER1登录,并做一个INSERT操作,查看日志文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | mysql> insert into t3 values (10,10, '2011-10-10 00:00:00' ); Query OK, 1 row affected (0.00 sec) mysql> show processlist; + ----+-------+----------------+-----------+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | + ----+-------+----------------+-----------+---------+------+-------+------------------+ | 69 | user1 | localhost:1439 | accesslog | Query | 0 | NULL | show processlist | + ----+-------+----------------+-----------+---------+------+-------+------------------+ 1 row in set (0.00 sec) mysql> select * from accesslog.accesslog; + ----+-----------+---------------------+-----------------+-----------------+ | id | thread_id | log_time | localname | matchname | + ----+-----------+---------------------+-----------------+-----------------+ | 1 | 65 | 2011-03-11 19:18:25 | user1@localhost | user1@localhost | | 2 | 91 | 2011-03-11 19:28:33 | user1@localhost | user1@localhost | | 3 | 2 | 2011-03-11 19:31:49 | user1@localhost | user1@localhost | | 4 | 2 | 2000-10-10 10:10:10 | user1@localhost | user1@localhost | | 5 | 21 | 2000-10-10 11:11:11 | root@localhost | root@% | | 6 | 69 | 2011-03-12 21:35:43 | user1@localhost | user1@localhost | + ----+-----------+---------------------+-----------------+-----------------+ 6 rows in set (0.01 sec) |
查看日志文件的内容
1 2 3 4 5 6 7 | # at 340 #110312 21:36:01 server id 1 end_log_pos 453 Query thread_id=69 exec_time=0 error_code=0 use text /*!*/ ; SET TIMESTAMP =1299936961 /*!*/ ; insert into t3 values (10,10, '2011-10-10 00:00:00' ) /*!*/ ; # at 453 |
thread_id=69
在日志表里记录的和日志文件里面记录的相同。可以通过这个thread_id来追踪到是谁,什么时间,做了什么操作。