背景:

在默认的主从复制过程或远程连接到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 '' 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='', MASTER_LOG_FILE='mysql-bin.000042', MASTER_LOG_POS=521, MASTER_SSL=, 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

MySQL(MariaDB)的 SSL 加密复制的更多相关文章

  1. mysql/mariadb基于ssl的主从复制

    当mysql/mariadb跨越互联网进行复制时别人可以窃取到mysql/mariadb的复制信息, 这些信息是明文的, 因此存在不安全性, 这里通过ssl对复制的信息进行加密 1. 创建证书中心 在 ...

  2. MySQL(mariadb)主从复制模式与复制过滤

    在前一篇文章<mysql多实例与复制应用>中只对mysql的复制做了简单的介绍,本篇内容专门介绍一下mysql的复制. MySQL复制 mysql复制是指将主数据库的DDL和DML操作通过 ...

  3. MySQL/MariaDB数据库的复制加密

      MySQL/MariaDB数据库的复制加密 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL的安全问题 1>.基于SSL复制 在默认的主从复制过程或远程连接 ...

  4. MySQL/MariaDB数据库的复制监控和维护

      MySQL/MariaDB数据库的复制监控和维护 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.清理日志 1>.删除指定日志文件名称之前的日志(也可用基于时间) M ...

  5. MySQL的SSL加密连接与性能开销

    本文转载自:http://www.innomysql.net/article/23959.html(只作转载, 不代表本站和博主同意文中观点或证实文中信息) Contents [hide] 1 前言 ...

  6. MySQL 5.7 的SSL加密方法

    MySQL 5.7 的SSL加密方法 MySQL 5.7.6或以上版本 (1)创建证书开启SSL验证--安装opensslyum install -y opensslopenssl versionOp ...

  7. MySQL/MariaDB数据库的复制过滤器

      MySQL/MariaDB数据库的复制过滤器 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.复制过滤器概述 1>.复制器过滤器功能 让从节点仅复制指定的数据库,或指 ...

  8. MySQL/MariaDB数据库的半同步复制

      MySQL/MariaDB数据库的半同步复制 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL半同步复制概述 1>.MySQL默认的异步复制 默认情况下,M ...

  9. MySQL/MariaDB数据库的主主复制

      MySQL/MariaDB数据库的主主复制 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.主主复制概述 1>.什么是主主复制 所谓的主主复制,说白了就是两台节点互为 ...

随机推荐

  1. 用libsvm进行回归预测

    最近因工作需要,学习了台湾大学林智仁(Lin Chih-Jen)教授等人开发的SVM算法开源算法包. 为了以后方便查阅,特把环境配置及参数设置等方面的信息记录下来. 林教授年轻时照片 SVM属于十大挖 ...

  2. SQl语句学习笔记(二)

    merge into        when matched then...  when not mached then... merge into t_road_pre_parameter a fr ...

  3. PHP: 手把手编写自己的 MVC 框架实例教程

    1 什么是MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller ...

  4. C#集合u

    List<T> 列表(动态数组),相当于C++的 vector Queue<T> 队列,先进先出 Stack<T> 栈,先进后出 LinkedList<T&g ...

  5. jQuery.lazyload使用及源码分析

    前言: 貌似以前自己也写过图片懒加载插件,但是新公司使用的是jQuery.lazyload插件,为了更好的运用,自己还是把源码看了遍,分别记录了如何使用, 插件原理,各个配置属性的完整解释,demo实 ...

  6. 那些你不知道的chrome URLs

    Xee:我用的是七星浏览器,因为我看了很多的浏览器,它们的版本都停滞不前了: 360安全浏览器的重度用户肯定不会对 se:last (上次未关闭页面)这个页面感到陌生,即使您没有见过这个,但也一定很熟 ...

  7. [译]git remote

    git remote命令让我们可以创建, 查看, 删除一个到其他仓储的连结. 下图展示了我们的本地仓储有两个remote连接, 一个是中央仓储, 一个是其他开发者的仓储. 除了使用完整的url指向他们 ...

  8. java项目报junit 相关错误

    maven配置,java工程运行时需要把test测试相关移除

  9. 移除wordpress留言中自动链接功能

    默认情况下,在 WordPress 博客的留言中含有 URL,会自动变成可点击的,虽然这样的链接是 nofollow 的,但是还是成为 SPAM 利用的对象,所以可以移除这个自动链接功能. 我们可以在 ...

  10. 怎么看网站是否开启CDN加速?测试网站全国访问速度方法详解

    注意域名,动静分离的网站,只对静态文件的域名做了cdn 怎么看网站有没开启CDN? 要看一个网站是否开启CDN,方法很简单,只要在不同的地区ping网址就可以,比如在山东济南ping www.jb51 ...