【MySQL 8.0】搭建一个使用 SSL 加密的 MySQL 主从复制拓扑(基于 Binlog 行复制)

news2024/12/23 23:27:23

文章目录

  • 先决条件
  • 搭建
    • 配置源、副本服务器选项文件
  • 验证启用了 SSL 连接
  • 创建复制用户
  • 获取复制源服务器的二进制日志坐标
    • 配置复制源
    • 开启复制
  • 验证
  • 进阶

之前,我们一起搭建了一个极简 MySQL 主从复制拓扑(基于 Binlog 行复制),这是一个不安全的复制拓扑,优点是性能高。生产环境中核心数据库系统的首要任务是安全、稳定,其次才是性能,这叫做关键任务型(Mission-Critical)应用程序。这也是 Oracle 、DB2、MS SQL Server 三家曾经为什么能近乎垄断全球数据库生产环境市场的原因。

笔者最初是因为测试 Mycat2 而搭建了一个使用 SSL 加密的复制拓扑,没有采用 Mycat2 建议的非安全的复制拓扑。在调试成功后,又搭建了非安全的复制拓扑。

下面来一起学习一下如何搭建一个安全的MySQL 主从复制拓扑吧!


先决条件

  • 源(或主)主服务器开启 SSL 加密连接。
  • (建议)在副本(或从)服务器配置复制通道时必须使用 SSL 连接。
  • 配置复制源时必须设置 SOURCE_SSL=1 才能使用 SOURCE_SSL_CASOURCE_SSL_CAPATH(不建议使用) 、SOURCE_SSL_CERTSOURCE_SSL_KEY 这些参数。
  • 非安全的复制拓扑的先决条件要求。

搭建

配置源、副本服务器选项文件

即配置主、从服务器选项文件。

Source 服务器 /etc/my.cnf 配置如下:

[mysqld@mycat]
log_timestamps=SYSTEM
port=3307
socket=/var/lib/mysql/mycat/mysql.sock
tmpdir=/tmp
datadir=/var/lib/mysql/mycat
log_bin=bin-mycat.log
lower_case_table_names=1

log-error=/var/log/mysqld-mycat.log
slow-query-log-file=/var/log/mysqld_mycat-slow.log
pid-file=/var/run/mysqld/mysqld-mycat.pid

innodb_buffer_pool_size=128M
innodb_redo_log_capacity=100M
innodb_flush_log_at_trx_commit=1
sync_binlog=1

#replication for mycat
server_id=1
##SSL authority
ssl_ca=ca.pem
ssl_cert=server-cert.pem
ssl_key=server-key.pem
#require_secure_transport=ON

Replica 服务器 /etc/my.cnf 配置如下:

[mysqld@mycat]
log_timestamps=SYSTEM
port=3307
socket=/var/lib/mysql/mycat/mysql.sock
tmpdir=/tmp
datadir=/var/lib/mysql/mycat
log_bin=bin-mycat.log
lower_case_table_names=1

log-error=/var/log/mysqld-mycat.log
slow-query-log-file=/var/log/mysqld_mycat-slow.log
pid-file=/var/run/mysqld/mysqld-mycat.pid

innodb_buffer_pool_size=128M
innodb_redo_log_capacity=100M
innodb_flush_log_at_trx_commit=1
sync_binlog=1

#replication for mycat
server_id=2

配置完成后分别启动两个 MySQL 实例。

验证启用了 SSL 连接

使用 mysql 连接到 Source 服务器验证:

mysql> \s

出现 SSL: Cipher in use is ECDHE-RSA-AES128-GCM-SHA256 即证明使用了 SSL 加密连接。

在这里插入图片描述

虽然已经证明使用了 SSL 加密连接,但因为默认的 --ssl-mode=PREFERRED ,没有进行证书验证,无法防止中间人攻击(Man-in-the-middle Attacks)。所以,下面我们再使用 --ssl-mode=VERIFY_CA 验证一下。

先复制 Source 服务器上的 datadir 数据目录中的 ca.pemclient-cert.pemclient-key.pem 到 Replica 服务器上。

