等保測評2.0:MySQL安全審計
一、說(shuō)明
本篇文章主要說(shuō)一說(shuō)MySQL數據庫安全審計控制點(diǎn)的相關(guān)內容和理解。
MySQL除了自身帶有的審計功能外,還存在著(zhù)一些其它的審計插件。
雖然遇到這些插件的概率不高,我還是把這些插件的基本參數都列出來(lái),到時(shí)候如果真遇到了,也不至于一頭霧水。
二、測評項
a)應啟用安全審計功能,審計覆蓋到每個(gè)用戶(hù),對重要的用戶(hù)行為和重要安全事件進(jìn)行審計;
b)審計記錄應包括事件的日期和時(shí)間、用戶(hù)、事件類(lèi)型、事件是否成功及其他與審計相關(guān)的信息;
c)應對審計記錄進(jìn)行保護,定期備份,避免受到未預期的刪除、修改或覆蓋等;
d)應對審計進(jìn)程進(jìn)行保護,防止未經(jīng)授權的中斷。
三、測評項a
a)應啟用安全審計功能,審計覆蓋到每個(gè)用戶(hù),對重要的用戶(hù)行為和重要安全事件進(jìn)行審計;
3.1. 自帶的審計功能
在MySQL中自帶了審計功能——general log,它會(huì )記錄所有關(guān)于mysql的sql語(yǔ)句(所以會(huì )給服務(wù)器和數據庫帶來(lái)很大的資源占用)。
不過(guò)僅僅從測評要求的角度來(lái)說(shuō),如果開(kāi)啟了general log,那么是符合測評項a的。
查詢(xún)的時(shí)候,可以使用log或者general關(guān)鍵詞,這里用的是general(不過(guò)用log要好一些):
show global variables like '%general%'
圖中的general_log變量的值為OFF,則表示沒(méi)有開(kāi)啟。
general_log_file則表示日志存儲在哪,圖中是存儲在一個(gè)文件中。
MySQL 5.1.6版開(kāi)始,可以將日志存儲在表當中,這個(gè)由log_output參數進(jìn)行控制,值為file,則代表存儲在文件中,為table,則代表存儲在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 // 審計信息存儲位置
log_timestamps = SYSTEM // 設置日志文件的輸出時(shí)間為地方時(shí)
修改my.cnf文件和設置global變量的區別在于,設置global變量,則數據庫重啟后設置就失效了。
而修改my.cnf文件,數據庫每次啟動(dòng)后,都會(huì )先去my.cnf讀取變量的值,再傳給相應的global變量。
下面其它變量也是如此。
另外要說(shuō)的一點(diǎn)是,變量general_log的類(lèi)型是bool,可以設置的值為OFF(或者0),以及ON(或者1),所以設置為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:指定日志輸出類(lèi)型,可為SYSLOG或FILE server_audit_logging:?jiǎn)?dòng)或關(guān)閉審計 server_audit_events:指定記錄事件的類(lèi)型,可以用逗號分隔的多個(gè)值(connect,query,table),如果開(kāi)啟了查詢(xún)緩存(query cache),查詢(xún)直接從查詢(xún)緩存返回數據,將沒(méi)有table記錄 server_audit_file_path:如server_audit_output_type為FILE,使用該變量設置存儲日志的文件,可以指定目錄,默認存放在數據目錄的server_audit.log文件中 server_audit_file_rotate_size:限制日志文件的大小 server_audit_file_rotations:指定日志文件的數量,如果為0日志將從不輪轉 server_audit_file_rotate_now:強制日志文件輪轉 server_audit_incl_users:指定哪些用戶(hù)的活動(dòng)將記錄,connect將不受此變量影響,該變量比server_audit_excl_users優(yōu)先級高 server_audit_syslog_facility:默認為L(cháng)OG_USER,指定facility server_audit_syslog_ident:設置ident,作為每個(gè)syslog記錄的一部分 server_audit_syslog_info:指定的info字符串將添加到syslog記錄 server_audit_syslog_priority:定義記錄日志的syslogd priority server_audit_excl_users:該列表的用戶(hù)行為將不記錄,connect將不受該設置影響
server_audit_mode:標識版本,用于開(kāi)發(fā)測試
這里我們比較關(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類(lèi)型,值為ON(1)以及OFF(0)。
server_audit_events:
記錄的事件,如果為空字符串,則代表記錄所有的事件。
CONNECT:連接、斷開(kāi)連接和失敗的連接,包括錯誤代碼
QUERY:以純文本形式執行的查詢(xún)及其結果,包括由于語(yǔ)法或權限錯誤而失敗的查詢(xún)
TABLE:受查詢(xún)執行影響的表
QUERY_DDL:與QUERY相同,但只篩選DDL類(lèi)型的查詢(xún)(create、alter、drop、rename和truncate語(yǔ)句,create/drop[procedure/function/user]和rename user除外(它們不是DDL)
QUERY_DML:與QUERY相同,但只篩選DML類(lèi)型的查詢(xún)(do、call、load data/xml、delete、insert、select、update、handler和replace語(yǔ)句)
QUERY_DCL:與QUERY相同,但只篩選DCL類(lèi)型的查詢(xún)(create user、drop user、rename user、grant、revoke和set password語(yǔ)句)
QUERY_DML_NO_SELECT:與QUERY_DML相同,但不記錄SELECT查詢(xún)。(從1.4.4版開(kāi)始)(do、call、load data/xml、delete、insert、update、handler和replace語(yǔ)句)
server_audit_file_path:
當server_audit_output_type為file時(shí),將路徑和文件名設置為日志文件。如果指定的路徑作為目錄存在,那么將在該目錄內創(chuàng )建名為“ server_audit.log”的日志。否則,該值將被視為文件名。默認值“ server_audit.log”,這意味著(zhù)將在數據庫目錄中創(chuàng )建此文件。
server_audit_file_rotate_size、server_audit_file_rotations、server_audit_file_rotate_now:
當server_audit_output_type為file時(shí),是否強制輪轉(server_audit_file_rotate_now),每個(gè)日志文件的最大大?。╯erver_audit_file_rotate_size),以及日志文件的最大數量(server_audit_file_rotations)。
更多變量的相關(guān)的解釋可以查看官方文檔:MariaDB Audit Plugin Options and System Variables
那么,從這個(gè)插件的功能來(lái)看,基本上默認配置就可以滿(mǎn)足測評項的要求。
3.3. MySQL Enterprise Audit Plugin
MySQL 企業(yè)版的 Enterprise Edition 中自帶 Audit Plugin ,名為 audit_log.so。
對于該插件,可以在my.cnf文件中加入以下參數啟用它:
[mysqld]
plugin-load=audit_log.so
也可以查詢(xún)插件,看到插件的狀態(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)系統變量為:
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:
不應記錄事件的帳戶(hù),除此之外的賬戶(hù)的事件都會(huì )被記錄。該值應為NULL或包含一個(gè)或多個(gè)用逗號分隔的帳戶(hù)名列表的字符串。
audit_log_file:
日志記錄的文件名,可以是相對路徑(相對于數據庫目錄)和完整路徑。
audit_log_format:
日志格式,可以是 OLD(舊樣式XML), NEW(新樣式XML,默認值)和(從MySQL 5.7.21開(kāi)始)JSON。
audit_log_include_accounts:
要包括在審核日志記錄中的帳戶(hù)。如果設置了此變量,則僅審核這些帳戶(hù)。
注意,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ì )執行自動(dòng)日志文件輪換。而是手動(dòng)使用audit_log_flush刷新日志文件。在這種情況下,請在刷新文件之前在服務(wù)器外部手動(dòng)重命名該文件(要不然原來(lái)的記錄就沒(méi)了)。
如果該 audit_log_rotate_on_size 值大于0,則會(huì )自動(dòng)進(jìn)行基于大小的日志文件輪換。每當寫(xiě)入日志文件導致其大小超過(guò)該 audit_log_rotate_on_size 值時(shí),審核日志插件都會(huì )關(guān)閉當前日志文件,將其重命名,然后打開(kāi)一個(gè)新的日志文件。
如果將此變量設置為不是4096的倍數的值,它將被截斷為最接近的倍數。(因此,將其設置為小于4096的效果是將其設置為0且不進(jìn)行旋轉,除非手動(dòng)進(jìn)行。)
audit_log_statement_policy:
應該被記錄的語(yǔ)句事件,在服務(wù)器啟動(dòng)的時(shí)候如果audit_log_statement_policy和audit_log_policy都顯示賦予了值,那么audit_log_statement_policy可能會(huì )被audit_log_policy覆蓋。
更多詳細的解釋請看官方文檔:MySQL Enterprise Audit
基本上默認配置也足夠滿(mǎn)足測評項要求了。
3.4. McAfee的libaudit_plugin
也是一個(gè)審核插件,其相關(guān)參數如下:
SHOW GLOBAL VARIABLES LIKE '%audi%';
audit_json_file #是否開(kāi)啟audit功能(ON\OFF)
audit_json_log_file #log日志名稱(chēng)及存儲位置,默認mysql的data目錄
audit_record_cmds='' #設置需要監控的SQL命令,默認全部(即該值為null)
audit_record_cmds='insert,delete,update,create,drop,alter,grant,truncate' #這是一些例子
audit_record_objs='' #設置需要監控的數據庫名稱(chēng)和表名,默認全部(即該值為null)
audit_record_objs=‘mysql.*’ #一個(gè)例子
audit_whitelist_users #用戶(hù)白名單
更多詳細解釋請查看官方文檔:McAfee的audit
基本上啟用后就滿(mǎn)足測評項要求了。
四、測評項b
b)審計記錄應包括事件的日期和時(shí)間、用戶(hù)、事件類(lèi)型、事件是否成功及其他與審計相關(guān)的信息;
只要啟用了審計功能,無(wú)論是自帶的審計還是插件,在記錄的信息上都能滿(mǎn)足這個(gè)要求。
4.1. 自帶的審計功能
其記錄內容如下:
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插件
其記錄內容如下:
日志的格式解釋可看官方文檔: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>
相似的格式介紹請查看官方文檔:審核日志文件格式
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')"
}
詳細的格式介紹請查看官方文檔:mysql-audit
五、測評項c
c)應對審計記錄進(jìn)行保護,定期備份,避免受到未預期的刪除、修改或覆蓋等;
5.1. 要求1
對審計記錄進(jìn)行保護,那么這里就不細說(shuō)了,說(shuō)一下大概的原則。
無(wú)論是自帶的審計還是審計插件,如果審核記錄存儲于文件中的,應該在操作系統上對這些日志文件的權限進(jìn)行限定,僅允許數據庫管理員可對這些文件進(jìn)行訪(fǎng)問(wèn)、修改等。同時(shí)也要限制MySQL中的file_priv權限。
如果審核記錄存儲于數據庫表中,那么也應該對數據庫的表進(jìn)行權限設置,僅數據庫管理員可對審核記錄表進(jìn)行訪(fǎng)問(wèn)、修改等。
5.2. 要求2
定期備份就不用多做什么說(shuō)明了,檢查備份文件和備份策略即可。
在這里有一個(gè)地方想探討下,在等級保護2.0試行稿中,對日志的留存時(shí)間有要求:
這里的法律法規要求一般來(lái)說(shuō)指的就是《網(wǎng)絡(luò )安全法》,其中有關(guān)日志留存時(shí)間的條款如下:
(三)采取監測、記錄網(wǎng)絡(luò )運行狀態(tài)、網(wǎng)絡(luò )安全事件的技術(shù)措施,并按照規定留存相關(guān)的網(wǎng)絡(luò )日志不少于六個(gè)月;
在等保正式2.0正式稿中,這個(gè)測評項被刪除了,那么《網(wǎng)絡(luò )安全法》對于日志留存時(shí)間(6個(gè)月)的要求是否落在了測評項c當中呢?
從基本要求來(lái)看,應該不是,其中沒(méi)有這個(gè)要求:
當然,既然網(wǎng)絡(luò )安全法這么規定了,等級保護肯定還是有測評項來(lái)實(shí)現該要求的,就是在安全管理中心的集中管控的測評項中:
按照我的個(gè)人理解,6個(gè)月的留存時(shí)間要求,應該是在集中管控的c測評項中去落實(shí)。
怎么測評呢?首先肯定要有相關(guān)的審計設備,也就是數據庫審計以及綜合日志審計設備,沒(méi)有這些設備,集中管控d測評項的第一個(gè)要求就沒(méi)法滿(mǎn)足。
然后在這些設備中,查看匯總的審計記錄留存時(shí)間是否滿(mǎn)足了法律法規的要求。
也就是,不需要跑去單個(gè)的設備上,查看每個(gè)設備的審計記錄是否滿(mǎn)足法律法規的要求。
否則,等級保護2.0正式稿中就不會(huì )將應確保審計記錄的留存時(shí)間符合法律法規要求挪到集中管控里面去了。
為什么說(shuō)到這個(gè)呢?因為我在初級教程里看到了關(guān)于留存時(shí)間的要求:
綜上所述,我個(gè)人覺(jué)得關(guān)于日志留存時(shí)間6個(gè)月的要求,應該再集中管控的d測評項中進(jìn)行統一描述,而不是在每個(gè)測評對象的安全審計的c測評項中進(jìn)行描述。
六、測評項d
d)應對審計進(jìn)程進(jìn)行保護,防止未經(jīng)授權的中斷。
這個(gè)就比較簡(jiǎn)單了,有兩個(gè)地方可以對審計進(jìn)程進(jìn)行配置。
一個(gè)是my.cnf,這里就需要操作系統上對配置文件的權限進(jìn)行限制,只允許數據庫管理有權限進(jìn)行修改。(同時(shí)也要限制MySQL中的file_priv權限。)
另外一個(gè)就是那些變量了,似乎是需要super權限才可以設置全局變量,那么這里的話(huà)就需要查看super權限給了哪些賬戶(hù)。