在MySQL的主从复制中,其传输过程是明文传输,并不能保证数据的安全性,在编译安装Mysql时,基本上都会加上一个 --with-openssl这样的选项,即表示支openssl加密传输协议,因此就可以为mysql配置基于ssl加密传输啦。

规划:
Master:
IP地址:172.16.4.111
MySQL版本:5.5.20
操作系统:RHEL5.4

Slave:
IP地址:172.16.4.112
MySQL版本:5.5.20
操作系统:RHEL5.4

由于使用了ssl加密传输协议,即意味着,在传输之前,主从服务器是要进行互相认证的,因此要为两台服务器准备各自的证书,私钥,以及为其颁发证书的CA的证书,明晰了这些,就先为两台服务器准备私钥,证书。这里需要将Master配置为一台CA服务器,方便为主从服务器颁发证书。ps:将服务器配置为CA服务器,详见:Openssl的用法(搭建CA服务器)  http://grass51.blog.51cto.com/4356355/798505

一、设置主从服务
在172.16.4.111服务器上
编辑/etc/my.cnf
#vim /etc/my.cnf
将serier_id修改为11
server_id=11                #修改server_id=11
log_bin=mysql-bin            #开启二进制日志
sync_binlog=1                #任何一个事务提交之后就立即写入到磁盘中的二进制文件
innodb_flush_logs_at_trx_commit=1       #任何一个事物提交之后就立即写入到磁盘中的日志文件
保存退出
启动mysql
#service mysqld start

在172.16.4.112服务器上

编辑/etc/my.cnf
#vim /etc/my.cnf
server_id=12                #修改server_id=12
#log-bin                #注释掉log-bin,从服务器不需要二进制日志,因此将其关闭
relay-log=mysql-relay                #定义中继日志名,开启从服务器中继日志
relay-log-index=mysql-relay.index     #定义中继日志索引名,开启从服务器中继索引
read_only=1                    #设定从服务器只能进行读操作,不能进行写操作
保存退出
启动mysql
#service mysqld start


二、准备证书,私钥

1、配置Master为CA服务器
#vim /etc/pki/tls/openssl.cnf
将  dir             = ../../CA修改为
dir             = /etc/pki/CA
#(umask 077;openssl genrsa 2048 > private/cakey.pem)
#openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650
#mkdir certs crl newcerts
#touch index.txt
#echo 01 > serial

2、为Master上的Mysql准备私钥以及颁发证书
#mkdir /usr/local/mysql/ssl
#cd ssl/
#(umask 077;openssl genrsa 1024 > mysql.key)
#openssl req -new -key mysql.key -out mysql.csr
#openssl ca -in mysql.csr -out mysql.crt
#cp /etc/pki/CA/cacert.pem /usr/local/mysql/ssl/
#chown -R mysql.mysql ssl/

3、为Slave上的Mysql准备私钥以及申请证书
#mkdir /usr/local/mysql/ssl
#cd ssl/
#(umask 077;openssl genrsa 1024 > mysql.key)
#openssl req -new -key mysql.key -out mysql.csr
#scp ./mysql.csr 172.16.4.111:/root

4、在Master上为Slave签发证书

#cd
#openssl ca -in mysql.csr -out mysql.crt
#scp ./mysql.crt 172.16.4.112:/usr/local/mysql/ssl
#cd /etc/pki/CA
#scp ./cacert.pem 172.16.4.112:/usr/local/mysql/ssl

到此证书以及私钥已经准备好,请确认在Master以及Slave的/usr/local/mysql/ssl目录下具有以下文件,以及属主和属组:

 


三、开启Mysql的ssl功能

Master:
登录Mysql查看
mysql> show variables like '%ssl%';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |
| have_ssl      | DISABLED |
| ssl_ca        |          |
| ssl_capath    |          |
| ssl_cert      |          |
| ssl_cipher    |          |
| ssl_key       |          |
+---------------+----------+
输出为DISABLED表示ssl还未开启,
编辑/etc/my.cnf
在[mysqld]和[mysqldump]之间,加入以下内容:
ssl                         #表示开启mysql的ssl功能

保存后重新启动mysql,再次登录mysql
mysql> show variables like '%ssl%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl  | YES   |
| have_ssl      | YES   |
| ssl_ca        |       |
| ssl_capath    |       |
| ssl_cert      |       |
| ssl_cipher    |       |
| ssl_key       |       |
+---------------+-------+
输出为YES表示ssl已经开启。

Slave:
执行同样的操作
mysql> show variables like '%ssl%';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |
| have_ssl      | DISABLED |
| ssl_ca        |          |
| ssl_capath    |          |
| ssl_cert      |          |
| ssl_cipher    |          |
| ssl_key       |          |
+---------------+----------+
输出为DISABLED表示ssl还未开启,
编辑/etc/my.cnf
在[mysqld]和[mysqldump]之间,加入一行ssl:
ssl

保存后重新启动mysql,再次登录mysql
mysql> show variables like '%ssl%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl  | YES   |
| have_ssl      | YES   |
| ssl_ca        |       |
| ssl_capath    |       |
| ssl_cert      |       |
| ssl_cipher    |       |
| ssl_key       |       |
+---------------+-------+
输出为YES表示ssl已经开启。


四、配置主从服务的ssl功能

Master:
编辑配置文件:
#vim /etc/my.cnf
在之间添加的ssl下面添加以下内容:
ssl-ca=/usr/local/mysql/ssl/cacert.pem
ssl-cert=/usr/local/mysql/ssl/mysql.crt
ssl-key=/usr/local/mysql/ssl/mysql.key