[root@ic-source mycat]$ scp ca.pem client-*.pem replica1:/usr/local/etc/cert_source/
ca.pem                                                                   100% 1147   506.2KB/s   00:00    
client-cert.pem                                                          100% 1192     1.1MB/s   00:00    
client-key.pem                                                           100% 1704     1.5MB/s   00:00   

注意,要修改 CA 文件的属主为 mysql 操作系统用户,否则在配置复制源时会报错。

[root@ic-replica1 lib]# chown -R mysql:mysql /usr/local/etc/cert_source/
[root@ic-replica1 lib]# ll /usr/local/etc/cert_source/
总用量 12
-rw-r--r-- 1 mysql mysql 1147 51 18:52 ca.pem
-rw-r--r-- 1 mysql mysql 1192 51 18:52 client-cert.pem
-rw------- 1 mysql mysql 1704 51 18:52 client-key.pem

然后在 Replcia 服务器上强制使用证书认证连接到 Source 服务器上的 MySQL 实例。

注意
ssl-* 这类 SSL 选项的值是指路径,需要使用绝对路径或相对于当前命令行所在目录 $PWD 的相对目录。因而,使用 mysql 客户端连接到 MySQL 服务器时需要 cd CA文件所在目录 ,或使用绝对路径。

例如,我的当前目录是 /var/lib ,SSL 参数使用绝对路径,执行:

[root@ic-replica1 lib]# pwd
/var/lib
[root@ic-replica1 lib]# mysql -uroot -p -P3307 -hsource --ssl-mode=verify_ca --ssl-ca=/usr/local/etc/cert_source/ca.pem --ssl-cert=/usr/local/etc/cert_source/client-cert.pem --ssl-key=/usr/local/etc/cert_source/client-key.pem -e '\s'
Enter password: 
--------------
mysql  Ver 8.0.31 for Linux on x86_64 (MySQL Community Server - GPL)

Connection id:          22938
Current database:
Current user:           root@replica1
SSL:                    Cipher in use is ECDHE-RSA-AES128-GCM-SHA256
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         8.0.31 MySQL Community Server - GPL
Protocol version:       10
Connection:             source via TCP/IP
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    utf8mb4
Conn.  characterset:    utf8mb4
TCP port:               3307
Binary data as:         Hexadecimal
Uptime:                 3 days 17 hours 30 min 17 sec

Threads: 6  Questions: 17832  Slow queries: 3  Opens: 429  Flush tables: 3  Open tables: 338  Queries per second avg: 0.055
--------------

无报错即验证成功。

如果不指定证书,会报错:

[root@ic-replica1 lib]# mysql -uroot -p -P3307 -hsource --ssl-mode=verify_ca  -e '\s'
Enter password: 
ERROR 2026 (HY000): SSL connection error: CA certificate is required if ssl-mode is VERIFY_CA or VERIFY_IDENTITY

创建复制用户

此处我额外创建了一个角色 role_repl 以复用。

mysql> create role `role_repl`;
Query OK, 0 rows affected (0.01 sec)
GRANT REPLICATION SLAVE ON *.* TO `role_repl` WITH GRANT OPTION;
mysql> create user repl1 identified by 'Repl?111' default role `role_repl`;
Query OK, 0 rows affected (0.00 sec)

mysql> show grants for repl1 using `role_repl`;
+-----------------------------------------------------------------+
| Grants for repl1@%                                              |
+-----------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO `repl1`@`%` WITH GRANT OPTION |
| GRANT `role_repl`@`%` TO `repl1`@`%`                            |
+-----------------------------------------------------------------+
2 rows in set (0.00 sec)

获取复制源服务器的二进制日志坐标

即获取主服务器的二进制日志坐标。

mysql> SHOW MASTER STATUS\G
*************************** 1. row ***************************
             File: bin-mycat.000009
         Position: 4029
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.01 sec)

配置复制源

在从服务器上配置复制源为主服务器。

mysql> change replication source to
    -> source_host='source',
    -> source_port=3307,
    -> source_user='repl1',
    -> source_password='Repl?111',
    -> source_log_file='bin-mycat.000009',
    -> source_log_pos=4029,
    -> source_ssl=1,
    -> source_ssl_ca='/usr/local/etc/cert_source/ca.pem',
    -> source_ssl_cert='/usr/local/etc/cert_source/client-cert.pem',
    -> source_ssl_key='/usr/local/etc/cert_source/client-key.pem';
