MariaDB Galera Clusterで、クライアントとの接続にSSLを利用することができるようなので、設定してみることにした。
調べていると、Galera Clusterのバージョンが10.0系と10.1系で設定方法が違うようだったが、今回は10.1系での設定を行う。

1.鍵ファイルの作成

まずは、Galera Cluster側で以下のコマンドを実行し、公開鍵の作成を行う。

openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
[root@BS-PUB-GALERA-01 ~]# openssl genrsa 2048 > ca-key.pem
Generating RSA private key, 2048 bit long modulus
.......................+++
......................................................................................+++
e is 65537 (0x10001)
[root@BS-PUB-GALERA-01 ~]# openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

次に、サーバ用・クライアント用それぞれの鍵ファイル、SSL証明書を作成する。

サーバ用

openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
[root@BS-PUB-GALERA-01 ~]# openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem
Generating a 2048 bit RSA private key
........................+++
..................................+++
writing new private key to 'server-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@BS-PUB-GALERA-01 ~]# openssl rsa -in server-key.pem -out server-key.pem
writing RSA key
[root@BS-PUB-GALERA-01 ~]# openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting CA Private Key

クライアント用

openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
[root@BS-PUB-GALERA-01 ~]# openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem
Generating a 2048 bit RSA private key
.........+++
................+++
writing new private key to 'client-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@BS-PUB-GALERA-01 ~]# openssl rsa -in client-key.pem -out client-key.pem
writing RSA key
[root@BS-PUB-GALERA-01 ~]# openssl x509 -req -in client-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting CA Private Key

最後に、以下のコマンドでサーバ・クライアントの鍵が問題ないかを確認する。
※「error 18 at 0 depth lookup:self signed certificate」とエラーが出る場合、CA証明書とサーバ・クライアントの鍵で同じ情報(未記入の場合も含む)が入っているのが原因。ここでは、CA証明書だけ「JP」を入れてる。

openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
[root@BS-PUB-GALERA-01 ~]# openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK

2.Galera Cluster & クライアントの設定ファイルを編集

鍵ファイルの作成が終わったら、クラスタを構成している各ノードにサーバ鍵を配布して、設定ファイルを編集する。
今回は、鍵ファイルは「/var/lib/mysql/cert」というディレクトリを作成し、そこに配布することとする。

設定ファイルの記述例は以下。
追記したところをハイライトで表示させている。

/etc/my.cnf.d/server.cnf

[mysqld]
bind-address=0.0.0.0
plugin-load-add=file_key_management.so
file_key_management
file_key_management_filename = /opt/key.enc
file_key_management_filekey = XXXXXX
file_key_management_encryption_algorithm=AES_CBC
ssl-ca = /var/lib/mysql/cert/ca-cert.pem
ssl-key = /var/lib/mysql/cert/server-key.pem
ssl-cert = /var/lib/mysql/cert/server-cert.pem

[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_provider_options="socket.ssl_key=/var/lib/mysql/cert/server-key.pem;socket.ssl_cert=/var/lib/mysql/cert/server-cert.pem;socket.ssl_ca=/var/lib/mysql/cert/ca-cert.pem"
binlog_format=ROW
wsrep_cluster_address='gcomm://'
wsrep_cluster_name='DBCLUSTER'
wsrep_node_name='DBCLUSTER-NODE1'
wsrep_node_address = XXX.XXX.XXX.XXX
general-log
general-log-file=queries.log
log-output=file

設定完了しサービス再起動したら、クライアント側でも鍵ファイルの設定を行う。
mysqlクライアント側の「/etc/my.cnf.d/client.cnf」で「[client]」配下に以下の内容を追記する。

ssl-ca = /PATH/ca-cert.pem
ssl-key = /PATH/client-key.pem
ssl-cert = /PATH/client-cert.pem

3.ユーザにSSLの使用設定

最後に、SSLを使用するユーザの権限設定を行う。
環境・SSL設定したいユーザに合わせ、以下のSQLを実行する。

GRANT ALL PRIVILEGES ON *.* TO ユーザ名@ホスト IDENTIFIED BY 'パスワード' REQUIRE SSL;
FLUSH PRIVILEGES;

これで、Galera ClusterでSSL接続ができるようになった。
一応、以下のSQLでSSLが有効になっているかを確認する。

SHOW STATUS LIKE 'Ssl_cipher'
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -pXXXXXXX -h XXX.XXX.XXX.XXX -e "SHOW STATUS LIKE 'Ssl_cipher'"
+---------------+---------------------------+
| Variable_name | Value                     |
+---------------+---------------------------+
| Ssl_cipher    | DHE-RSA-AES256-GCM-SHA384 |
+---------------+---------------------------+

tcpdumpでパケットキャプチャも行ったが、SSL化前は実行したSQL文もその結果も丸見えだったのが、SSL化以後は無事見えない状態になった。

SQLの実行結果

[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -pXXXXXXXX -h XXX.XXX.XXX.XXX -e "SELECT * FROM test"
+------+--------+
| id   | name   |
+------+--------+
|    1 | test   |
|    2 | test   |
|    3 | test   |
|    4 | test   |
|    5 | second |
|    5 | five   |
|    6 | six    |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
|    5 | five   |
+------+--------+

パケットキャプチャ

[root@BS-PUB-GFRONT-01 ~]# tcpdump port 3306 -X | grep -i five -C 4 #SSL化前
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
        0x0090:  0005 0000 04fe 0000 2200 0700 0005 0131  ........"......1
        0x00a0:  0474 6573 7407 0000 0601 3204 7465 7374  .test.....2.test
        0x00b0:  0700 0007 0133 0474 6573 7407 0000 0801  .....3.test.....
        0x00c0:  3404 7465 7374 0900 0009 0135 0673 6563  4.test.....5.sec
        0x00d0:  6f6e 6407 0000 0a01 3504 6669 7665 0600  ond.....5.five..
        0x00e0:  000b 0136 0373 6978 0700 000c 0135 0466  ...6.six.....5.f
        0x00f0:  6976 6507 0000 0d01 3504 6669 7665 0700  ive.....5.five..
        0x0100:  000e 0135 0466 6976 6507 0000 0f01 3504  ...5.five.....5.
        0x0110:  6669 7665 0700 0010 0135 0466 6976 6507  five.....5.five.
        0x0120:  0000 1101 3504 6669 7665 0700 0012 0135  ....5.five.....5
        0x0130:  0466 6976 6507 0000 1301 3504 6669 7665  .five.....5.five
        0x0140:  0700 0014 0135 0466 6976 6507 0000 1501  .....5.five.....
        0x0150:  3504 6669 7665 0700 0016 0135 0466 6976  5.five.....5.fiv
        0x0160:  6507 0000 1701 3504 6669 7665 0700 0018  e.....5.five....
        0x0170:  0135 0466 6976 6507 0000 1901 3504 6669  .5.five.....5.fi
        0x0180:  7665 0700 001a 0135 0466 6976 6507 0000  ve.....5.five...
        0x0190:  1b01 3504 6669 7665 0700 001c 0135 0466  ..5.five.....5.f
        0x01a0:  6976 6505 0000 1dfe 0000 2200            ive.......".
[root@BS-PUB-GFRONT-01 ~]# tcpdump port 3306 -X | grep -i five -C 4 #SSL化後
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
...該当する値がないため返ってこない...

これで、Galera Clusterへの接続でSSLを有効にすることができた。