如何在Ubuntu上的MariaDB Galera群集中加密复制流量

之前,我们讨论了如何在Ubuntu上设置MariaDB Galera多主群集。 默认情况下,MariaDB Galera群集中的复制流量未加密。 本教程将向您展示如何启用TLS加密,以便群集中的节点可以通过公共Internet安全地相互通信。 Galera群集中有两种类型的复制流量:

  • 状态转移
  • 写集复制

什么是国家转移?

状态转移是将数据库从一个节点复制到另一个节点的过程。 发送数据的节点称为施主。 接收数据的节点称为连接器。 状态转移有两种:

  • 快照状态传输(SST):复制整个数据库
  • 增量状态传输(IST):仅复制数据修改

当新节点加入群集时,因为它不包含数据,所以使用SST(又名节点配置)。 当断开连接的节点重新加入群集时,将使用IST。

了解SST

有5种SST方法:

  • wsrep_sst_rsync:默认方法
  • wsrep_sst_mysqldump:最慢的方法
  • wsrep_sst_mariabackup:非阻塞方法
  • wsrep_sst_xtrabackup
  • wsrep_sst_xtrabackup-v2

同步 是默认的SST方法,并且是最快的方法。 建议您不要使用 xtrabackup 要么 xtrabackup-v2 方法,因为它们不适用于MariaDB 10.3或更高版本,并且不支持GTID和静态数据加密。

我个人更喜欢 mariabackup 因为它在状态转移期间不会阻塞施主节点,这是从xtrabackup方法继承的优势。 Rsync和mysqldump要求供体在传输过程中通过 flush tables with read lock 命令。 mariabackup SST方法是xtrabackup-v2 SST方法的分支,它依赖于 mariabackupsocat 命令行实用程序。

要将mariabackup设置为SST方法,请先安装 socatmariabackup 在群集中的每个节点和联接器节点上。

sudo apt install socat

如果您是从默认的Ubuntu存储库中安装MariaDB的,则可以从以下位置安装mariabackup实用程序: mariadb-client-10.1 包。

sudo apt install mariadb-client-10.1

如果从mariadb.org存储库安装了最新版本的MariaDB,则需要使用以下命令安装mariabackup。

sudo apt install mariadb-backup

然后将以下两行添加到 [mysqld] MariaDB配置文件的主单元,位于集群中的每个节点和联接器节点上。

[mysqld]
...
wsrep_sst_method = mariabackup
wsrep_sst_auth = mariabackup:your_password

第一行指定将mariabackup用于SST方法,第二行定义用于身份验证的用户名和密码。

接下来,在集群中已经存在的节点上登录MariaDB监视器,并创建数据库用户并授予必要的权限。 (请注意,您不需要在每个节点上运行以下命令。数据将自动复制到其他节点。)

create user 'mariabackup'@'localhost' identified by 'your_password';
grant reload, process, lock tables, replication client on *.* to 'mariabackup'@'localhost';

刷新特权表并退出;

flush privileges;

exit;

在每个节点上一个接一个地重新启动MariaDB服务器,然后在连接器节点上重新启动MariaDB服务器。

sudo systemctl restart mariadb

加密Mariabackup SST

您可以使用openssl创建自签名TLS证书,但是我将使用为Web服务器配置的现有“让我们加密TLS”证书。 要在mariabackup SST上启用TLS加密,请打开MariaDB主配置文件(/etc/mysql/mariadb.conf.d/50-server.cnf 要么 /etc/mysql/my.cnf),并添加以下几行 在文件末尾。 根据需要替换路径名。

[sst]
encrypt=4
tkey=/etc/letsencrypt/live/linuxbabe.com/privkey.pem
tcert=/etc/letsencrypt/live/linuxbabe.com/cert.pem
tca=/etc/letsencrypt/live/linuxbabe.com/chain.pem

encrypt 变量有5个可能的值:0、1、2、3、4。 0 表示加密被禁用。 123 不再工作了。 保存并关闭文件。 的 mysql 用户需要访问上述SSL文件的权限,因此您需要使用以下命令授予读取权限。

sudo setfacl -R -m "u:mysql:rx" /etc/letsencrypt/archive/

sudo setfacl -R -m "u:mysql:rx" /etc/letsencrypt/live/

请注意,您需要在集群中的所有节点上使用相同的TLS证书和私钥,然后重新启动整个Galera集群以使更改生效。

请注意,在SST期间, /var/lib/mysql/ 用户添加的目录将被删除。

了解IST

当断开连接的节点重新加入群集时,将使用IST。 群集中的所有节点都维护一个Galera缓存(GCache),又名写集缓存,其中包含节点提交的写集。 当断开连接的节点重新加入群集时,它会请求来自捐助者的GCache的增量状态传输。 IST不会锁定捐助者。

