TXSQL企业级特性揭秘:加密与审计
前言:TXSQL是騰訊基礎(chǔ)架構(gòu)部數(shù)據(jù)庫團(tuán)隊(duì)自研的MySQL分支,對(duì)騰訊云以及眾多的內(nèi)部業(yè)務(wù)提供了強(qiáng)大的數(shù)據(jù)庫內(nèi)核支撐。相比原生的MySQL,TXSQL在BINLOG復(fù)制和InnoDB存儲(chǔ)引擎方面做了很多的優(yōu)化,另外在Server層面也做了大量的工作。因此TXSQL擁有更好的性能,更好的穩(wěn)定性和可維護(hù)性,以及更多的企業(yè)級(jí)特性。本文將對(duì)加密和審計(jì)這兩個(gè)企業(yè)級(jí)特性進(jìn)行詳細(xì)的解讀。
?
一、加密
?
這里的加密是指對(duì)存儲(chǔ)在磁盤上數(shù)據(jù)的進(jìn)行加密。對(duì)數(shù)據(jù)的通信進(jìn)行加密MySQL很早就開始支持了。數(shù)據(jù)的加密操作是可以脫離數(shù)據(jù)庫進(jìn)行的,比如用戶在插入一條數(shù)據(jù)時(shí),對(duì)該數(shù)據(jù)進(jìn)行加密;檢索數(shù)據(jù)時(shí),再對(duì)該數(shù)據(jù)進(jìn)行解密操作。這樣做存在兩個(gè)問題:其一,加密數(shù)據(jù)在數(shù)據(jù)庫中的查詢效率低下:加密數(shù)據(jù)在數(shù)據(jù)庫中很難進(jìn)行相似性(like)查詢,以及進(jìn)行范圍查詢。其二,加密密鑰的安全性問題由用戶保證:密鑰由用戶維護(hù)和管理,增加了安全的風(fēng)險(xiǎn)和維護(hù)的難度。
?
1.1 MySQL數(shù)據(jù)加密
MySQL在5.7版本推出數(shù)據(jù)加密功能:透明數(shù)據(jù)加密(Transparent Data Encryption)。透明加密是指數(shù)據(jù)的加解密操作對(duì)用戶透明。用戶在創(chuàng)建加密表時(shí),不用指定加密密鑰。數(shù)據(jù)在寫盤時(shí)加密,在讀盤時(shí)解密。目前透明數(shù)據(jù)加密只支持InnoDB存儲(chǔ)引擎。下面的語句創(chuàng)建了一個(gè)加密表:
CREATE TABLE t1 (c1 INT) ENGINE=InnoDBENCRYPTION='Y';
其中,ENCRYPTION='Y'表示對(duì)該表的數(shù)據(jù)進(jìn)行加密。那么數(shù)據(jù)是如何進(jìn)行加解密的呢?
?
1.1.1兩層密鑰體系
我們?cè)趧?chuàng)建加密表的時(shí)候,會(huì)自動(dòng)生成一個(gè)隨機(jī)的表空間密鑰(Tablespace Key)。數(shù)據(jù)由表空間密鑰保護(hù)。當(dāng)我們?cè)诩用鼙碇胁迦胍粭l記錄,記錄以明文插入到緩沖區(qū)(Buffer Pool)的數(shù)據(jù)頁中。當(dāng)數(shù)據(jù)頁要寫盤時(shí),通過表空間密鑰,對(duì)該頁上的所有數(shù)據(jù)記錄進(jìn)行加密后再寫盤。當(dāng)請(qǐng)求的數(shù)據(jù)頁不在緩沖區(qū)時(shí),數(shù)據(jù)頁從磁盤讀入,通過表空間密鑰,對(duì)數(shù)據(jù)頁中所有記錄進(jìn)行解密之后,加入到緩沖區(qū)中。一句話:數(shù)據(jù)頁在緩沖區(qū)中是明文,在磁盤上是密文。另外數(shù)據(jù)加密采用的加密算法是AES256。
?
表空間密鑰是如何保存的?MySQL有一個(gè)全局的主密鑰(Master Key), 主密鑰有對(duì)應(yīng)的ID(Master Key ID)。表空間密鑰由主密鑰保存。當(dāng)表空間密鑰生成后,通過主密鑰加密,寫入到表空間的第一個(gè)數(shù)據(jù)頁中,和加密后的表空間密鑰一同保存的還有主密鑰的ID。當(dāng)表空間第一次打開時(shí),讀取第一個(gè)數(shù)據(jù)頁,通過主密鑰ID,得到主密鑰;然后通過主密鑰對(duì)表空間密鑰進(jìn)行解密。
??
當(dāng)系統(tǒng)運(yùn)行之后,第一次創(chuàng)建加密表之前,全局的主密鑰為空。創(chuàng)建加密表時(shí),當(dāng)主密鑰為空,InnoDB會(huì)自動(dòng)生成一個(gè)主密鑰ID,由固定前綴加server uuid以及序號(hào)組成。通過主密鑰管理接口,為主密鑰ID生成一個(gè)對(duì)應(yīng)的主密鑰。
?
1.1.2 ?KEYRING密鑰管理框架
主密鑰的管理則是通過MySQL的KEYRING插件框架進(jìn)行的。主要有四個(gè)接口:?
l? my_key_fetch
my_bool
my_key_fetch(const char *key_id, const char **key_type, const char* user_id,
??????????? void **key, size_t *key_len);
l? my_key_generate
my_bool
my_key_generate(const char *key_id, const char *key_type,
??????????????? const char *user_id, size_t key_len);
l? my_key_remove
l? my_key_store
?
我們可以把KEYRING框架理解為一個(gè)簡單的Key-Value的store。上述InnoDB內(nèi)部生成主密鑰的過程是通過調(diào)用my_key_generate和my_key_fetch完成。
?
MySQL社區(qū)版本提供KEYRING插件的一個(gè)簡單的文件實(shí)現(xiàn):KEYRING_FILE。密鑰保存在文件中,通常叫keyring_file。這種實(shí)現(xiàn)方式非常不安全。當(dāng)加密的表空間文件和keyring_file一同被拷貝出去,那么加密的表空間文件是可以正常讀取的。
?
MySQL商業(yè)版提供KEYRING插件的另外一種實(shí)現(xiàn):KEYRING_OKV。密鑰保存在ORACLE Key Vault中,確保密鑰的安全性。
?
1.2 ?TXSQL數(shù)據(jù)加密
在TXSQL中,我們沿用MySQL的透明加密體系,提供 KEYRING插件的另外一種實(shí)現(xiàn):KEYRING_KMS。將KEYRING與企業(yè)級(jí)的KMS(Key Management Service) 集成。
?
KMS是騰訊云一項(xiàng)保護(hù)數(shù)據(jù)及密鑰安全的密鑰服務(wù)。服務(wù)涉及的各個(gè)流程均采用高安全性協(xié)議通信,保證服務(wù)高安全;提供分布式集群管理和熱備份,保證服務(wù)高可靠和高可用。KMS也采用的是兩層密鑰體系。KMS涉及兩類密鑰,即用戶主密鑰(CMK)與數(shù)據(jù)密鑰(Datakey)。用戶主密鑰用于加密數(shù)據(jù)密鑰或密碼、證書、配置文件等小包數(shù)據(jù)(最多 4KB)。數(shù)據(jù)密鑰用于加密業(yè)務(wù)數(shù)據(jù)。海量的業(yè)務(wù)數(shù)據(jù)在存儲(chǔ)或通信過程中使用數(shù)據(jù)密鑰以對(duì)稱加密的方式加密,而數(shù)據(jù)密鑰又通過用戶主密鑰采用非對(duì)稱加密方式加密保護(hù)。
?
通過API調(diào)用KMS接口時(shí),首先創(chuàng)建用戶主密鑰;然后創(chuàng)建數(shù)據(jù)密鑰。CMK的個(gè)數(shù)限制為128,而數(shù)據(jù)密鑰則無此限制。在KEYRING_KMS實(shí)現(xiàn)上,MySQL的主密鑰和KMS的數(shù)據(jù)密鑰對(duì)應(yīng)。由于KMS接口的限制和實(shí)際需要,我們只實(shí)現(xiàn)了KEYRING的兩個(gè)接口:my_key_generate和my_key_fetch。
?
我們依然保留MySQL兩層密鑰體系,我們只是用KMS來實(shí)現(xiàn)了主密鑰的管理,但沒有使用KMS來進(jìn)行數(shù)據(jù)的加密。主要考慮有兩點(diǎn):一是系統(tǒng)可用性方面的考慮,比如萬一KMS短時(shí)不可用,那么加密數(shù)據(jù)將無法訪問;二是系統(tǒng)性能方面的考慮,所有數(shù)據(jù)的加解密都通過KMS,加解密效率和網(wǎng)絡(luò)開銷無疑對(duì)系統(tǒng)影響巨大
?
1.2.1 Key Generate
在KEYRING_KMS中,我們同樣有一個(gè)本地文件,用來存儲(chǔ)密鑰ID和加密后的數(shù)據(jù)密鑰。這個(gè)加密后的數(shù)據(jù)密鑰是由KMS返回,所以解密這個(gè)數(shù)據(jù)密鑰也需要通過KMS來做。在下圖的流程中,我們通過固定的CMK別名(alias)來獲取或創(chuàng)建CMK,然后產(chǎn)生數(shù)據(jù)密鑰,將加密后的數(shù)據(jù)密鑰保存在本地文件中。
?
1.2.2 ?Key Fetch
獲取密鑰首先根據(jù)密鑰ID從文件中讀取加密后的數(shù)據(jù)密鑰,再通過KMS對(duì)數(shù)據(jù)密鑰進(jìn)行解密,獲取密鑰明文。KMS進(jìn)行解密時(shí),只需要提供密文,不要需要其他信息。獲取密鑰明文成功之后,我們對(duì)密鑰明文進(jìn)行了緩存,減少對(duì)KMS的訪問。
1.2.3 ?基于角色的訪問控制
在用戶開啟加密功能時(shí),在CAM中,為用戶創(chuàng)建了一個(gè)可以訪問KMS的角色(role),并將此角色的權(quán)限授予指定的控制臺(tái)用戶。我們通過訪問CAM獲取臨時(shí)證書(secret key, secret id,token),通過臨時(shí)證書來訪問KMS。其中CAM是騰訊云提供的訪問控制服務(wù)。
?
如果不采用角色訪問控制,在開啟加密的時(shí)候,需要用戶提供自己的證書。其一,用戶體驗(yàn)差,其二,用戶證書的安全性差。
?
還有一點(diǎn)值得注意:InnoDB中使用的主密鑰是可以輪換的。通過如下語句進(jìn)行輪換:
ALTER INSTANCE ROTATE INNODB MASTER KEY;
主密鑰的輪換過程:
1. ?產(chǎn)生新的主密鑰ID;
2. ?獲取新的主密鑰(keygenerate);
3. ?對(duì)所有加密表空間,執(zhí)行步驟4,5
4. ?對(duì)加密的表空間,用舊的主密鑰解密表空間密鑰;
5. ?用新的主密鑰加密表空間密鑰。
主密鑰的輪換,進(jìn)一步提高了系統(tǒng)的安全性。
?
通過以上介紹,我們可以看到,TXSQL透明數(shù)據(jù)加密,將KMS和CAM有機(jī)的結(jié)合在一起,對(duì)訪問控制,密鑰管理和數(shù)據(jù)加密等各個(gè)環(huán)節(jié)進(jìn)行嚴(yán)格把控,為用戶在騰訊云上提供了一個(gè)完整、安全、可靠的數(shù)據(jù)加密解決方案。
二、審計(jì)
數(shù)據(jù)庫審計(jì)也是數(shù)據(jù)庫安全的重要一環(huán)。所謂審計(jì),就是對(duì)用戶在數(shù)據(jù)庫中的操作和行為進(jìn)行記錄,基于這些記錄,可以進(jìn)行審查分析。我們可以通過審計(jì)記錄來對(duì)一個(gè)非法操作進(jìn)行追查;對(duì)數(shù)據(jù)庫性能和運(yùn)行狀態(tài)進(jìn)行(也可以通過系統(tǒng)監(jiān)控獲得);可以對(duì)用戶的訪問模式進(jìn)行跟蹤建模等等。這些事后的分析可以幫助我們發(fā)現(xiàn)數(shù)據(jù)庫運(yùn)行過程中的風(fēng)險(xiǎn),發(fā)出告警,以及采取必要的干預(yù)措施。
?
2.1 MySQL審計(jì)
MySQL同樣提供了一個(gè)審計(jì)插件(AuditPlugin)框架。在框架內(nèi)部主要處理函數(shù)為:
int (*event_notify)(MYSQL_THD, mysql_event_class_t, const void *);
?
在Server層面,從系統(tǒng)啟動(dòng),用戶登錄,到SQL執(zhí)行的各個(gè)節(jié)點(diǎn),以事件的方式,通知審計(jì)插件進(jìn)行記錄。以下是事件類型的例子:
MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE
?MYSQL_AUDIT_CONNECTION_CONNECT
?MYSQL_AUDIT_CONNECTION_DISCONNECT
?MYSQL_AUDIT_CONNECTION_DISCONNECT
?MYSQL_AUDIT_COMMAND_START
?MYSQL_AUDIT_COMMAND_END
MySQL社區(qū)版只提供審計(jì)插件的范例,而在MySQL商業(yè)版中提供企業(yè)級(jí)審計(jì)功能。
?
2.2 TXSQL審計(jì)
TXSQL的重要用戶有對(duì)審計(jì)功能的迫切需求:用戶需要對(duì)數(shù)據(jù)庫操作進(jìn)行事后的跟蹤和分析。我們利用審計(jì)插件框架,綜合考慮功能和性能,提供了一套全新的審計(jì)解決方案。
?
2.2.1 審計(jì)架構(gòu)
我們整個(gè)審計(jì)框架的示意圖
?
用戶連接(session)產(chǎn)生的審計(jì)記錄被寫入到一片固定的內(nèi)存中;專門的寫盤線程(Flush Thread)將內(nèi)存中的審計(jì)記錄寫入到審計(jì)文件中(Audit File);審計(jì)代理(Audit Agent)則讀取審計(jì)文件,將審計(jì)記錄發(fā)送到審計(jì)日志中心:CTSDB集群進(jìn)行集中存儲(chǔ)。其中,一個(gè)TXSQL實(shí)例對(duì)應(yīng)一個(gè)寫盤線程,一個(gè)審計(jì)代理服務(wù)多個(gè)TXSQL實(shí)例,一臺(tái)物理機(jī)上只有一個(gè)審計(jì)代理。
?
CTSDB是騰訊基礎(chǔ)架構(gòu)部數(shù)據(jù)庫團(tuán)隊(duì)研發(fā)的時(shí)間序列數(shù)據(jù)庫(目前可以在騰訊云上申請(qǐng)?jiān)囉?。審計(jì)數(shù)據(jù)又恰好是時(shí)間序列數(shù)據(jù)。選擇CTSDB來存儲(chǔ)審計(jì)數(shù)據(jù)帶來的好處有:其一數(shù)據(jù)壓縮率高;其二數(shù)據(jù)吞吐量大;其三數(shù)據(jù)分析能力強(qiáng)。完全滿足我們?cè)诟邏毫η闆r下,對(duì)審計(jì)數(shù)據(jù)的處理和分析能力。
?
2.2.2 審計(jì)日志格式
我們采用json格式對(duì)審計(jì)日志傳輸。記錄的內(nèi)容有時(shí)間戳,影響的行數(shù),執(zhí)行的時(shí)間,錯(cuò)誤碼,規(guī)則號(hào),主機(jī),實(shí)例名,用戶名,數(shù)據(jù)庫名,過濾策略名,SQL語句,以及SQL類型等。
?
2.2.3 審計(jì)過濾規(guī)則
考慮到審計(jì)日志量巨大,提供過濾規(guī)則就很必要。我們提供如下過濾規(guī)則
1. ?主機(jī)IP,用戶名,數(shù)據(jù)庫名,表名可以使用“include, exclude, =, <>, regex”進(jìn)行過濾;
2. ?SQL語句可以使用“include,exclude, regex”進(jìn)行過濾;
3. ?SQL類型可以使用“=,<>”進(jìn)行過濾;
4. ?影響函數(shù)和之行時(shí)間可以使用“>, <, >=, <=, =”進(jìn)行過濾。
?
2.2.4 審計(jì)性能
為了減少審計(jì)帶來的性能損失,我們只對(duì)命令執(zhí)行完之后的結(jié)果進(jìn)行審計(jì)。這樣就省去了很大一部分的審計(jì)日志。根據(jù)我們的測試,打開審計(jì)并進(jìn)行全量審計(jì)(Audit all)時(shí),系統(tǒng)性能損失9%;打開審計(jì)并且不進(jìn)行審計(jì)(Audit null)時(shí),性能損失約為3%。
?
三、小結(jié)
TXSQL在實(shí)現(xiàn)加密和審計(jì)這兩個(gè)企業(yè)級(jí)特性,是對(duì)用戶需求的積極響應(yīng)。在實(shí)現(xiàn)上,也充分結(jié)合與騰訊云內(nèi)其他平臺(tái)進(jìn)行結(jié)合,提供一站式的解決方案。為了給用戶提供性能更好,功能更強(qiáng),可用性更高的數(shù)據(jù)庫服務(wù),TXSQL一直在努力。另外,TXSQL?關(guān)于加密和審計(jì)的開源工作也在進(jìn)行著中,已經(jīng)初步和?MariaDB?達(dá)成了相關(guān)合作,在不久的將來里,這兩個(gè)企業(yè)級(jí)的功能就能與大家在開源版本中見面。
總結(jié)
以上是生活随笔為你收集整理的TXSQL企业级特性揭秘:加密与审计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯副总裁姚星:腾讯AI Lab将致力打
- 下一篇: 贺TDSQL喜提286万QPS!本文回顾