Query OK, 0 rows affected, 2 warnings (0.00 sec)

开启复制

在从服务器上开启复制。

mysql> start replica;
Query OK, 0 rows affected (0.01 sec)

mysql> show replica status\G
*************************** 1. row ***************************
             Replica_IO_State: Waiting for source to send event
                  Source_Host: source
                  Source_User: repl1
                  Source_Port: 3307
                Connect_Retry: 60
              Source_Log_File: bin-mycat.000009
          Read_Source_Log_Pos: 4029
               Relay_Log_File: ic-replica1-relay-bin.000002
                Relay_Log_Pos: 326
        Relay_Source_Log_File: bin-mycat.000009
           Replica_IO_Running: Yes
          Replica_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_Source_Log_Pos: 4029
              Relay_Log_Space: 542
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Source_SSL_Allowed: Yes
           Source_SSL_CA_File: /usr/local/etc/cert_source/ca.pem
           Source_SSL_CA_Path: 
              Source_SSL_Cert: /usr/local/etc/cert_source/client-cert.pem
            Source_SSL_Cipher: 
               Source_SSL_Key: /usr/local/etc/cert_source/client-key.pem
        Seconds_Behind_Source: 0
Source_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Source_Server_Id: 1
                  Source_UUID: fefc2e34-d95f-11ed-9382-000c298d6cb9
             Source_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
    Replica_SQL_Running_State: Replica has read all relay log; waiting for more updates
           Source_Retry_Count: 86400
                  Source_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Source_SSL_Crl: 
           Source_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Source_TLS_Version: 
       Source_public_key_path: 
        Get_Source_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

结果如下图所示,没有报错即搭建成功。
在这里插入图片描述

验证

在主服务器上查看有哪些副本服务器、建库、建表:

mysql> show replicas;
+-----------+------+------+-----------+--------------------------------------+
| Server_Id | Host | Port | Source_Id | Replica_UUID                         |
+-----------+------+------+-----------+--------------------------------------+
|         2 |      | 3307 |         1 | 72e8f54a-d965-11ed-8c0b-000c298656b1 |
+-----------+------+------+-----------+--------------------------------------+
1 row in set (0.00 sec)

mysql> create database mycat;
Query OK, 1 row affected (0.00 sec)

mysql> use mycat;
Database changed
mysql> create table m1(id int primary key);
Query OK, 0 rows affected (0.06 sec)

mysql> insert into m1 values (1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

在从服务器上验证是否同步成功:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mycat              |
| mysql              |
| performance_schema |
| sys                |
| testdb             |
+--------------------+
6 rows in set (0.01 sec)

mysql> use mycat;
Database changed
mysql> table m1;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
+----+
3 rows in set (0.00 sec)

可以看到已经同步成功了。

进阶

上面我们并没有限制复制用户强制使用 SSL 加密连接。在副本上要求加密连接并不能确保源需要来自副本的加密连接。如果要确保源只接受使用加密连接连接的副本,应使用 REQUIRE SSL 。例如:

先在 Replica 服务器上关闭复制:

mysql> stop replica;
Query OK, 0 rows affected, 1 warning (0.00 sec)

再在 Source 服务器上创建用户

mysql> ALTER USER repl1 REQUIRE SSL;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status\G
*************************** 1. row ***************************
             File: bin-mycat.000011
         Position: 1352
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.00 sec)

在 Replica 服务器上重新配置复制源的日志起始位置,并启动,查看有无报错:

mysql> change replication source to source_log_pos=1352;
Query OK, 0 rows affected (0.04 sec)

mysql> start replica;
Query OK, 0 rows affected (0.04 sec)

