0816關於MySQL的審計 init-connect+binlog實現用戶操作追蹤
阿新 • • 發佈:2017-08-17
database 復用 time utf ant 很大的 uri sin 超級用戶
在MYSQL中,每個連接都會先執行init-connect,進行連接的初始化。我們可以在這裏獲取用戶的登錄名稱和thread的ID值。然後配合binlog,就可以追蹤到每個操作語句的操作時間,操作人等。實現審計。 實驗過程:
1:創建登錄日誌庫,登錄日誌表
Linux 下的配置文件為 my.cnf,windows下位my.ini
3:創建普通用戶,不能有super權限。init-connect對具有super權限的用戶不起作用。同時此用戶必須至少要有對accesslog.accesslog表的INSERT權限,如果沒有,登錄後的任何操作都會導致MYSQL登錄失敗。
如果沒有對log-bin指定log文件,默認在 /var/lib/mysql目錄下以mysqld-bin.00000X等作為名稱。而 mysqld-bin.index則記錄了所有的log的文件名稱
使用時則使用mysqlbinlog /var/lib/mysql|grep -B "表名"等來追蹤database的操作。
在日誌表裏記錄的和日誌文件裏面記錄的相同。可以通過這個thread_id來追蹤到是誰,什麽時間,做了什麽操作。
轉自:http://blog.sina.com.cn/s/blog_605f5b4f01013xkv.html
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 DEF AULT 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;
Linux 下的配置文件為 my.cnf,windows下位my.ini
- init-connect=‘insert into accesslog.accesslog values(null,connection_id(),now(),user(),current_user());‘ -- 註意修改對應SQL
3:創建普通用戶,不能有super權限。init-connect對具有super權限的用戶不起作用。同時此用戶必須至少要有對accesslog.accesslog表的INSERT權限,如果沒有,登錄後的任何操作都會導致MYSQL登錄失敗。
- grant insert,select,update on *.* to [email protected]; #帶INSERT權限
- grant select,update on *.* to [email protected]; #不帶INSERT權限
- mysql> select * FROM accesslog.accesslog;
- +----+-----------+---------------------+-----------------+-----------------+
- | id | thread_id | log_time | localname | matchname |
- +----+-----------+---------------------+-----------------+-----------------+
- | 1 | 65 | 2011-03-11 19:18:25 | [email protected] | [email protected] |
- +----+-----------+---------------------+-----------------+-----------------+
- 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>
- 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 -B "表名"等來追蹤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 [email protected] 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 [email protected] for table ‘accesslog‘
- 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 | [email protected] | [email protected] |
- | 2 | 91 | 2011-03-11 19:28:33 | [email protected] | [email protected] |
- | 3 | 2 | 2011-03-11 19:31:49 | [email protected] | [email protected] |
- | 4 | 2 | 2000-10-10 10:10:10 | [email protected] | [email protected] |
- | 5 | 21 | 2000-10-10 11:11:11 | [email protected] | root@% |
- | 6 | 69 | 2011-03-12 21:35:43 | [email protected] | [email protected] |
- +----+-----------+---------------------+-----------------+-----------------+
- 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來追蹤到是誰,什麽時間,做了什麽操作。
3. Q&A
Q:使用init-connect會影響服務器性能嗎?
A:理論上,只會在用戶每次連接時往數據庫裏插入一條記錄,不會對數據庫產生很大影響。除非連接頻率非常高(當然,這個時候需要註意的就是如何進行連接復用和控制,而非是不是要用這種方法的問題了)
Q:access-log表如何維護?
A: 由於是一個log系統,推薦使用archive存儲引擎,有利於數據厄壓縮存放。如果數據庫連接數量很大的話,建議一定時間做一次數據導出,然後清表。
Q:表有其他用途麽?
A:有!access-log表當然不只用於審計,當然也可以用於對於數據庫連接的情況進行數據分析,例如每日連接數分布圖等等,只有想不到沒有做不到。
Q:會有遺漏的記錄嗎?
A:會的,init-connect 是不會在super用戶登錄時執行的。所以access-log裏不會有數據庫超級用戶的記錄,這也是為什麽我們不主張多個超級用戶,並且多人使用的原因
-- 這個跟權限有關
0816關於MySQL的審計 init-connect+binlog實現用戶操作追蹤