你的MySQL服務器開啟SSL了嗎?SSL在https和MySQL中的原理思考


最近,准備升級一組MySQL到5.7版本,在安裝完MySQL5.7后,在其data目錄下發現多了很多.pem類型的文件,然后通過查閱相關資料,才知這些文件是MySQL5.7使用SSL加密連接的。本篇主要介紹MySQL5.7 SSL連接加密功能、如何使用?以及使用SSL的一些注意點。

我們知道,MySQL5.7之前版本,安全性做的並不夠好,比如安裝時生成的root空密碼賬號、存在任何用戶都能連接上的test庫等,導致數據庫存在較大的安全隱患。好在5.7版本對以上問題進行了一一修復。與此同時,MySQL 5.7版本還提供了更為簡單SSL安全訪問配置,且默認連接就采用SSL的加密方式,這讓數據庫的安全性提高一個層次。

一、SSL介紹

SSL(Secure Socket Layer:安全套接字層)利用數據加密、身份驗證和消息完整性驗證機制,為基於TCP等可靠連接的應用層協議提供安全性保證。

SSL協議提供的功能主要有:

           1、 數據傳輸的機密性:利用對稱密鑰算法對傳輸的數據進行加密。
           2.、身份驗證機制:基於證書利用數字簽名方法對服務器和客戶端進行身份驗證,其中客戶端的身份驗證是可選的。
           3、 消息完整性驗證:消息傳輸過程中使用MAC算法來檢驗消息的完整性。

如果用戶的傳輸不是通過SSL的方式,那么其在網絡中數據都是以明文進行傳輸的,而這給別有用心的人帶來了可乘之機。所以,現在很多大型網站都開啟了SSL功能。同樣地,在我們數據庫方面,如果客戶端連接服務器獲取數據不是使用SSL連接,那么在傳輸過程中,數據就有可能被竊取。

二、MySQL5.7 SSL配置和啟用

1、安裝時啟動SSL 

在MySQL5.7安裝初始化階段,我們發現比之前版本多了一步操作,而這個操作就是安裝SSL的。

shell> bin/mysqld --initialize --user=mysql    # MySQL 5.7.6 and up
shell> bin/mysql_ssl_rsa_setup                 # MySQL 5.7.6 and up

當運行完這個命令后,默認會在data_dir目錄下生成以下pem文件,這些文件就是用於啟用SSL功能的:

復制代碼
[root mysql_data]# ll *.pem
-rw------- 1 mysql mysql 1675 Jun 12 17:22 ca-key.pem         #CA私鑰
-rw-r--r-- 1 mysql mysql 1074 Jun 12 17:22 ca.pem             #自簽的CA證書,客戶端連接也需要提供
-rw-r--r-- 1 mysql mysql 1078 Jun 12 17:22 client-cert.pem    #客戶端連接服務器端需要提供的證書文件
-rw------- 1 mysql mysql 1675 Jun 12 17:22 client-key.pem     #客戶端連接服務器端需要提供的私鑰文件
-rw------- 1 mysql mysql 1675 Jun 12 17:22 private_key.pem #私鑰/公鑰對的私有成員
-rw-r--r-- 1 mysql mysql 451 Jun 12 17:22 public_key.pem #私鑰/公鑰對的共有成員
-rw-r--r-- 1 mysql mysql 1078 Jun 12 17:22 server-cert.pem #服務器端證書文件
-rw------- 1 mysql mysql 1675 Jun 12 17:22 server-key.pem #服務器端私鑰文件
復制代碼

 這時從數據庫服務器本地進入MySQL命令行,你可以看到如下變量值:

復制代碼
root> mysql -h 10.126.xxx.xxx -udba -p

###查看SSL開啟情況

dba:(none)> show global variables like '%ssl%'; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | have_openssl | YES | | have_ssl | YES | #已經開啟了SSL | ssl_ca | ca.pem | | ssl_capath | | | ssl_cert | server-cert.pem | | ssl_cipher | | | ssl_crl | | | ssl_crlpath | | | ssl_key | server-key.pem | +---------------+-----------------+

###查看dba連接的方式