这里一定要对应到您所存放证书和私钥的绝对路径
保存退出,重新启动Mysql
mysql> show variables like '%ssl%';
+---------------+---------------------------------+
| Variable_name | Value                           |
+---------------+---------------------------------+
| have_openssl  | YES                             |
| have_ssl      | YES                             |
| ssl_ca        | /usr/local/mysql/ssl/cacert.pem |
| ssl_capath    |                                 |
| ssl_cert      | /usr/local/mysql/ssl/mysql.crt  |
| ssl_cipher    |                                 |
| ssl_key       | /usr/local/mysql/ssl/mysql.key  |
+---------------+---------------------------------+

Slave:
编辑配置文件:
#vim /etc/my.cnf
在之间添加的ssl下面添加以下内容:
ssl-ca=/usr/local/mysql/ssl/cacert.pem
ssl-cert=/usr/local/mysql/ssl/mysql.crt
ssl-key=/usr/local/mysql/ssl/mysql.key

这里一定要对应到您所存放证书和私钥的绝对路径
保存退出,重新启动Mysql
mysql> show variables like '%ssl%';
+---------------+---------------------------------+
| Variable_name | Value                           |
+---------------+---------------------------------+
| have_openssl  | YES                             |
| have_ssl      | YES                             |
| ssl_ca        | /usr/local/mysql/ssl/cacert.pem |
| ssl_capath    |                                 |
| ssl_cert      | /usr/local/mysql/ssl/mysql.crt  |
| ssl_cipher    |                                 |
| ssl_key       | /usr/local/mysql/ssl/mysql.key  |
+---------------+---------------------------------+


五、记录主服务器的二进制日志文件以及事件,并且创建基于ssl复制的用户

ps:这里主从服务器的数据当前都是一致的,如果从服务器是新添加的,则需要将主服务器的最后的一个二进制日志之前的所有数据导入从服务器,具体步骤见:mysql的主从复制的场景二       http://grass51.blog.51cto.com/4356355/836600


Master:
mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000075 |      107 |              |                  |
+------------------+----------+--------------+------------------+

mysql> grant replication client,replication slave on *.* to sslrepl@172.16.4.112 identified by '135246' require ssl;
Query OK, 0 rows affected (0.01 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)


六、启动从服务的从服务线程
Slave:
mysql> change master to \
    -> master_host='172.16.4.111',
    -> master_user='sslrepl',
    -> master_password='135246',
    -> master_log_file='mysql-bin.000075',
    -> master_log_pos=107,
    -> master_ssl=1,
    -> master_ssl_ca='/usr/local/mysql/ssl/cacert.pem',
    -> master_ssl_cert='/usr/local/mysql/ssl/mysql.crt',
    -> master_ssl_key='/usr/local/mysql/ssl/mysql.key';
Query OK, 0 rows affected (0.17 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 172.16.4.111
                  Master_User: sslrepl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000075
          Read_Master_Log_Pos: 608
               Relay_Log_File: relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000075
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 608
              Relay_Log_Space: 107
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: Yes
           Master_SSL_CA_File: /usr/local/mysql/ssl/cacert.pem
           Master_SSL_CA_Path: /usr/local/mysql/ssl
              Master_SSL_Cert: /usr/local/mysql/ssl/mysql.crt
            Master_SSL_Cipher:
               Master_SSL_Key: /usr/local/mysql/ssl/mysql.key
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Queueing master event to the relay log
                  Master_Host: 172.16.4.111
                  Master_User: sslrepl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000075
          Read_Master_Log_Pos: 608
               Relay_Log_File: relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000075
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 608
              Relay_Log_Space: 403
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: Yes
           Master_SSL_CA_File: /usr/local/mysql/ssl/cacert.pem
           Master_SSL_CA_Path: /usr/local/mysql/ssl
              Master_SSL_Cert: /usr/local/mysql/ssl/mysql.crt
            Master_SSL_Cipher:
               Master_SSL_Key: /usr/local/mysql/ssl/mysql.key
        Seconds_Behind_Master: 2132
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1


输出信息为
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Master_SSL_Allowed: Yes
说明,基于ssl的配置已经成功


七、验证是否使用了ssl加密
Slave:
使用***epl用户登录mysql
#mysql --ssl-ca=/usr/local/mysql/ssl/cacert.pem --ssl-cert=/usr/local/mysql/ssl/mysql.crt --ssl-key=/usr/local/mysql/ssl/mysql.key -usslrepl -h172.16.4.111 -p135246
mysql> \s
--------------
mysql  Ver 14.12 Distrib 5.0.77, for redhat-linux-gnu (i386) using readline 5.1

Connection id:        3
Current database:   
Current user:        sslrepl@172.16.4.112
SSL:            Cipher in use is DHE-RSA-AES256-SHA
Current pager:        stdout
Using outfile:        ''
Using delimiter:    ;
Server version:        5.5.19-log MySQL Community Server (GPL)
Protocol version:    10
Connection:        172.16.4.111 via TCP/IP
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    latin1
Conn.  characterset:    latin1
TCP port:        3306
Uptime:            8 min 18 sec

Threads: 3  Questions: 47  Slow queries: 0  Opens: 34  Flush tables: 1  Open tables: 27  Queries per second avg: 0.094
--------------

输出信息:
SSL:            Cipher in use is DHE-RSA-AES256-SHA

说明是加密连接了。

由于SSL相关的配置写进了配置文件,则默认是加密连接的。
也可以使用--skip-ssl选项取消加密连接。


至此基于SSL加密的MySQL主从复制架构就配置成功了!

对于基于SSL机密的主主复制只需各自建立基于ssl加密的用户即可。
 

 

学海无涯,如有错误,欢迎指出!