mysql> show replica status\G
*************************** 1. row ***************************
             Replica_IO_State: Waiting for source to send event
                  Source_Host: source
                  Source_User: repl1
                  Source_Port: 3307
                Connect_Retry: 60
              Source_Log_File: bin-mycat.000011
          Read_Source_Log_Pos: 1352
               Relay_Log_File: ic-replica1-relay-bin.000002
                Relay_Log_Pos: 326
        Relay_Source_Log_File: bin-mycat.000011
           Replica_IO_Running: Yes
          Replica_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_Source_Log_Pos: 1352
              Relay_Log_Space: 542
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Source_SSL_Allowed: Yes
           Source_SSL_CA_File: /usr/local/etc/cert_source/ca.pem
           Source_SSL_CA_Path: 
              Source_SSL_Cert: /usr/local/etc/cert_source/client-cert.pem
            Source_SSL_Cipher: 
               Source_SSL_Key: /usr/local/etc/cert_source/client-key.pem
        Seconds_Behind_Source: 0
Source_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Source_Server_Id: 1
                  Source_UUID: fefc2e34-d95f-11ed-9382-000c298d6cb9
             Source_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
    Replica_SQL_Running_State: Replica has read all relay log; waiting for more updates
           Source_Retry_Count: 86400
                  Source_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Source_SSL_Crl: 
           Source_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Source_TLS_Version: 
       Source_public_key_path: 
        Get_Source_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

可以看到没有报错。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/481945.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

请问这个网址怎么用httpx 把json数据取出来

点击上方“Python爬虫与数据挖掘”,进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 空山新雨后,天气晚来秋。 大家好,我是皮皮。 一、前言 前几天在Python铂金群【gyx】问了一个Python网络爬虫处理的问题&#xf…

【JavaEE】认识线程

目录 1、什么是线程 2、为什么引入线程 2.1、线程的优缺点 3、CPU的工作原理 4、线程和进程的关系 4.1、线程和进程的入口函数 4.2、线程独享的资源 1、什么是线程 一个进程中可以有一个或者多个线程,每个线程都是一个独立的执行流。多个线程之间,也…

嵌入式开发--无刷电机学习3--帕克变换

帕克变换的物理意义 前面说到克拉克变换的物理意义,是将三相定子线圈产生磁场的过程,等效为2个正交放置的线圈,来产生同样的磁场。通过控制这两个正交线圈即可等效控制三相定子线圈。 还有一个问题,定子线圈产生的磁场&#xff…

集群与存储

所谓集群就是通过高速网络将很多服务器集中起来一起提供一种服务,在客户端看起来就是只有一个服务器 任务调度是集群中的核心系统 HPC高性能计算集群 LB负载均衡 HA高可用 LVS工作模式 NAT 网络地址转换 -m DR 路由模式 节点需要VIP -g TUN 隧道模式 -i 调度…

「Codeforces」D. Big Brush

D. Big Brush https://codeforces.com/contest/1638/problem/D 题目描述 给你一张 n m n\times m nm 大的网格纸,你有一把 2 2 2 \times 2 22 的刷子,每次只能涂满这么多,即 ( i , j ) 、 ( i 1 , j ) 、 ( i , j 1 ) 、 ( i 1 , j …

第二十二章 光照贴图

光照贴图过程将预先计算场景中静态物体表面的亮度,并将结果存储在称为“光照贴图”的纹理中供以后使用。光照贴图可以包含直接光照和间接光照,以及阴影效果。但是,烘焙到光照贴图中的数据无法在运行时更改,这就是为什么移动静态物…

Python入门教程+项目实战-12.1节: 字典的基础概念

目录 12.1.1 理解字典类型 12.1.2 字典的类型名 12.1.3 字典的定义 12.1.4 在循环中遍历字典 12.1.5 字典的键类型 12.1.6 知识要点 12.1.7 系统学习python 12.1.1 理解字典类型 在日常生活中,我们常常会接触到“字典”这种数据类型,例如一本书籍…

排序篇:直接插入、希尔、直接选择和堆排序(C语言)

目录 前言: 一:插入排序 (1)直接插入排序 基础思路(有个印象就行,主要看单趟): 单趟排序: 完整排序: 时间复杂度分析: (2)希尔排序 基础思路(有个印象就行,主要看单趟)&#…

【2023 年第十三届 MathorCup 高校数学建模挑战赛】D 题 航空安全风险分析和飞行技术评估问题 27页论文及代码