显然,IST比SST快,因为它仅传输修改。 但是,如果施主的GCache不足以存储联接程序所需的所有写集,则将启动SST。 为了避免SST,可以增加GCache的大小。 默认值为128MB,您可以在MariaDB监视器上使用以下命令进行检查。

show variables like 'wsrep_provider_options'G

与GCache相关的值如下:

gcache.dir = /var/lib/mysql/; gcache.keep_pages_size = 0; gcache.mem_size = 0; gcache.name = /var/lib/mysql//galera.cache; gcache.page_size = 128M; gcache.recover = no; gcache.size = 128M;

GCache文件位于 /var/lib/mysql/galera.cache 并且它的大小已预先分配。 要增加GCache的大小,您需要在其中添加以下行 [mysqld] MariaDB配置文件的单位。

wsrep_provider_options="gcache.size = 1G"

将1G替换为您首选的缓存大小。 您可以使用此指令计算自定义写集缓存大小。 还建议设置 gcache.recover 参数 yes,因此一个节点可以尝试在启动时恢复其Gcache并继续向其他加入节点提供IST。

wsrep_provider_options="gcache.size = 1G; gcache.recover = yes"

在群集中的每个节点上应用相同的配置,然后一次重新启动它们。

加密IST

我尝试使用“让我们加密TLS”证书加密IST通信,但是当节点加入群集时,我总是在错误日志文件中收到以下错误。

[ERROR] WSREP: handshake with remote endpoint ssl://xx.xx.xx.xx:4567 failed: asio.ssl:337047686: 'certificate verify failed' ( 337047686: 'error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed')

因此,我创建了一个自签名服务器证书和私钥。 步骤如下。

创建一个目录以保存SSL文件。

sudo mkdir /etc/ssl/mysql/

更改目录。

cd /etc/ssl/mysql/

生成CA密钥文件:

sudo openssl genrsa 2048 > ca-key.pem

生成CA证书文件:

sudo openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca.pem

您将需要回答一些问题。 我刚刚输入了国家代码和组织名称。

生成服务器密钥文件。 您还需要回答一些问题并输入密码来保护密钥。

sudo openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem

删除密码。

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

生成服务器证书文件:

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

然后使用以下命令将所有文件复制到集群中的其他节点: scp 实用程序,建议将它们存储在同一目录中(/etc/ssl/mysql/)。 还要确保mysql用户具有读取所有SSL文件的权限。

sudo chown mysql:mysql /etc/ssl/mysql/ -R
sudo chmod 400 /etc/ssl/mysql/*
sudo chmod 700 /etc/ssl/mysql/

之后,打开MariaDB主配置文件(/etc/mysql/mariadb.conf.d/50-server.cnf 要么 /etc/mysql/my.cnf),然后在 [mysqld] 单元。

wsrep_provider_options="socket.ssl_key=/etc/ssl/mysql/server-key.pem;socket.ssl_cert=/etc/ssl/mysql/server-cert.pem;socket.ssl_ca=/etc/ssl/mysql/ca.pem"

如果您还有其他wsrep提供程序选项,则需要将它们组合在一起,如下所示。

wsrep_provider_options="gcache.size = 1G; gcache.recover = yes;socket.ssl_key=/etc/ssl/mysql/server-key.pem;socket.ssl_cert=/etc/ssl/mysql/server-cert.pem;socket.ssl_ca=/etc/ssl/mysql/ca.pem"

配置集群中的每个节点,然后重新启动整个集群以使更改生效。 如果一切顺利,您的节点将能够加入群集,并且您可以在MariaDB日志中看到如下消息,表明IST已加密。 (IST使用TCP端口4568。)

2019-03-19 14:40:03 1 [Note] WSREP: IST sender using ssl
2019-03-19 14:40:03 0 [Note] WSREP: async IST sender starting to serve ssl://xx.xx.xx.xx:4568 sending 166613-167529

加密写集复制流量

写集复制是普通的同步复制,节点将数据修改发送到所有其他节点。 实际上,写集复制使用与IST相同的加密机制。 如果您为IST启用了TLS加密,则写集复制也会被加密,并且在MariaDB日志中会看到以下消息,表明写集复制已通过TLS保护。 (写集复制使用TCP端口4567。)

SSL handshake successful, remote endpoint ssl://xx.xx.xx.xx:4567 local endpoint ssl://xx.xx.xx.xx:37118 cipher: TLS_AES_256_GCM_SHA384 compression: none

结论

我希望本教程可以帮助您加密MariaDB Galera集群中的复制流量。 在下一个教程中,我们将看到如何将主从复制与MariaDB Galera集群结合在一起。 与往常一样,如果您发现这篇文章很有用,请订阅我们的免费新闻通讯以获取更多提示和技巧。 保重🙂

Sidebar