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