如何理解MySQL的SSL連接
1. 概述
不僅僅是https站點(diǎn),ssl連接在各個(gè)方面都慢慢流行起來了,像mysql5.7以后默認(rèn)就開啟了ssl連接,這篇文章主要介紹下mysql在ssl加密連接的情況下發(fā)生了哪些事情和怎么來解密ssl加密的mysql流量,以及一些對(duì)ssl連接的疑問解答。
2. 服務(wù)端配置
1. mysql進(jìn)行ssl配置時(shí)候,需要一個(gè)CA和CA用服務(wù)端的key頒發(fā)給服務(wù)端的證書,分別是ssl_ca ssl_key ssl_cert 這三個(gè)參數(shù)值。 也就是show variables like ‘%ssl%’;看到的結(jié)果,詳情略。
2. 進(jìn)行用戶配置,在grant授權(quán)時(shí)候需要在最后加上require X509;值。
3. 制作證書:
一般我們的CA是本機(jī),然后進(jìn)行自頒發(fā)證書,比如以前講到過的教程,CA簡(jiǎn)單搭建:
- cd /etc/pki/CA
- (umask 077; openssl genrsa 2048 > private/cakey.pem)
- openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650 #x509
- touch index.txt #證書索引
- echo 01 > serial #當(dāng)前所發(fā)證書的序列號(hào),從01開始
CA頒發(fā)mysql服務(wù)端證書:
- mkdir -p /data/ssl && cd /data/ssl
- (umask 077;openssl genrsa 2048 > master.key)
- openssl req -new -key master.key -out master.csr -days 3650
- openssl ca -in master.csr -out master.crt -days 3650
- chown -R mysql:mysql master*
上述證書配置在my.cnf里面。
CA頒發(fā)mysql客戶端證書:
- mkdir -p /data/ssl_slave && cd /data/ssl_slave
- (umask 077;openssl genrsa 2048 > slave.key)
- openssl req -new -key slave.key -out slave.csr -days 3650
- openssl ca -in slave.csr -out slave.crt -days 3650
- chown -R mysql:mysql slave*
上述證書復(fù)制給客戶端機(jī)器備用。
3. 客戶端
連接命令:
- mysql -h127.0.0.1 -P3306 --ssl-cert=/data/ssl/slave.crt --ssl-key=/data/ssl/slave.key
這樣指定由服務(wù)端指定的CA證書頒發(fā)給客戶端的證書和私鑰進(jìn)行來連接。客戶端一般不需要提供CA證書,除非客戶端加了需要驗(yàn)證服務(wù)端的有效性,也就是雙向認(rèn)證。
服務(wù)端的CA證書可以頒發(fā)很多證書給客戶端,這里有個(gè)吊銷的概念,CA可以吊銷自己頒發(fā)給別人的證書(CRL)。
但是吊銷證書針對(duì)我們5.5的版本是不生效的,也就是說給客戶端頒發(fā)證書之后,就算你在CA這里吊銷了,但是客戶端還是可以通過那個(gè)證書連過來。這里chrome也是一樣的,不檢查證書是否被吊銷,費(fèi)事。
這里和瀏覽器的https訪問有差異,比如瀏覽器是我們要校驗(yàn)服務(wù)端是否合法,但是mysql連接時(shí)候是服務(wù)端校驗(yàn)我們客戶端是否合法,雙向校驗(yàn)除外。
4. ssl握手簡(jiǎn)談
這里在ssl層會(huì)提供些待進(jìn)行協(xié)商的信息給服務(wù)端,比如ssl_cipher加密算法和某個(gè)隨機(jī)數(shù),明文傳給服務(wù)端,服務(wù)端進(jìn)行協(xié)商之后,也產(chǎn)生個(gè)隨機(jī)數(shù),然后和自己的證書(ssl_cert值)一起發(fā)送給客戶端。 客戶端收到服務(wù)端發(fā)送的證書之后,從里面取出公鑰信息,然后用這個(gè)公鑰加密一個(gè)隨機(jī)密碼發(fā)送給服務(wù)端。由于是服務(wù)端的公鑰,服務(wù)端收到之后可以用他的私鑰(ssl_key值)進(jìn)行解密,獲取到這個(gè)隨機(jī)密碼,然后就用這個(gè)密碼進(jìn)行后續(xù)的流量加解密了(這里的hash校驗(yàn)就不說了,就是每次收到之后進(jìn)行個(gè)校驗(yàn),看是否解密出的數(shù)據(jù)和加密之前的是一致)。
具體情況有些差異。
客戶端指定自己的私鑰和證書連服務(wù)端之后,服務(wù)端會(huì)用啟動(dòng)時(shí)候加載的ssl_ca值,也就是CA中心來校驗(yàn)客戶端發(fā)送過來的證書是自己頒發(fā)的,如果CA認(rèn)為是合法的才有后續(xù)的協(xié)商。
加解密流程比較復(fù)雜,不需要太精通,就知道可以合法情況下可以正常加解密正常流轉(zhuǎn)就好了。
5. 小疑問
1.服務(wù)端用的CA里面key和證書文件被別人拿走了,有風(fēng)險(xiǎn)嗎?
那肯定的,風(fēng)險(xiǎn)莫過于此了,如果是一個(gè)CA公司的話,這樣公司可以準(zhǔn)備申請(qǐng)破產(chǎn)了。這里的話簡(jiǎn)單說是這樣別人可以用CA頒發(fā)可以被服務(wù)端信任的證書來連接,也可以做中間人攻擊。
2.服務(wù)端用的證書和私鑰被別人拿走了,有風(fēng)險(xiǎn)嗎?
那肯定的,也就是說別人可以進(jìn)行中間人攻擊或者用私鑰進(jìn)行被加密的流量進(jìn)行解密,而且無法吊銷此證書(Mysql 5.5)。
3.服務(wù)端的ssl證書可以平滑替換嗎?
不可以,mysql里面這個(gè)變量是只讀的,在啟動(dòng)時(shí)候加載,就算后續(xù)把證書內(nèi)容改變了,mysql認(rèn)的還是啟動(dòng)時(shí)候加載在內(nèi)存里面的信息,需要替換的話需要重啟mysql。
4.客戶端需要用服務(wù)端的證書信息來連接mysql嗎?
不一定,一般只需要用服務(wù)端里面的CA頒發(fā)的任意證書就可以了,除非授權(quán)時(shí)候有用REQUIRE SUBJECT特意指定SUBJECT的屬性。
5.CA頒發(fā)了新的證書給從庫服務(wù)器,只要這個(gè)證書不泄露,別人就無法解密我們的加密流量嗎?
不是的,這個(gè)證書只是證明你這個(gè)從庫是有效的客戶端,可以用主庫里面定義的私鑰進(jìn)行流量解密。
6.有私鑰就可以解密流量嗎?不一定,看加密算法,如果不是DH加密算法,可以解密所有的加密流量,如果是DH之類的加密算法只可以通過手段解密之后的流量,但不能否認(rèn)泄漏CA和服務(wù)器證書的風(fēng)險(xiǎn)。
7.流量解密需要怎么測(cè)試呢配置ssl-cipher加密算法,去掉DH相關(guān)的加密算法,然后wireshark指定私鑰就可以了,下面附帶個(gè)解密加密的mysql流量教程。
6. wireshark流量解密
下面進(jìn)行ssl解密。
下載mysql服務(wù)端的證書私鑰,也就是之前說的master.key文件,然后打開wireshark的首選項(xiàng)進(jìn)行協(xié)議配置:
重新打開會(huì)發(fā)現(xiàn)多了個(gè)Decrypted SSL的選項(xiàng),也就是ssl解密之后的明文信息(正式測(cè)試時(shí)候留意是否存在wireshark的緩存導(dǎo)致數(shù)據(jù)異常):
sql語句成功讀取了,ssl流量成功解密。
以上測(cè)試環(huán)境基于Percona-Server-5.5,水平有限,如發(fā)現(xiàn)有理解偏差,歡迎留言指正。