MySQL安全審計(init_connect)


1、常規安全

在說審計之前我們先提一點一般我們常用的MySQL的安全注意事項。

  • 指定完善的MySQL安全流程
  • 用戶授權郵件備注
  • 每個人對應權限均需留底
  • 所有用戶非管理員及特殊賬戶,均精細化授權

2、sql審計

MySQL安全審計,對於小公司來說既沒有數據庫中間件平台,也沒有SQL審計平台,那么如果做一個簡單高性能的數據庫審計呢?今日瀏覽global屬性時發現 init_connect的屬性,這個屬性可以執行用戶連接后做的操作,官方使用的autocommit 做的實例,而且可以支持動態修改。那我們是不是可以利用這個特性和binlog記錄實踐ID,審計所有人都做了在什么時間登錄做了什么事情。

官方資料: https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html

此實驗的難點:

  • 用戶授權,所有用戶及對該表有select,insert權限
  • 研究在主從情況模式下如何區分對待(級聯)
  • 對鏈接的性能會有多大差距(主要針對非連接池或鏈接復用的情況下)

2.1 實驗

創建存儲用戶數據的表

(root@localhost:mysql.sock) [(none)]>create database accesslog;
Query OK, 1 row affected (0.08 sec)

(root@localhost:mysql.sock) [(none)]>use accesslog

CREATE TABLE accesslog (`id` int(11) primary key auto_increment,
`thread_id` bigint COMMENT '線程ID',
`time` datetime COMMENT '時間', 
`localname` varchar(100) COMMENT '連接的ID用戶+地址', 
`matchname` varchar(100) COMMENT '匹配到的用戶ID');

創建所有需要監控的賬號,給予INSERT權限

(root@localhost:mysql.sock) [accesslog]>select connection_id(), now(), user(), current_user();
+-----------------+---------------------+----------------+----------------+
| connection_id() | now()               | user()         | current_user() |
+-----------------+---------------------+----------------+----------------+
|               5 | 2017-06-20 09:02:12 | root@localhost | root@localhost |
+-----------------+---------------------+----------------+----------------+
1 row in set (0.05 sec)

想必大家看到如上信息,就明白了我們要干什么了,對吧。
那我們配置init_connect

SET GLOBAL init_connect='INSERT INTO accesslog.accesslog(thread_id,time,localname,matchname) values(connection_id(), now(), user(), current_user());';

接下來,見證奇跡的時刻到了

需要注意的就是,官方為了保證安全,有super權限的將not exec,原文如下(所以super。。。。):

For users that have the SUPER privilege, the content of init_connect is not executed. This is done so that an erroneous value for init_connect does not prevent all clients from connecting. For example, the value might contain a statement that has a syntax error, thus causing client connections to fail. Not executing init_connect for users that have the SUPER privilege enables them to open a connection and fix the init_connect value. 

創建測試用戶:

(root@localhost:mysql.sock) [(none)]>grant create ,drop, select ,insert, update on testdemo.* to evantest@'%' identified by '123';
Query OK, 0 rows affected, 1 warning (0.05 sec)

(root@localhost:mysql.sock) [(none)]>grant insert on accesslog.* to evantest@'%';
Query OK, 0 rows affected (0.00 sec)

測試效果

[root@MySQL-Node-07 mysql_test_data]# mysql -uevantest -p123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.18-log MySQL Community Server (GPL)

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

(evantest@localhost:mysql.sock) [(none)]>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| accesslog          |
| testdemo           |
+--------------------+
3 rows in set (0.00 sec)

(evantest@localhost:mysql.sock) [(none)]>use testdemo
Database changed
(evantest@localhost:mysql.sock) [testdemo]>create table testtable(id int comment 'test');
Query OK, 0 rows affected (0.02 sec)

查看數據庫:

(root@localhost:mysql.sock) [accesslog]>select * from accesslog;
+----+-----------+---------------------+--------------------+----------------+
| id | thread_id | time                | localname          | matchname      |
+----+-----------+---------------------+--------------------+----------------+
|  1 |         6 | 2017-06-20 09:06:32 | root@localhost     | root@localhost |
|  2 |        10 | 2017-06-20 09:17:35 | evantest@localhost | evantest@%     |
+----+-----------+---------------------+--------------------+----------------+
2 rows in set (0.00 sec)

查看執行了那些操作:
解析binlog

# at 2895
#170620  9:17:35 server id 1  end_log_pos 2926 CRC32 0x45ce5d15 	Xid = 67
COMMIT/*!*/;
# at 2926
#170620  9:18:02 server id 1  end_log_pos 2991 CRC32 0x86520809 	Anonymous_GTID	last_committed=11	sequence_number=12
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 2991
#170620  9:18:02 server id 1  end_log_pos 3118 CRC32 0xf03899c0 	Query	thread_id=10	exec_time=0	error_code=0
use `testdemo`/*!*/;
SET TIMESTAMP=1497921482/*!*/;
create table testtable(id int comment 'test')
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file

這樣我們就可以通過線程ID + 時間鎖定對應的人在對應的時間做了那些事情。


免責聲明!

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



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