記錄mysql的具體操作明細


分類: MySQL

 

前言:
測試環境莫名其妙有幾條重要數據被刪除了,由於在binlog里面只看到是公用賬號刪除的,無法查詢是那個誰在那個時間段登錄的,就考慮怎么記錄每一個MYSQL賬號的登錄信息,在MYSQL中,每個連接都會先執行init-connect,進行連接的初始化,我們可以在這里獲取用戶的登錄名稱和thread的ID值。然后配合binlog,就可以追蹤到每個操作語句的操作時間,操作人以及客戶端的連接進程信息等。實現審計。


1,在mysql服務器db中建立單獨的記錄訪問信息的庫
set names utf8;
create database access_log;
CREATE TABLE `access_log` 
(
  `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 comment '錄入用戶登錄信息';



2,在配置文件中配置init-connect參數。登錄時插入日志表。如果這個參數是個錯誤的SQL語句,登錄就會失敗。
vim /usr/local/mysql/my.cnf
init-connect='INSERT INTO access_log.access_log VALUES(NULL,CONNECTION_ID(),NOW(),USER(),CURRENT_USER());'
然后重啟數據庫

3,創建普通用戶,不能有super權限,而且用戶必須有對access_log庫的access_log表的insert權限,否則會登錄失敗。
給登錄用戶賦予insert權限,但是不賦予access_log的insert、select權限,
GRANT INSERT,DELETE,UPDATE,SELECT ON test.* TO audit_user@'%' IDENTIFIED BY 'cacti_user1603';
mysql> GRANT CREATE,DROP,ALTER,INSERT,DELETE,UPDATE,SELECT ON test.* TO audit_user@'%' IDENTIFIED BY 'cacti_user1603';
Query OK, 0 rows affected (0.00 sec)
mysql> exit
然后去用新的audit_user登錄操作
[root@db_server ~]# /usr/local/mysql/bin/mysql  -uaudit_user -p -S /usr/local/mysql/mysql.sock
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 25
Server version: 5.6.12-log

Copyright (c) 2000, 2013, 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.

mysql> lect * from access_log.access_log;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    26
Current database: *** NONE ***


ERROR 1184 (08S01): Aborted connection 26 to db: 'unconnected' user: 'audit_user' host: 'localhost' (init_connect command failed)
mysql> 
看到報錯信息 (init_connect command failed),再去錯誤日志error log驗證一下:
tail -fn 5 /usr/local/mysql/mysqld.log 
2014-07-28 16:03:31 23743 [Warning] Aborted connection 25 to db: 'unconnected' user: 'audit_user' host: 'localhost' (init_connect command failed)
2014-07-28 16:03:31 23743 [Warning] INSERT command denied to user ''@'localhost' for table 'access_log'
2014-07-28 16:04:04 23743 [Warning] Aborted connection 26 to db: 'unconnected' user: 'audit_user' host: 'localhost' (init_connect command failed)
2014-07-28 16:04:04 23743 [Warning] INSERT command denied to user ''@'localhost' for table 'access_log'
看到必須要有對access_log庫的access_log表的insert權限才行。


4,賦予用戶access_loginsertselect權限,然后重新賦予權限:
GRANT SELECT,INSERT ON access_log.* TO audit_user@'%';
mysql> 
mysql> GRANT SELECT,INSERT ON access_log.* TO audit_user@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> exit
Bye

再登錄,報錯如下:
[root@db_server ~]# /usr/local/mysql/bin/mysql  -uaudit_user -p -S /usr/local/mysql/mysql.sock
Enter password: 
ERROR 1045 (28000): Access denied for user 'audit_user'@'localhost' (using password: YES)
[root@db_server ~]# 

去查看error日志:
2014-07-28 16:15:29 23743 [Warning] INSERT command denied to user ''@'localhost' for table 'access_log'
2014-07-28 16:15:41 23743 [Warning] Aborted connection 37 to db: 'unconnected' user: 'audit_user' host: 'localhost' (init_connect command failed)
2014-07-28 16:15:41 23743 [Warning] INSERT command denied to user ''@'localhost' for table 'access_log'
2014-07-28 16:15:50 23743 [Warning] Aborted connection 38 to db: 'unconnected' user: 'audit_user' host: 'localhost' (init_connect command failed)
2014-07-28 16:15:50 23743 [Warning] INSERT command denied to user ''@'localhost' for table 'access_log'

需要用root用戶登錄進去,清空掉用戶為''的用戶記錄。
 mysql> select user,host,password from mysql.user;
+----------------+-----------+-------------------------------------------+
| user           | host      | password                                  |
+----------------+-----------+-------------------------------------------+
| root           | localhost |                                           |
| root           | db_server   |                                           |
| root           | 127.0.0.1 |                                           |
| root           | ::1       |                                           |
|                | localhost |                                           |
|                | db_server   |                                           |
| cacti_user     | %         | *EB9E3195E443D577879101A35EF64A701B35F949 |
| cacti_user     | 1         | *D5FF9B53A78232DA13D3643965A5961449B387DB |
| cacti_user     | 2         | *D5FF9B53A78232DA13D3643965A5961449B387DB |
| test_user      | 192.%     | *8A447777509932F0ED07ADB033562027D95A0F17 |
| test_user      | 1         | *8A447777509932F0ED07ADB033562027D95A0F17 |
| weakpwd_user_1 | 10.%      | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| weakpwd_user_2 | 10.%      | *B1461C9C68AFA1129A5F968C343636192A084ADB |
| weakpwd_user_3 | 10.%      | *DCB7DF5FFC82C441503300FFF165257BC551A598 |
| audit_user     | %         | *AEAB1915B137FAFDE9B949D67A9A42DDB68DD8A2 |
+----------------+-----------+-------------------------------------------+
15 rows in set (0.00 sec)

mysql> drop user ''@'localhost';
Query OK, 0 rows affected (0.00 sec)

mysql> drop user ''@'db_server';
Query OK, 0 rows affected (0.00 sec)

mysql> 

再用已經分配了access_log表的Insert權限的audit_user登錄
mysql> select * from access_log.access_log;
+----+-----------+---------------------+---------------------------+--------------+
| id | thread_id | log_time            | localname                 | matchname    |
+----+-----------+---------------------+---------------------------+--------------+
|  4 |        41 | 2014-07-28 16:19:37 | audit_user@localhost      | audit_user@% |
|  5 |        42 | 2014-07-28 16:20:32 | audit_user@localhost      | audit_user@% |
|  6 |        45 | 2014-07-28 16:21:11 | audit_user@localhost      | audit_user@% |
+----+-----------+---------------------+---------------------------+--------------+
6 rows in set (0.00 sec)

mysql> show full processlist;
+----+------------+-----------+------+---------+------+-------+-----------------------+
| Id | User       | Host      | db   | Command | Time | State | Info                  |
+----+------------+-----------+------+---------+------+-------+-----------------------+
| 45 | audit_user | localhost | NULL | Query   |    0 | init  | show full processlist |
+----+------------+-----------+------+---------+------+-------+-----------------------+
1 row in set (0.00 sec)

mysql> 

5,再用另外一個用戶登錄建表,錄入測試數據。
建表錄入數據記錄
mysql> use test;
Database changed
mysql> create table t1 select 1 as a, 'wa' as b;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

查看跟蹤用戶行為記錄。
mysql> select * from access_log.access_log;
+----+-----------+---------------------+---------------------------+--------------+
| id | thread_id | log_time            | localname                 | matchname    |
+----+-----------+---------------------+---------------------------+--------------+
|  4 |        41 | 2014-07-28 16:19:37 | audit_user@localhost      | audit_user@% |
|  5 |        42 | 2014-07-28 16:20:32 | audit_user@localhost      | audit_user@% |
|  6 |        45 | 2014-07-28 16:21:11 | audit_user@localhost      | audit_user@% |
|  7 |        48 | 2014-07-28 16:30:42 | audit_user@192.168.3.62    | audit_user@% |
|  8 |        50 | 2014-07-28 16:46:11 | audit_user@192.168.3.62    | audit_user@% |
+----+-----------+---------------------+---------------------------+--------------+
8 rows in set (0.00 sec)

去mysql db服務器上查看binlog 內容,解析完后,沒有insert語句,怎么回事,去看my.cnf
#binlog-ignore-db=mysql                         # No sync databases
#binlog-ignore-db=test                          # No sync databases
#binlog-ignore-db=information_schema            # No sync databases
#binlog-ignore-db=performance_schema

原來是對test庫有binlog過濾設置,全部注釋掉。重啟mysql庫,重新來一遍,可以在看到binlog
在MySQL客戶端上重新執行。
mysql> use test;
Database changed
mysql> insert into test.t1 select 5,'t5';
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from access_log.access_log;
+----+-----------+---------------------+---------------------------+--------------+
| id | thread_id | log_time            | localname                 | matchname    |
+----+-----------+---------------------+---------------------------+--------------+
|  1 |        17 | 2014-07-28 15:41:04 | cacti_user@192.168.171.71 | cacti_user@% |
|  2 |        18 | 2014-07-28 15:41:05 | cacti_user@192.168.171.71 | cacti_user@% |
|  3 |        19 | 2014-07-28 15:41:05 | cacti_user@192.168.171.71 | cacti_user@% |
|  4 |        41 | 2014-07-28 16:19:37 | audit_user@localhost      | audit_user@% |
|  5 |        42 | 2014-07-28 16:20:32 | audit_user@localhost      | audit_user@% |
|  6 |        45 | 2014-07-28 16:21:11 | audit_user@localhost      | audit_user@% |
|  7 |        48 | 2014-07-28 16:30:42 | audit_user@192.168.3.62    | audit_user@% |
|  8 |        50 | 2014-07-28 16:46:11 | audit_user@192.168.3.62    | audit_user@% |
|  9 |        56 | 2014-07-28 19:32:12 | audit_user@192.168.1.12    | audit_user@% |
| 10 |         1 | 2014-07-28 20:02:56 | audit_user@192.168.3.62    | audit_user@% |
+----+-----------+---------------------+---------------------------+--------------+
10 rows in set (0.00 sec)
看到thread_id為1


6,如何查看何跟蹤用戶行為記錄。
去mysql數據庫服務器上查看binlog,應該thread_id=1的binlog記錄。
[root@db_server binlog]# /usr/local/mysql/bin/mysqlbinlog  --base64-output=DECODE-ROWS  mysql-bin.000018 -v>3.log
[root@db_server binlog]# vim 3.log
# at 1103
#140728 20:12:48 server id 72  end_log_pos 1175 CRC32 0xa323c00e        Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1406549568/*!*/;
BEGIN
/*!*/;
# at 1175
#140728 20:12:48 server id 72  end_log_pos 1229 CRC32 0xbb8ca914        Table_map: `access_log`.`t1` mapped to number 72
# at 1229
#140728 20:12:48 server id 72  end_log_pos 1272 CRC32 0x8eed1450        Write_rows: table id 72 flags: STMT_END_F
### INSERT INTO `access_log`.`t1`
### SET
###   @1=10
###   @2='w0'
# at 1272
#140728 20:12:48 server id 72  end_log_pos 1303 CRC32 0x72b26336        Xid = 14
COMMIT/*!*/;

看到thread_id=1,然后,就可以根據thread_id=1來判斷執行這條insert命令的來源,還可以在mysql服務器上執行show full processlist;來得到MySQL客戶端的請求端口,
mysql> show full processlist;
+----+------------+-------------------+------+---------+------+-------+-----------------------+
| Id | User       | Host              | db   | Command | Time | State | Info                  |
+----+------------+-------------------+------+---------+------+-------+-----------------------+
|  1 | audit_user | 192.168.3.62:44657 | test | Sleep   |  162 |       | NULL                  |
|  3 | root       | localhost         | NULL | Query   |    0 | init  | show full processlist |
+----+------------+-------------------+------+---------+------+-------+-----------------------+
2 rows in set (0.00 sec)


mysql> 
看到Id為1的線程,端口是44657

我們切換回mysql客戶端,去查看端口是44657的是什么進程,如下所示:
[tim@db_client ~]$ netstat -antlp |grep 44657
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 192.168.3.62:44657           192.168.1.12:3307            ESTABLISHED 6335/mysql          
[tim@db_client ~]$ 

獲取到該進程的PID 6335,再通過ps -eaf得到該進程所執行的命令,如下所示:
[tim@db_client ~]$ ps -eaf|grep 6335
tim   6335 25497  0 19:59 pts/1    00:00:00 mysql -uaudit_user -p -h 192.168.1.12 -P3307
tim   6993  6906  0 20:16 pts/2    00:00:00 grep 6335
[tim@db_client ~]$

最后查到是通過mysql客戶端登陸連接的。加入這個6335是某個web工程的,那么,也可以根據ps -eaf命令查詢得到web工程的進程信息。

 

http://blog.chinaunix.net/uid-24086995-id-168445.html

http://blog.itpub.net/26230597/viewspace-1240386


免責聲明!

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



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