dba:(none)> \s
--------------
/usr/local/mysql/bin/mysql Ver 14.14 Distrib 5.7.18, for linux-glibc2.5 (x86_64) using EditLine wrapper

Connection id: 2973
Current database:
Current user: dba@10.126.xxx.xxx
SSL: Cipher in use is DHE-RSA-AES256-SHA #表示該dba用戶是采用SSL連接到mysql服務器上的,如果不是ssl,那么會顯示“Not in use“
Current pager: more
Using outfile: ''
Using delimiter: ;
Server version: 5.7.18-log MySQL Community Server (GPL)
Protocol version: 10
Connection: 10.126.126.160 via TCP/IP
Server characterset: utf8
Db characterset: utf8
Client characterset: utf8
Conn. characterset: utf8
TCP port: 3306
Uptime: 2 hours 35 min 48 sec

復制代碼

【注意】:如果用戶是采用本地localhost或者sock連接數據庫,那么不會使用SSL方式了。

2、如果安裝MySQL57時沒有運行過mysql_ssl_rsa_setup,那么如何開啟SSL呢?

1)、關閉MySQL服務
2)、運行mysql_ssl_rsa_setup 命令
3)、到data_dir目錄下修改.pem文件的所屬權限用戶為mysql
    chown -R mysql.mysql *.pem
4)、啟動MySQL服務

3、強制某用戶必須使用SSL連接數據庫

#修改已存在用戶 
ALTER USER 'dba'@'%' REQUIRE SSL;
#新建必須使用SSL用戶
grant select on *.* to 'dba'@'%' identified by 'xxx' REQUIRE SSL;

對於上面強制使用ssl連接的用戶,如果不是使用ssl連接的就會報錯,像下面這樣:

[root]# /usr/local/mysql/bin/mysql -udba -p -h10.126.xxx.xxx --ssl=0
Enter password: 
ERROR 1045 (28000): Access denied for user 'dba'@'10.126.xxx.xxx' (using password: YES)

三、未使用SSL和使用SSL安全性對比

【測試方式】在MySQL服務器端通過tshark抓包的方式來模擬竊取數據。驗證、對比未使用SSL和使用SSL兩者在安全性上有什么不同?

    1 未使用SSL情況:

         在客戶端機器(10.126.126.161)上連接數據庫並進行insert操作,使用--ssl-mode=DISABLED關閉SSL

          同時在MySQL服務器端(10.126.126.160)上用tshark進行抓包:

【結論】未使用SSL情況下,在數據庫服務器端可以通過抓包的方式獲取數據,安全性不高。

    2 采用SSL情況:   

      在客戶端機器(10.126.126.161)上連接數據庫並進行insert操作,使用--ssl-mode=REQUIRED指定SSL

      同時在MySQL服務器端(10.126.126.160)上再次用tshark進行抓包:

【結論】沒有抓到該語句,采用SSL加密后,tshark抓不到數據,安全性高。

 

四、使用SSL前后性能對比(QPS)

服務器配置:CPU:32核心       內存:128G      磁盤:SSD

為了盡量准確測試QPS,采用全內存查詢,因為我們線上熱點數據基本都在內存中;按照並發線程數分類:1線程、4線程、8線程、16線程、24線程、32線程、64線程;

具體數據如下:

從測試數據可以發現,開啟SSL后,數據庫QPS平均降低了23%左右,相對還是比較影響性能的。從SSL實現方式來看,建立連接時需要進行握手、加密、解密等操作。所以耗時基本都在建立連接階段,這對於使用短鏈接的應用程序可能產生更大的性能損耗,比如采用PHP開發。不過如果使用連接池或者長連接可能會好許多。

五、總結

1、MySQL5.7默認是開啟SSL連接,如果強制用戶使用SSL連接,那么應用程序的配置也需要明確指定SSL相關參數,否則程序會報錯。

2、雖然SSL方式使得安全性提高了,但是相對地使得QPS也降低23%左右。所以要謹慎選擇:

      2.1、對於非常敏感核心的數據,或者QPS本來就不高的核心數據,可以采用SSL方式保障數據安全性;

      2.2、對於采用短鏈接、要求高性能的應用,或者不產生核心敏感數據的應用,性能和可用性才是首要,建議不要采用SSL方式;

 

 

 

 

 

 

 SSL在https和MySQL中的原理思考

 

