等保測(cè)評(píng)2.0:MySQL安全審計(jì)
一、說(shuō)明
本篇文章主要說(shuō)一說(shuō)MySQL數(shù)據(jù)庫(kù)安全審計(jì)控制點(diǎn)的相關(guān)內(nèi)容和理解。
MySQL除了自身帶有的審計(jì)功能外,還存在著一些其它的審計(jì)插件。
雖然遇到這些插件的概率不高,我還是把這些插件的基本參數(shù)都列出來(lái),到時(shí)候如果真遇到了,也不至于一頭霧水。
二、測(cè)評(píng)項(xiàng)
a)應(yīng)啟用安全審計(jì)功能,審計(jì)覆蓋到每個(gè)用戶,對(duì)重要的用戶行為和重要安全事件進(jìn)行審計(jì);
b)審計(jì)記錄應(yīng)包括事件的日期和時(shí)間、用戶、事件類型、事件是否成功及其他與審計(jì)相關(guān)的信息;
c)應(yīng)對(duì)審計(jì)記錄進(jìn)行保護(hù),定期備份,避免受到未預(yù)期的刪除、修改或覆蓋等;
d)應(yīng)對(duì)審計(jì)進(jìn)程進(jìn)行保護(hù),防止未經(jīng)授權(quán)的中斷。
三、測(cè)評(píng)項(xiàng)a
a)應(yīng)啟用安全審計(jì)功能,審計(jì)覆蓋到每個(gè)用戶,對(duì)重要的用戶行為和重要安全事件進(jìn)行審計(jì);
3.1. 自帶的審計(jì)功能
在MySQL中自帶了審計(jì)功能——general log,它會(huì)記錄所有關(guān)于mysql的sql語(yǔ)句(所以會(huì)給服務(wù)器和數(shù)據(jù)庫(kù)帶來(lái)很大的資源占用)。
不過(guò)僅僅從測(cè)評(píng)要求的角度來(lái)說(shuō),如果開(kāi)啟了general log,那么是符合測(cè)評(píng)項(xiàng)a的。
查詢的時(shí)候,可以使用log或者general關(guān)鍵詞,這里用的是general(不過(guò)用log要好一些):
show global variables like '%general%'
圖中的general_log變量的值為OFF,則表示沒(méi)有開(kāi)啟。
general_log_file則表示日志存儲(chǔ)在哪,圖中是存儲(chǔ)在一個(gè)文件中。
MySQL 5.1.6版開(kāi)始,可以將日志存儲(chǔ)在表當(dāng)中,這個(gè)由log_output參數(shù)進(jìn)行控制,值為file,則代表存儲(chǔ)在文件中,為table,則代表存儲(chǔ)在gengera_log表中。
mysql> show variables like 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output | TABLE |
+---------------+-------+
mysql> select * from general_log;
| 2018-07-17 23:00:12 | root[root] @ localhost [] | 2 | 1132333306 | Query | select * from test.student3
也可以去看一看/etc/my.cnf文件,查看是否啟用了general_log:
[mysqld]
general_log = on // on為開(kāi)啟;off為關(guān)閉
general_log_file = /var/log/generalLog.log // 審計(jì)信息存儲(chǔ)位置
log_timestamps = SYSTEM // 設(shè)置日志文件的輸出時(shí)間為地方時(shí)
修改my.cnf文件和設(shè)置global變量的區(qū)別在于,設(shè)置global變量,則數(shù)據(jù)庫(kù)重啟后設(shè)置就失效了。
而修改my.cnf文件,數(shù)據(jù)庫(kù)每次啟動(dòng)后,都會(huì)先去my.cnf讀取變量的值,再傳給相應(yīng)的global變量。
下面其它變量也是如此。
另外要說(shuō)的一點(diǎn)是,變量general_log的類型是bool,可以設(shè)置的值為OFF(或者0),以及ON(或者1),所以設(shè)置為ON和1是一個(gè)意思。
3.2. MariaDB的Audit Plugin插件
該插件可以用于MySQL的一些版本上,比如MySQL 5.7.18。
該插件的相關(guān)變量為:
SHOW GLOBAL VARIABLES LIKE 'server_audit%';
+-------------------------------+-----------------------+
| Variable_name | Value |
+-------------------------------+-----------------------+
| server_audit_events | CONNECT,QUERY,TABLE |
| server_audit_excl_users | |
| server_audit_file_path | server_audit.log |
| server_audit_file_rotate_now | OFF |
| server_audit_file_rotate_size | 1000000 |
| server_audit_file_rotations | 9 |
| server_audit_incl_users | |
| server_audit_logging | ON |
| server_audit_mode | 0 |
| server_audit_output_type | file |
| server_audit_query_log_limit | 1024 |
| server_audit_syslog_facility | LOG_USER |
| server_audit_syslog_ident | mysql-server_auditing |
| server_audit_syslog_info | |
| server_audit_syslog_priority | LOG_INFO |
+-------------------------------+-----------------------+
解釋如下:
server_audit_output_type:指定日志輸出類型,可為SYSLOG或FILE server_audit_logging:?jiǎn)?dòng)或關(guān)閉審計(jì) server_audit_events:指定記錄事件的類型,可以用逗號(hào)分隔的多個(gè)值(connect,query,table),如果開(kāi)啟了查詢緩存(query cache),查詢直接從查詢緩存返回?cái)?shù)據(jù),將沒(méi)有table記錄 server_audit_file_path:如server_audit_output_type為FILE,使用該變量設(shè)置存儲(chǔ)日志的文件,可以指定目錄,默認(rèn)存放在數(shù)據(jù)目錄的server_audit.log文件中 server_audit_file_rotate_size:限制日志文件的大小 server_audit_file_rotations:指定日志文件的數(shù)量,如果為0日志將從不輪轉(zhuǎn) server_audit_file_rotate_now:強(qiáng)制日志文件輪轉(zhuǎn) server_audit_incl_users:指定哪些用戶的活動(dòng)將記錄,connect將不受此變量影響,該變量比server_audit_excl_users優(yōu)先級(jí)高 server_audit_syslog_facility:默認(rèn)為L(zhǎng)OG_USER,指定facility server_audit_syslog_ident:設(shè)置ident,作為每個(gè)syslog記錄的一部分 server_audit_syslog_info:指定的info字符串將添加到syslog記錄 server_audit_syslog_priority:定義記錄日志的syslogd priority server_audit_excl_users:該列表的用戶行為將不記錄,connect將不受該設(shè)置影響
server_audit_mode:標(biāo)識(shí)版本,用于開(kāi)發(fā)測(cè)試
這里我們比較關(guān)注的是server_audit_logging、server_audit_events、server_audit_output_type、server_audit_file_path、server_audit_file_rotate_size、server_audit_file_rotations、server_audit_file_rotate_now。
server_audit_logging:
即為是否開(kāi)啟,bool類型,值為ON(1)以及OFF(0)。
server_audit_events:
記錄的事件,如果為空字符串,則代表記錄所有的事件。
CONNECT:連接、斷開(kāi)連接和失敗的連接,包括錯(cuò)誤代碼
QUERY:以純文本形式執(zhí)行的查詢及其結(jié)果,包括由于語(yǔ)法或權(quán)限錯(cuò)誤而失敗的查詢
TABLE:受查詢執(zhí)行影響的表
QUERY_DDL:與QUERY相同,但只篩選DDL類型的查詢(create、alter、drop、rename和truncate語(yǔ)句,create/drop[procedure/function/user]和rename user除外(它們不是DDL)
QUERY_DML:與QUERY相同,但只篩選DML類型的查詢(do、call、load data/xml、delete、insert、select、update、handler和replace語(yǔ)句)
QUERY_DCL:與QUERY相同,但只篩選DCL類型的查詢(create user、drop user、rename user、grant、revoke和set password語(yǔ)句)
QUERY_DML_NO_SELECT:與QUERY_DML相同,但不記錄SELECT查詢。(從1.4.4版開(kāi)始)(do、call、load data/xml、delete、insert、update、handler和replace語(yǔ)句)
server_audit_file_path:
當(dāng)server_audit_output_type為file時(shí),將路徑和文件名設(shè)置為日志文件。如果指定的路徑作為目錄存在,那么將在該目錄內(nèi)創(chuàng)建名為“ server_audit.log”的日志。否則,該值將被視為文件名。默認(rèn)值“ server_audit.log”,這意味著將在數(shù)據(jù)庫(kù)目錄中創(chuàng)建此文件。
server_audit_file_rotate_size、server_audit_file_rotations、server_audit_file_rotate_now:
當(dāng)server_audit_output_type為file時(shí),是否強(qiáng)制輪轉(zhuǎn)(server_audit_file_rotate_now),每個(gè)日志文件的最大大?。╯erver_audit_file_rotate_size),以及日志文件的最大數(shù)量(server_audit_file_rotations)。
更多變量的相關(guān)的解釋可以查看官方文檔:MariaDB Audit Plugin Options and System Variables
那么,從這個(gè)插件的功能來(lái)看,基本上默認(rèn)配置就可以滿足測(cè)評(píng)項(xiàng)的要求。
3.3. MySQL Enterprise Audit Plugin
MySQL 企業(yè)版的 Enterprise Edition 中自帶 Audit Plugin ,名為 audit_log.so。
對(duì)于該插件,可以在my.cnf文件中加入以下參數(shù)啟用它:
[mysqld]
plugin-load=audit_log.so
也可以查詢插件,看到插件的狀態(tài):
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE 'audit%';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| audit_log | ACTIVE |
+-------------+---------------+
該插件的相關(guān)系統(tǒng)變量為:
mysql> SHOW VARIABLES LIKE 'audit_log%';
+-----------------------------+--------------+
| Variable_name | Value |
+-----------------------------+--------------+
| audit_log_buffer_size | 1048576 |
| audit_log_connection_policy | ALL |
| audit_log_current_session | OFF |
| audit_log_exclude_accounts | |
| audit_log_file | audit.log |
| audit_log_filter_id | 0 |
| audit_log_flush | OFF |
| audit_log_format | NEW |
| audit_log_include_accounts | |
| audit_log_policy | ALL |
| audit_log_rotate_on_size | 0 |
| audit_log_statement_policy | ALL |
| audit_log_strategy | ASYNCHRONOUS |
+-----------------------------+--------------+
audit_log_connection_policy:
控制審核日志插件如何將連接事件寫(xiě)入其日志文件的策略
audit_log_exclude_accounts:
不應(yīng)記錄事件的帳戶,除此之外的賬戶的事件都會(huì)被記錄。該值應(yīng)為NULL或包含一個(gè)或多個(gè)用逗號(hào)分隔的帳戶名列表的字符串。
audit_log_file:
日志記錄的文件名,可以是相對(duì)路徑(相對(duì)于數(shù)據(jù)庫(kù)目錄)和完整路徑。
audit_log_format:
日志格式,可以是 OLD(舊樣式XML), NEW(新樣式XML,默認(rèn)值)和(從MySQL 5.7.21開(kāi)始)JSON。
audit_log_include_accounts:
要包括在審核日志記錄中的帳戶。如果設(shè)置了此變量,則僅審核這些帳戶。
注意,audit_log_exclude_accounts與audit_log_include_accounts是互斥的,它們之間只有一個(gè)的值為非null,不能同時(shí)為非null。
audit_log_policy:
事件記錄策略
audit_log_rotate_on_size:
如果 audit_log_rotate_on_size 值為0,則審核日志插件不會(huì)執(zhí)行自動(dòng)日志文件輪換。而是手動(dòng)使用audit_log_flush刷新日志文件。在這種情況下,請(qǐng)?jiān)谒⑿挛募霸诜?wù)器外部手動(dòng)重命名該文件(要不然原來(lái)的記錄就沒(méi)了)。
如果該 audit_log_rotate_on_size 值大于0,則會(huì)自動(dòng)進(jìn)行基于大小的日志文件輪換。每當(dāng)寫(xiě)入日志文件導(dǎo)致其大小超過(guò)該 audit_log_rotate_on_size 值時(shí),審核日志插件都會(huì)關(guān)閉當(dāng)前日志文件,將其重命名,然后打開(kāi)一個(gè)新的日志文件。
如果將此變量設(shè)置為不是4096的倍數(shù)的值,它將被截?cái)酁樽罱咏谋稊?shù)。(因此,將其設(shè)置為小于4096的效果是將其設(shè)置為0且不進(jìn)行旋轉(zhuǎn),除非手動(dòng)進(jìn)行。)
audit_log_statement_policy:
應(yīng)該被記錄的語(yǔ)句事件,在服務(wù)器啟動(dòng)的時(shí)候如果audit_log_statement_policy和audit_log_policy都顯示賦予了值,那么audit_log_statement_policy可能會(huì)被audit_log_policy覆蓋。
更多詳細(xì)的解釋請(qǐng)看官方文檔:MySQL Enterprise Audit
基本上默認(rèn)配置也足夠滿足測(cè)評(píng)項(xiàng)要求了。
3.4. McAfee的libaudit_plugin
也是一個(gè)審核插件,其相關(guān)參數(shù)如下:
SHOW GLOBAL VARIABLES LIKE '%audi%';
audit_json_file #是否開(kāi)啟audit功能(ON\OFF)
audit_json_log_file #log日志名稱及存儲(chǔ)位置,默認(rèn)mysql的data目錄
audit_record_cmds='' #設(shè)置需要監(jiān)控的SQL命令,默認(rèn)全部(即該值為null)
audit_record_cmds='insert,delete,update,create,drop,alter,grant,truncate' #這是一些例子
audit_record_objs='' #設(shè)置需要監(jiān)控的數(shù)據(jù)庫(kù)名稱和表名,默認(rèn)全部(即該值為null)
audit_record_objs=‘mysql.*’ #一個(gè)例子
audit_whitelist_users #用戶白名單
更多詳細(xì)解釋請(qǐng)查看官方文檔:McAfee的audit
基本上啟用后就滿足測(cè)評(píng)項(xiàng)要求了。
四、測(cè)評(píng)項(xiàng)b
b)審計(jì)記錄應(yīng)包括事件的日期和時(shí)間、用戶、事件類型、事件是否成功及其他與審計(jì)相關(guān)的信息;
只要啟用了審計(jì)功能,無(wú)論是自帶的審計(jì)還是插件,在記錄的信息上都能滿足這個(gè)要求。
4.1. 自帶的審計(jì)功能
其記錄內(nèi)容如下:
mysql> select * from general_log;
| 2018-07-17 23:00:12 | root[root] @ localhost [] | 2 | 1132333306 | Query | select * from test.student3
4.2. MariaDB的Audit Plugin插件
其記錄內(nèi)容如下:
日志的格式解釋可看官方文檔:MariaDB Audit Plugin – Log Format
4.3. MySQL Enterprise Audit Plugin
該插件的日志文件可以是XML或者JSON格式,以XML為例:
<AUDIT_RECORD>
<TIMESTAMP>2019-10-03T14:09:38 UTC</TIMESTAMP>
<RECORD_ID>6_2019-10-03T14:06:33</RECORD_ID>
<NAME>Query</NAME>
<CONNECTION_ID>5</CONNECTION_ID>
<STATUS>0</STATUS>
<STATUS_CODE>0</STATUS_CODE>
<USER>root[root] @ localhost [127.0.0.1]</USER>
<OS_LOGIN/>
<HOST>localhost</HOST>
<IP>127.0.0.1</IP>
<COMMAND_CLASS>drop_table</COMMAND_CLASS>
<SQLTEXT>DROP TABLE IF EXISTS t</SQLTEXT>
</AUDIT_RECORD>
相似的格式介紹請(qǐng)查看官方文檔:審核日志文件格式
4.4. McAfee的libaudit_plugin
該插件日志文件的格式是json:
{
"msg-type": "activity",
"date": "1510038432019",
"thread-id": "43",
"query-id": "1891",
"user": "root",
"priv_user": "root",
"ip": "",
"host": "localhost",
"connect_attrs": {
"_os": "linux-glibc2.5",
"_client_name": "libmysql",
"_pid": "4009",
"_client_version": "5.7.9",
"_platform": "x86_64",
"program_name": "mysql"
},
"pid": "4009",
"os_user": "root",
"appname": "mysql",
"rows": "1",
"cmd": "insert",
"objects": [
{
"db": "part",
"name": "e",
"obj_type": "TABLE"
}
],
"query": "insert into e values (9898,'smart','james')"
}
詳細(xì)的格式介紹請(qǐng)查看官方文檔:mysql-audit
五、測(cè)評(píng)項(xiàng)c
c)應(yīng)對(duì)審計(jì)記錄進(jìn)行保護(hù),定期備份,避免受到未預(yù)期的刪除、修改或覆蓋等;
5.1. 要求1
對(duì)審計(jì)記錄進(jìn)行保護(hù),那么這里就不細(xì)說(shuō)了,說(shuō)一下大概的原則。
無(wú)論是自帶的審計(jì)還是審計(jì)插件,如果審核記錄存儲(chǔ)于文件中的,應(yīng)該在操作系統(tǒng)上對(duì)這些日志文件的權(quán)限進(jìn)行限定,僅允許數(shù)據(jù)庫(kù)管理員可對(duì)這些文件進(jìn)行訪問(wèn)、修改等。同時(shí)也要限制MySQL中的file_priv權(quán)限。
如果審核記錄存儲(chǔ)于數(shù)據(jù)庫(kù)表中,那么也應(yīng)該對(duì)數(shù)據(jù)庫(kù)的表進(jìn)行權(quán)限設(shè)置,僅數(shù)據(jù)庫(kù)管理員可對(duì)審核記錄表進(jìn)行訪問(wèn)、修改等。
5.2. 要求2
定期備份就不用多做什么說(shuō)明了,檢查備份文件和備份策略即可。
在這里有一個(gè)地方想探討下,在等級(jí)保護(hù)2.0試行稿中,對(duì)日志的留存時(shí)間有要求:
這里的法律法規(guī)要求一般來(lái)說(shuō)指的就是《網(wǎng)絡(luò)安全法》,其中有關(guān)日志留存時(shí)間的條款如下:
(三)采取監(jiān)測(cè)、記錄網(wǎng)絡(luò)運(yùn)行狀態(tài)、網(wǎng)絡(luò)安全事件的技術(shù)措施,并按照規(guī)定留存相關(guān)的網(wǎng)絡(luò)日志不少于六個(gè)月;
在等保正式2.0正式稿中,這個(gè)測(cè)評(píng)項(xiàng)被刪除了,那么《網(wǎng)絡(luò)安全法》對(duì)于日志留存時(shí)間(6個(gè)月)的要求是否落在了測(cè)評(píng)項(xiàng)c當(dāng)中呢?
從基本要求來(lái)看,應(yīng)該不是,其中沒(méi)有這個(gè)要求:
當(dāng)然,既然網(wǎng)絡(luò)安全法這么規(guī)定了,等級(jí)保護(hù)肯定還是有測(cè)評(píng)項(xiàng)來(lái)實(shí)現(xiàn)該要求的,就是在安全管理中心的集中管控的測(cè)評(píng)項(xiàng)中:
按照我的個(gè)人理解,6個(gè)月的留存時(shí)間要求,應(yīng)該是在集中管控的c測(cè)評(píng)項(xiàng)中去落實(shí)。
怎么測(cè)評(píng)呢?首先肯定要有相關(guān)的審計(jì)設(shè)備,也就是數(shù)據(jù)庫(kù)審計(jì)以及綜合日志審計(jì)設(shè)備,沒(méi)有這些設(shè)備,集中管控d測(cè)評(píng)項(xiàng)的第一個(gè)要求就沒(méi)法滿足。
然后在這些設(shè)備中,查看匯總的審計(jì)記錄留存時(shí)間是否滿足了法律法規(guī)的要求。
也就是,不需要跑去單個(gè)的設(shè)備上,查看每個(gè)設(shè)備的審計(jì)記錄是否滿足法律法規(guī)的要求。
否則,等級(jí)保護(hù)2.0正式稿中就不會(huì)將應(yīng)確保審計(jì)記錄的留存時(shí)間符合法律法規(guī)要求挪到集中管控里面去了。
為什么說(shuō)到這個(gè)呢?因?yàn)槲以诔跫?jí)教程里看到了關(guān)于留存時(shí)間的要求:
綜上所述,我個(gè)人覺(jué)得關(guān)于日志留存時(shí)間6個(gè)月的要求,應(yīng)該再集中管控的d測(cè)評(píng)項(xiàng)中進(jìn)行統(tǒng)一描述,而不是在每個(gè)測(cè)評(píng)對(duì)象的安全審計(jì)的c測(cè)評(píng)項(xiàng)中進(jìn)行描述。
六、測(cè)評(píng)項(xiàng)d
d)應(yīng)對(duì)審計(jì)進(jìn)程進(jìn)行保護(hù),防止未經(jīng)授權(quán)的中斷。
這個(gè)就比較簡(jiǎn)單了,有兩個(gè)地方可以對(duì)審計(jì)進(jìn)程進(jìn)行配置。
一個(gè)是my.cnf,這里就需要操作系統(tǒng)上對(duì)配置文件的權(quán)限進(jìn)行限制,只允許數(shù)據(jù)庫(kù)管理有權(quán)限進(jìn)行修改。(同時(shí)也要限制MySQL中的file_priv權(quán)限。)
另外一個(gè)就是那些變量了,似乎是需要super權(quán)限才可以設(shè)置全局變量,那么這里的話就需要查看super權(quán)限給了哪些賬戶。