MySQL(MariaDB)的 SSL 加密複製

本文轉自:http://www.cnblogs.com/zhoujinyi/p/4191096.html


背景:

      在默認的主從複製過程或遠程連接到MySQL/MariaDB所有的鏈接通信中的數據都是明文的,在局域網內連接倒問題不大;要是在外網裏訪問數據或則複製,則安全隱患會被放大很多。由於項目要求需要直接和外網的一臺實例進行同步。所以本文介紹下通過SSL加密的方式進行復制的方法,來進一步提高數據的安全性。本文會一起介紹MySQL和MariaDB。

環境搭建:

默認情況下ssl都是關閉的,要是have_ssl顯示NO,則表示數據庫不支持SSL,需要重新編譯安裝來支持它,顯示爲DISABLED表示支持SSL,但沒有開啓。

複製代碼
>show variables like '%ssl%';                                                                                                  +---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |
| have_ssl      | DISABLED |
| ssl_ca        |          |
| ssl_capath    |          |
| ssl_cert      |          |
| ssl_cipher    |          |
| ssl_key       |          |
+---------------+----------+
複製代碼

現在來開啓SSL,在配置文件的mysqld選項組裏面添加:

ssl

重啓數據庫,再次查看:

複製代碼
show variables like '%ssl%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl  | YES   |
| have_ssl      | YES   |
| ssl_ca        |       |
| ssl_capath    |       |
| ssl_cert      |       |
| ssl_cipher    |       |
| ssl_key       |       |
+---------------+-------+
複製代碼

接着就是配置SSL的重點了:

1:在主服務器上創建CA證書:

openssl genrsa 2048 > ca-key.pem

openssl req -new -x509 -nodes -days 1000 -key ca-key.pem > ca-cert.pem

2:在主服務器上創建服務端的證書:

openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem > server-req.pem

openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem

3:在主服務器上創建客戶端的證書:

openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem > client-req.pem

openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem

上面的操作都是在主上執行的,並且都在/etc/mysql/ 目錄下執行的。這裏需要注意的是MySQL和MariaDB不同:

MySQL在生成上面證書的時候需要輸入大量用戶信息,在CA上創建證書要注意所有的用戶信息要和CA中的一致,從國家到部門都要相同,否則會造成證書無法使用,直接全部默認回車即可。要是用戶信息一樣則MariaDB會報錯:

 ERROR 2026 (HY000): SSL connection error: error:00000001:lib(0):func(0):reason(1)

[ERROR] Slave I/O: error connecting to master ... - retry-time: 60  retries: 86400  message: SSL connection error: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed, Internal MariaDB error code: 2026

MariaDB在生成上面證書的時候也是需要輸入大量用戶信息,和MySQL不同的是輸入的用戶信息服務端和客戶端不能一致。即服務端輸入和客戶端輸入不一樣。具體原因見這裏,最後可以通過:

openssl verify -CAfile /etc/mysql/ca-cert.pem /etc/mysql/server-cert.pem /etc/mysql/client-cert.pem

 驗證MariaDB證書的有效性。好了,所有的證書已經生成,那麼在主上需要修改配置文件,把生成的證書配置起來:

ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/server-cert.pem
ssl-key=/etc/mysql/server-key.pem

並且把生成的證書:ca-cert.pem,client-cert.pem,client-key.pem 複製給從服務器

重啓主服務器,查看SSL的情況:

複製代碼
>show variables like '%ssl%';
+---------------+----------------------------+
| Variable_name | Value                      |
+---------------+----------------------------+
| have_openssl  | DISABLED                   |
| have_ssl      | DISABLED                   |
| ssl_ca        | /etc/mysql/ca-cert.pem     |
| ssl_capath    |                            |
| ssl_cert      | /etc/mysql/server-cert.pem |
| ssl_cipher    |                            |
| ssl_key       | /etc/mysql/server-key.pem  |
+---------------+----------------------------+
複製代碼

發現have_ssl變成了DISABLED,查看錯誤日誌:

SSL error: Unable to get private key from '/etc/mysql/server-key.pem'
141229 11:09:02 [Warning] Failed to setup SSL
141229 11:09:02 [Warning] SSL error: Unable to get private key

發現服務端的key不可用,在網上到了解決辦法,大家可以自己看:http://askubuntu.com/questions/194074/enabling-ssl-in-mysql,概括的說就是openssl新版本的變化導致的,這裏有2個解決辦法來重新生成server-key.pem:

方法1:openssl rsa

openssl rsa -in server-key.pem -out server-key.pem 

再次查看SSL情況:

複製代碼
>show variables like '%ssl%';
+---------------+----------------------------+
| Variable_name | Value                      |
+---------------+----------------------------+
| have_openssl  | YES                        |
| have_ssl      | YES                        |
| ssl_ca        | /etc/mysql/ca-cert.pem     |
| ssl_capath    |                            |
| ssl_cert      | /etc/mysql/server-cert.pem |
| ssl_cipher    |                            |
| ssl_key       | /etc/mysql/server-key.pem  |
+---------------+----------------------------+
複製代碼

方法2:這裏也可以直接安裝openssl的0.9.8x版本進行證書生成。

wget http://www.openssl.org/source/openssl-0.9.8x.tar.gz 
tar xvfz openssl-0.9.8x.tar.gz 
cd openssl-0.9.8x 
./config --prefix=/usr/local/openssl-0.9.8 
make 
make install