【2023 年第十三届 MathorCup 高校数学建模挑战赛】D 题 航空安全风险分析和飞行技术评估问题 27页论文及代码 1 题目 D 题 航空安全风险分析和飞行技术评估问题 飞行安全是民航运输业赖以生存和发展的基础。随着我国民航业的快速发展,针对飞行安全问题的研究显得…

网络编程 总结一

一、网络基础: 概念:1> 网络编程的本质就是进程间的通信,只不过进程分布在不同的主机上 2>在跨主机传输过程中,需要确定通信协议后,才可以通信 1. OSI体系结构(重点) 定义7层模型&…

针对近日ChatGPT账号大批量封禁的理性分析

文 / 高扬 这两天不太平。 3月31号,不少技术圈的朋友和我闲聊说,ChatGPT账号不能注册了。 我不以为然,自己有一个号足够了,并不关注账号注册的事情。 后面又有不少朋友和我说ChatGPT账号全部不能注册了,因为老美要封锁…

Java笔记_15(不可变集合、Stream流、方法引用)

Java笔记_15 一、创建不可变集合1.1、创建不可变集合的应用场景1.2、创建不可变集合的书写格式 二、Stream流2.1、体验Stream流2.2、Stream流的思想和获取Stream流2.3、Stream流的中间方法2.4、Stream流的终结方法2.5、收集方法collect2.6、练习-数字过滤2.7、练习-字符串过滤并…

Python词云图的制作与案例分享(包含 wordcloud 和 jieba库)

一、基本知识 Python 有很多可用于制作词云图的库,其中比较常用的有 wordcloud 和 jieba。 wordcloud 是一个用于生成词云图的 Python 库,其使用了 Python 的 PIL 库和 numpy 库。您可以使用 pip 命令来安装 wordcloud 库: pip install wo…

第12章 项目沟通管理和干系人管理

文章目录 12.1.2 沟通的方式 404沟通管理计划的编制过程12.2.2 制订沟通管理计划的工具 4114、沟通方法 12.3.2 管理沟通的工具 41312.4.2 控制沟通的技术和方法 4163、会议 12.5.1 项目干系人管理所涉及的过程 420项目干系人管理的具体内容:(1&#xff…

从“青铜”到“王者”,制造企业的数字化闯关记

打过游戏的朋友可能有一个常识,越是精彩纷呈、奖励丰厚的副本,越是需要召集队友一同组团闯关。很多实体企业在数字化转型中,也不会单打独斗,一把手会先找咨询公司对企业内外情况进行调研、梳理、规划,提出一个顶层规划…

科学计算库—numpy随笔【五一创作】

文章目录 8.1、numpy8.1.1、为什么用 numpy?8.1.2、numpy 数据类型推理8.1.3、numpy 指定长度数组快速创建8.1.4、numpy 哪个是行、列?8.1.5、numpy 如何进行数据类型转换?8.1.6、numpy 有几种乘法?8.1.7、numpy 索引和切片操作8.…

2023年前端面试题汇总-代码输出篇

1. 异步 & 事件循环 1. 代码输出结果 const promise new Promise((resolve, reject) > {console.log(1);console.log(2); }); promise.then(() > {console.log(3); }); console.log(4); 输出结果如下: 1 2 4 promise.then 是微任务,它…

【今日重磅—国产大模型首批内测机会来了】什么是讯飞星火,如何获得内测和使用方法

♥️作者:白日参商 🤵‍♂️个人主页:白日参商主页 ♥️坚持分析平时学习到的项目以及学习到的软件开发知识,和大家一起努力呀!!! 🎈🎈加油! 加油&#xff01…

数电实验:Quartus II 软件使用 (八进制计数器和全加器)

一、实验目的: 1.熟悉可编程逻辑器件的设计工具Quartus II 软件的使用。 2.熟悉FPGA开发实验系统的软件环境,掌握各个菜单和图标的作用和功能。 二、实验内容 (1)以74160实现八进制计数器为例,学Quartus II 软件的…

【手撕代码系列】JS手写实现Promise.all

Promise.all() 方法接收一个 Promise 对象数组作为参数,返回一个新的 Promise 对象。该 Promise 对象在所有的 Promise 对象都成功时才会成功,其中一个 Promise 对象失败时,则该 Promise 对象立即失败。 本篇博客将手写实现 Promise.all() 方…