mysql 用init-connect+binlog實現用戶操作追蹤做access的ip的log記錄


MYSQL中,每個連接都會先執行init-connect,進行連接的初始化。我們可以在這里獲取用戶的登錄名稱和thread的ID值。然后配合binlog,就可以追蹤到每個操作語句的操作時間,操作人等。實現審計。

實驗過程:
1:創建登錄日志庫,登錄日志表

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 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, #登錄時間

  `localname` varchar(30) DEFAULT NULL, #登錄名稱帶IP

  `matchname` varchar(30) DEFAULT NULL, #登錄用戶,user的全稱

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2:在配置文件中配置init-connect參數。登錄時插入日志表。如果這個參數是個錯誤的SQL語句,登錄就會失敗。
Linux 下的配置文件為 my.cnf,windows下my.ini

init-connect='insert into accesslog.accesslog values(null,connection_id(),now(),user(),current_user());'

log-bin

重啟service mysqld 以使其配置文件生效

3:創建普通用戶,不能有super權限。init-connect對具有super權限的用戶不起作用。同時此用戶必須要有INSERT權限,如果沒有,登錄后的任何操作都會導致MYSQL登錄失敗。

grant insert,select,update on *.* to 'user1'@'localhost'; #帶INSERT權限

grant select,update on *.* to 'user2'@'localhost'; #不帶INSERT權限

4:SESSION1登錄,並查看日志

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;# 當前運行的threadId

+----+-------+----------------+------+---------+------+-------+------------------+

| 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登錄

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 ***

看下錯誤日志
如果沒有對log-bin指定log文件,默認在 /var/lib/mysql目錄下以mysqld-bin.00000X等作為名稱。而 mysqld-bin.index則記錄了所有的log的文件名稱
使用時則使用mysqlbinlog /var/lib/mysql|grep "*****"等來追蹤database的操作。

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操作,查看日志文件。

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)

查看日志文件的內容

# 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來追蹤到是誰,什么時間,做了什么操作。

 

注:

1.mysql在linux下可以安裝audit_log.so插件來實現審計,在windows下不可以,所以用此方法代替。

2.此方法只適用於binlog存在的條件下,如果系統默認保留14天binlog日志則14天以前的用戶信息無法查詢。

3.對於用戶賦權時不是on *.*的用戶需要加grant insert on accesslog.accesslog to user@host。

4.當mysql重啟后accesslog表中thread_id可能會有重復情況,此時需要結合log_time判斷具體登錄用戶信息。

5.注釋為本人自己總結,如有不對歡迎指出。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM