liuyuehua 发表于 2018-10-2 06:39:57

基于SSL实现MySQL的加密主从复制

  大家都知道MySQL的主从复制是明文传输的,这对一些特殊业务来说是不允许的,下面来尝试构建基于SSL的主从复制

环境:RHEL5.8 SELinux关闭,iptables关闭,MySQL 5.5.28-i686 tar包初始化安装(非编译)
规划:  


[*]master: 172.16.1.18master.laoguang.me
[*]slave:172.16.1.19slave.laoguang.me
  

准备工作:hostname与规划一致,配置/etc/hosts做好解析,时间要同步,过程不再赘述,见http://laoguang.blog.51cto.com/6013350/1073891,mysql安装见http://laoguang.blog.51cto.com/6013350/1039208,数据目录为/data/mydata
一.在master上配置CA服务器,并为master,slave颁发证书
1.1 master建立CA服务器,过程见http://laoguang.blog.51cto.com/6013350/1035608
1.2 master的MySQL证书申请  


[*]mkdir /data/mydata/ssl
[*]cd /data/mydata/ssl
[*]openssl genrsa 1024 > mysql.key
[*]openssl req -new -key mysql.key -out mysql.csr -days 3650
[*]##接下来的输入与建立CA时的一致,common name为master.laoguang.me
[*]openssl ca openssl ca -in mysql.csr -out mysql.crt ##为MySQL签证
[*]cp /etc/pki/CA/cacert.pem .##将CA的证书也拷过来
[*]chown mysql:mysql *
[*]chmod 600 *
  

1.3 slave上申请证书  


[*]mkdir /data/mydata/ssl
[*]cd /data/mydata/ssl
[*]openssl genrsa 1024 > mysql.key
[*]openssl req -new -key mysql.key -out mysql.csr -days 3650
[*]##接下来的输入与建立CA时的一致,common name为slave.laoguang.me
[*]scp mysql.csr master:/root
  

1.4 master上为slave签发  


[*]cd /root
[*]openssl ca -in mysql.csr -out mysql.crt
[*]scp mysql.crt slave:/data/mydata/ssl
[*]scp /etc/pki/CA/cacert.pem slave:/data/mydata/ssl
  

1.5 slave上更改权限与属主  


[*]chown mysql:mysql mysql.*
[*]chmod 600 mysql.*
  

二.Master上编缉/etc/my.cnf启用ssl,并设置主从
2.1 修改/etc/my.cnf  


[*]
[*]log-bin=mysql-bin
[*]sync_binlog   = 1                  ##二进制日志
[*]server-id       = 1                  ##此id必须全局唯一
[*]innodb_flush_log_at_trx_commit=1    ##每秒将事务日志立刻刷写到磁盘
[*]ssl                     ##启用ssl默认是不开启的,mysql中show variables like '%ssl%'查看
[*]ssl_ca =/data/mydata/ssl/cacert.pem##ca文件的位置
[*]ssl_cert= /data/mydata/ssl/mysql.crt ##证书文件的位置
[*]ssl_key = /data/mydata/ssl/mysql.key ##私钥文件的位置
  

2.2 启动mysql,并查看ssl信息  


[*]service mysqld start
[*]mysql
[*]mysql> show variables like '%ssl%';
[*]+---------------+-----------------------------+
[*]| Variable_name | Value                     |
[*]+---------------+-----------------------------+
[*]| have_openssl| YES                         |
[*]| have_ssl      | YES                         |
[*]| ssl_ca      | /data/mydata/ssl/cacert.pem |
[*]| ssl_capath    |                           |
[*]| ssl_cert      | /data/mydata/ssl/mysql.crt|
[*]| ssl_cipher    |                           |
[*]| ssl_key       | /data/mydata/ssl/mysql.key|
[*]+---------------+-----------------------------+
  

2.3 为同步建立一最小权限账户,并要求ssl  


[*]mysql> create user 'backup_ssl'@'172.16.1.19' identified by 'redhat';
[*]mysql> revoke all privileges,grant option from 'backup_ssl'@'172.16.1.19';
[*]mysql> grant replication slave,replication client on *.* to 'backup_ssl'@'172.16.1.19' require ssl;
[*]mysql> flush privileges;
  

三.Slave上编缉/etc/my.cnf,启用ssl,并设置主从
3.1 编缉/etc/my.cnf  


[*]
[*]server-id       = 2                  ##此id必须全局唯一  ##log-bin = mysql-bin                ##注释掉,从服务器不需要二进制日志
[*]relay-log = mysql-ralay            ##中继日志
[*]relay-log-index = mysql-ralay.index##中继目录
[*]read-only = 1                        ##从服务器只读
[*]ssl                        ##启用ssl默认是不开启的,mysql中show variables like '%ssl%'查看
[*]ssl_ca =/data/mydata/ssl/cacert.pem##ca文件的位置
[*]ssl_cert= /data/mydata/ssl/mysql.crt ##证书文件的位置
[*]ssl_key = /data/mydata/ssl/mysql.key ##私钥文件的位置
  

3.2 启用mysqld并查看ssl相关信息  


[*]servie mysqld start
[*]mysql> show variables like '%ssl%';
[*]+---------------+-----------------------------+
[*]| Variable_name | Value                     |
[*]+---------------+-----------------------------+
[*]| have_openssl| YES                         |
[*]| have_ssl      | YES                         |
[*]| ssl_ca      | /data/mydata/ssl/cacert.pem |
[*]| ssl_capath    |                           |
[*]| ssl_cert      | /data/mydata/ssl/mysql.crt|
[*]| ssl_cipher    |                           |
[*]| ssl_key       | /data/mydata/ssl/mysql.key|
[*]+---------------+-----------------------------+
  

3.3 启动slave同步进程,连接主服务器  


[*]mysql> change master to
[*]    -> master_host='172.16.1.18',
[*]    -> master_user='backup_ssl',
[*]    -> master_password='redhat',
[*]    -> master_log_file='mysql-bin.000001',
[*]    -> master_ssl=1,
[*]    -> master_ssl_ca='/data/mydata/ssl/cacert.pem',
[*]    -> master_ssl_cert='/data/mydata/ssl/mysql.crt',
[*]    -> master_ssl_key='/data/mydata/ssl/mysql.key';
[*]mysql> start slave
[*]mysql> show slave status\G; ##查看slave状态
  

关注以下参数:  


[*]Slave_IO_Running: Yes      ##IOthread是否运行,如果为No代表slave运行不正常
[*]Slave_SQL_Running: Yes   ##SQLthread是否运行,如果为No代表slave运行不正常
[*]Master_SSL_CA_File: /data/mydata/ssl/cacert.pem##是否启用了ssl
[*]Master_SSL_Cert: /data/mydata/ssl/mysql.crt
[*]Master_SSL_Key: /data/mydata/ssl/mysql.key
[*]Master_Log_File: mysql-bin.000023                ##最后接收的主服务器的二进制
[*]Exec_Master_Log_Pos: 1087                        ##最后执行的位置,查看master中是不是该位置
[*]Last_IO_Errno: 0                                 ##最后一次IOthread有没有报错
  


如果与上图累似,slave基本正常,下面测试
四.测试
4.1 主服务器上建立一数据库  


[*]mysql> create database testssl;
  

4.2 从服务器上查看有没有同步过去  


[*]mysql> show databases;
  

如果同步成功,说明没有错误
4.3 从服务器mysql基于ssl连接主服务器,查看连接状态是否加密  


[*]mysql -ubackup_ssl -predhat -h172.16.1.18 --ssl-cert=/data/mydata/ssl/mysql.crt \
[*]--ssl-key=/data/mydata/ssl/mysql.key
  

查看连接状态  


[*]mysql> status;
[*]Current user:       backup_ssl@slave.laoguang.me
[*]SSL:            Cipher in use is DHE-RSA-AES256-SHA
  

由此可知连接是加密的,可以用tcpdump抓包测试
到此基于SSL的mysql主从同步构建完毕,如果你的从服务器是新加的,先将主服务器最近一次的完整备份恢复到从服务器,并从同步完整备份后的二进制日志,即change master时添加master_log_op=n, n代表完整备份后的二进制位置,其它的基本一致。
后记:今天尝试只给slave签发证书,master拥有有CA的证书,理论上应该能成功的,不过就是连接不上,所以暂时放弃,然后尝试master的证书名字为master.crt,slave的证书为slave.crt结果也连不上,后来google,把master与slave的证书,私钥都叫mysql.crt,mysql.key才得以完成,有了解的人说明一下,单证书为何不行,两个证书名称不一致也不行在原因,感谢!

页: [1]
查看完整版本: 基于SSL实现MySQL的加密主从复制