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 + 時間鎖定對應的人在對應的時間做了那些事情。