本文是通過方法1來進行解決的。

到此在主上的操作完成,再生成一個複製帳號:REQUIRE SSL

GRANT REPLICATION SLAVE ON *.* TO 'rep'@'192.168.200.%' IDENTIFIED BY '123456' REQUIRE SSL;

接着就去從上配置。之前已經把生成的證書給了從服務器,那麼在配置之前可以用SSL連接主服務器試試:

$mysql --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -h192.168.200.245 -urep -p
Enter password: 
SSL error: Unable to get private key from 'client-key.pem'
ERROR 2026 (HY000): SSL connection error

同理,也是SSL的問題導致的,重新生成client-key.pem,方法同重新生成server-key.pem一樣:

openssl rsa -in client-key.pem -out client-key.pem 

繼續用SSL測試連接:

複製代碼
$mysql --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -h192.168.200.245 -urep -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 763
Server version: 5.5.35-0ubuntu0.12.04.2-log (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.5.37, for debian-linux-gnu (x86_64) using readline 6.2

Connection id:        763
Current database:    
Current user:        rep@192.168.200.212
SSL:            Cipher in use is DHE-RSA-AES256-SHA
Current pager:        stdout
Using outfile:        ''
Using delimiter:    ;
Server version:        5.5.35-0ubuntu0.12.04.2-log (Ubuntu)
Protocol version:    10
Connection:        192.168.200.245 via TCP/IP
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    utf8
Conn.  characterset:    utf8
TCP port:        3306
Uptime:            22 min 52 sec

Threads: 3  Questions: 2325  Slow queries: 1  Opens: 7483  Flush tables: 1  Open tables: 100  Queries per second avg: 1.694
複製代碼

SSL測試連接成功,並且登入的SSL協議是:Cipher in use is DHE-RSA-AES256-SHA

繼續在從上配置SSL:

ssl
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/client-cert.pem
ssl-key=/etc/mysql/client-key.pem

查看SSL是否被支持:

複製代碼
>show variables like '%ssl%';
+---------------+----------------------------+
| Variable_name | Value                      |
+---------------+----------------------------+
| have_openssl  | YES                        |
| have_ssl      | YES                        |
| ssl_ca        | /etc/mysql/ca-cert.pem     |
| ssl_capath    |                            |
| ssl_cert      | /etc/mysql/client-cert.pem |
| ssl_cipher    |                            |
| ssl_key       | /etc/mysql/client-key.pem  |
+---------------+----------------------------+
複製代碼

從上SSL也被正確支持,那麼最後開始配置主從replicate。在從上CHANGE:

CHANGE MASTER TO MASTER_HOST='192.168.200.245', MASTER_USER='rep', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000042', MASTER_LOG_POS=521, MASTER_SSL=1, MASTER_SSL_CA = '/etc/mysql/ca-cert.pem', MASTER_SSL_CERT = '/etc/mysql/client-cert.pem', MASTER_SSL_KEY = '/etc/mysql/client-key.pem'

測試:

M:

複製代碼
>create table tmp_1229(id int,name varchar(100))default charset utf8;

>insert into tmp_1229 values(1,'a'),(2,'b'),(3,'c');

>select * from tmp_1229;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | c    |
+------+------+
複製代碼

S:

複製代碼
>select * from tmp_1229;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | c    |
+------+------+

複製代碼

以上同步成功。

總結:

      SSL(Secure Sockets Layer 安全套接層),及其繼任者傳輸層安全(Transport Layer Security,TLS)是爲網絡通信提供安全及數據完整性的一種安全協議。複製默認是明文進行傳輸的,通過SSL加密可以大大提高數據的安全性。在上面的過程中,遇到一些問題:

1:openssl版本問題引起的證書不可用,文中已經說明解決辦法。

2:MariaDB 證書的不可用,原因是生成服務端客戶端證書的時候輸入一致導致的,文中也說明了解決辦法。

3:要是配置有問題,在用SSL登陸的時候,可以發現錯誤信息,可以直接定位到哪裏出問題。

ssl登陸:
mysql --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -h192.168.200.245 -urep -p

4:在配置MariaDB的時候,在生成證書的時候可以直接先驗證,查看是否有問題。

驗證:
openssl verify -CAfile /etc/mysql/ca-cert.pem /etc/mysql/server-cert.pem /etc/mysql/client-cert.pem 

/etc/mysql/server-cert.pem: OK
/etc/mysql/client-cert.pem: OK

5:要是openssl版本沒有問題,不需要再次通過openssl rsa 再次生成,具體的安裝配置方法參照本文章即可。

更新(2016.3.19):

今天做了MySQL5.7的SSL複製,5.7安裝的時候就已經在數據目錄下面生成了上面的這些pem文件,所以直接把client的pem複製到從上去就可以了(注意複製過去之後修改權限,屬主改成mysql即可)。否則報錯:

Failed to set up SSL because of the following SSL library error: Unable to get certificate ... server-cert.pem
Failed to set up SSL because of the following SSL library error: Unable to get private key ... server-cert.pem

 

更多信息:

https://blog.marceloaltmann.com/en-mysql-replication-with-ssl-pt-replicacao-em-mysql-com-ssl/

http://www.zhengdazhi.com/?p=856

http://dev.mysql.com/doc/refman/5.5/en/replication-solutions-ssl.html

https://dev.mysql.com/doc/refman/5.7/en/replication-solutions-secure-connections.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章