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

・10 分钟阅读

默认情况下,MariaDB Galera集群中的复制通信未加密,本教程将向你展示如何启用TLS加密,以便集群中的节点可以通过公共Internet安全地彼此通信,Galera集群中有2种复制通信:

  • 状态转移
  • 写集复制
  • 什么是状态转移?

    状态转移是将数据库从一个节点复制到另一个节点的过程。有两种状态转换:

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

    有5个SST方法:

  • wsrep_sst_rsync:默认方法
  • wsrep_sst_mysqldump:最慢的方法
  • wsrep_sst_mariabackup:非阻塞方法
  • wsrep_sst_xtrabackup
  • wsrep_sst_xtrabackup-v2
  • Rsync是默认的SST方法,它是最快的,建议不要使用xtrabackup或xtrabackup-v2方法,因为它们不能与MariaDB 10.3或更高版本一起使用,并且它们不支持GTID和静态数据加密。

    Rsync和mysqldump要求在传输过程中通过 flush tables with read lock 命令。 mariabackup SST方法是xtrabackup-v2 SST方法的分支,它依赖于mariabackup和socat命令行实用程序。

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

    sudo apt install socat

    如果从默认的Ubuntu存储库安装MariaDB,那么你可以从mariadb-client-10.1包安装mariabackup工具。

    sudo apt install mariadb-client-10.1

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

    sudo apt install mariadb-backup

    然后,在集群中的每个和joiner MariaDB配置文件的[mysqld]单元中添加以下两行。

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

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

    (请注意,您不需要在每个节点上运行以下命令。数据将自动复制到其他节点。 )

    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服务器配置的现有let's Encrypt 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,表示加密被禁用,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集群以便让更改生效。

    理解IST

    当断开连接的节点重新加入群集时,将使用IST。

    为了避免SST,可以增加GCache的大小,默认值为mb,你可以在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,因此node可以尝试恢复它Gcache,以便在启动,并继续时服务。

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

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

    加密IST

    我尝试使用let's Encrypt TLS证书来加密IST流量,但是当node加入集群时,我总是在错误日志文件中得到以下错误。

    [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启用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集群中的复制流量。

    Huangzhongbang profile image