之前對HTTPS通信過程有過了解,HTTPS是應用HTTP協議使用SSL加密的版本,在TCP和HTTP之間增加SSL協議。通過握手階段認證雙方身份,協商對稱秘鑰對通信信息進行加密。此處只描述常用的服務器單向驗證,大致過程簡要描述如下:

0:事先Web服務器把自己的公鑰和Web信息提交給權威CA,CA確認后,用自己的私鑰將Web信息以及公鑰的文摘簽名,制成數字證書交給Web服務器;
     客戶端Web瀏覽器事先安裝被信任的權威CA的根證書(未簽名證書或者自簽名證書)
1:客戶端向服務器發起連接請求,協商使用的SSL版本、非對稱加密算法、對稱加密算法以及摘要生成算法,雙方達成共識
2:Web服務器向客戶端發送自己的數字證書,客戶端用CA的根證書解密,證明Web服務器身份真實,同時證明服務器公鑰正確
3:客戶端用服務器公鑰加密一個隨機數,作為通信收發數據的對稱秘鑰,發送給服務器
4:服務器用自己的私鑰解密,拿到對稱秘鑰,返回ACK
5:客戶端和服務器使用對稱秘鑰開始通信

 

到學習MySQL的SSL連接配置時產生一個疑問,HTTPS有CA作為可信第三方,負責確認服務器身份,而MySQL連接通信只2方,沒聽說還有個CA從中協調啊,那還怎么SSL啊?

通過網上查資料,發現自己對SSL相關的很多概念理解不是很准確,對之前CA的驗證方式理解不對。首先明確一些概念:

公私鑰對:非對稱加密算法,公鑰和私鑰成對出現,用公鑰加密用私鑰解密,用私鑰加密用公鑰解密

CA:證書頒發機構,通信雙方可信的第三方。自己有公私鑰對,網站想證明自己真實可信,但用戶不相信自己,只相信CA說的,於是網站提交自己的信息和公鑰給CA,CA核實網站信息和提交的公鑰,覺得靠譜,於是簽名,制成證書,交給網站成為一個資質。

簽名:別人不知道我的私鑰,但是知道我的公鑰。怎么證明這文件是我認證的呢?我用自己的私鑰加密,別人用我的公鑰解密成功,那肯定知道是我加密的,別人干不了。具體一點,先對文本內容計算散列值,然后對這個散列值用自己的私鑰加密。(別人對文本內容計算散列值,然后用我的私鑰解密得到的值做對比,一致證明簽名OK)

證書:包含3部分,通信方具體信息(地點、域名、組織、擁有者等)、通信方的公鑰、權威CA的簽名。(具體信息和公鑰計算散列值,然后對這個散列值用自己的私鑰加密)

根證書:權威CA也有自己的證書(畢竟需要CA的公鑰來驗證網站證書真偽),那CA的證書誰簽名啊?畢竟沒有更高一級了,所以根證書是未簽名的或者是自簽名的,沒人給這個證書背書了,所以叫做根,是信任鏈的起點,都可以理解了。

 

再看MySQL的SSL連接配置,思考SSL通信過程,就可以理解為什么需要這些文件了(此處描述SSL單向驗證模式)

MySQL服務器端要配置3個文件:ssl-ca.pem, ssl-key.pem, ssl-cert.pem

客戶端連接時需要文件:ssl-ca.pem

ssl-ca.pem就充當了可信的第三方,CA根證書,文件里包含了CA的信息和公鑰,客戶端和服務器都有。

1.客戶端向MySQL服務器發起連接請求,雙方協商加密算法、SSL版本等

2.服務器向客戶端發來自己的證書(ssl-cert.pem的內容,CA簽名的),客戶端用ssl-ca.pem的公鑰解密,確認服務器身份和公鑰真實。

3.客戶端產生隨機數作為對稱加密的秘鑰,用服務器公鑰加密,發送給服務器

4.服務器用自己的私鑰(ssl-key.pem)解密,拿到這個隨機數,返回ACK

5.雙方用隨機數做密鑰,以對稱加密方式通信

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM