133 lines
4.8 KiB
Plaintext
133 lines
4.8 KiB
Plaintext
|
socat tunnel for encrypted rsync SST
|
||
|
====================================
|
||
|
|
||
|
`wsrep_sst_rsync_tunnel` is an extension of the rsync-based [SST](http://galeracluster.com/documentation-webpages/glossary.html#term-state-snapshot-transfer)
|
||
|
implementation that ships with mariadb. Its purpose is to encrypt
|
||
|
communication between the donor and the joiner during an SST.
|
||
|
|
||
|
Encryption is implemented by means of a socat tunnel, using OPENSSL
|
||
|
addresses. It can be configured via the regular openssl flags exposed
|
||
|
by socat.
|
||
|
|
||
|
|
||
|
## How to configure the script
|
||
|
|
||
|
This SST script can configured by setting a few keys in your favorite
|
||
|
mariadb option file in addition to the usual galera settings.
|
||
|
|
||
|
[mysqld]
|
||
|
...
|
||
|
bind_address=<node-name>
|
||
|
wsrep_sst_method=rsync_tunnel
|
||
|
...
|
||
|
|
||
|
[sst]
|
||
|
tca=/path/to/your/ca-file.crt
|
||
|
tcert=/path/to/node/certificate.crt
|
||
|
tkey=/path/to/node/key.key
|
||
|
sockopt=<openssl-address-options-as-per-socat-manual>
|
||
|
|
||
|
When a joiner node requests an SST, `wsrep_sst_rsync_tunnel` uses
|
||
|
socat to listen to incoming SSL connections on port 4444 in lieu of
|
||
|
the original rsync daemon. Received data will be forwarded to the
|
||
|
rscynd daemon started locally to replicate the database.
|
||
|
|
||
|
When a donor node serves the SST, `wsrep_sst_rsync_tunnel` makes
|
||
|
a series of rsync calls that target a locally started socat daemon.
|
||
|
The daemon tunnels all rsync traffic into an encrypted SSL connection
|
||
|
that targets the joiner's end of the socat tunnel.
|
||
|
|
||
|
Encryption parameters are specified under the `[sst]` group in the
|
||
|
mariadb option file, where `tkey` and `tcert` are respectively the key
|
||
|
and the certificate that are used by both sides of the socat tunnel.
|
||
|
Each node typically has a different key and cert. Both key and
|
||
|
certificate can be combined into a single PEM file and referenced by
|
||
|
`tcert`. Option `tca` holds a list of the trusted signing
|
||
|
certificates.
|
||
|
|
||
|
In case you need to tweak the creation of the SSL connection, you can
|
||
|
pass valid socat options (as per socat manual) via the `sockopt` key.
|
||
|
For debugging purpose, the exact socat command that is being executed
|
||
|
shows up in the mariadb log file.
|
||
|
|
||
|
Note that socat verifies that the certificate's commonName matches
|
||
|
that of the host that is being targeted. The target name comes from
|
||
|
the value configured in `bind_address`, so it's important that it
|
||
|
matches the certificate's commonName. An IP address can be used for
|
||
|
`bind_address`, but you may get into trouble in case different
|
||
|
hostnames resolve to the same IP (e.g. multiple networks per host).
|
||
|
|
||
|
|
||
|
## Examples of use
|
||
|
|
||
|
Suppose you're running a 3-node galera cluster
|
||
|
`node1.my.cluster`, `node2.my.cluster`, `node3.my.cluster`.
|
||
|
|
||
|
### Scenario: using self-signed certificates
|
||
|
|
||
|
On each node, create a key and a certificate, and bundle them into a
|
||
|
single PEM file. For instance on `node1.my.cluster`:
|
||
|
|
||
|
openssl genrsa -out /tls/mysql-$(hostname -f).key 2048
|
||
|
openssl req -new -key /tls/mysql-$(hostname -f).key -x509 -days 365000 -subj "/CN=$(hostname -f)" -out /tls/mysql-$(hostname -f).crt -batch
|
||
|
cat /tls/mysql-$(hostname -f).key /tls/mysql-$(hostname -f).crt > /tls/mysql.pem
|
||
|
|
||
|
Then, on each node, create a cafile that will contain all the certs to
|
||
|
trust:
|
||
|
|
||
|
for n in node1.my.cluster node2.my.cluster node3.my.cluster; do
|
||
|
ssh $n 'cat /tls/mysql-$(hostname -f).crt' >> /tls/all-mysql.crt
|
||
|
done
|
||
|
|
||
|
Once you have those two files on each host, you can configure the SST
|
||
|
appropriately. For instance from `/etc/my.cnf.d/galera.cnf`:
|
||
|
|
||
|
[mysqld]
|
||
|
...
|
||
|
|
||
|
[sst]
|
||
|
tca=/tls/all-mysql.crt
|
||
|
tcert=/tls/mysql.pem
|
||
|
|
||
|
### Scenario: using self-signed certificates, without verification
|
||
|
|
||
|
By default, when socat tries to establish a SSL connection to a peer,
|
||
|
it also verifies that it can trust the peer's certificate. If for some
|
||
|
reason you need to disable that feature, you can amend the previous
|
||
|
configuration with a sockopt option:
|
||
|
|
||
|
[mysqld]
|
||
|
...
|
||
|
|
||
|
[sst]
|
||
|
tca=/tls/all-mysql.crt
|
||
|
tcert=/tls/mysql.pem
|
||
|
sockopt="verify=0"
|
||
|
|
||
|
The associated sockopt value is passed to socat when
|
||
|
the donor or the joiner configures his part of the tunnel.
|
||
|
|
||
|
Note: please do not do so in production, this is inherently insecure
|
||
|
as you will not verify the identity of the peer you're connecting to!
|
||
|
|
||
|
### Scenario: using certificates from a CA
|
||
|
|
||
|
Suppose you have a FreeIPA service which generated a key file and a
|
||
|
certificate file for the three galera nodes, respectively located at
|
||
|
/tls/mysql.key and /tls/mysql.crt.
|
||
|
|
||
|
Assuming that the certificate for the FreeIPA server is available at
|
||
|
/etc/ipa/ca.crt, you can configure you galera servers as follows:
|
||
|
|
||
|
[sst]
|
||
|
tca=/etc/ipa/ca.crt
|
||
|
tcert=/tls/mysql.crt
|
||
|
tkey=/tls/mysql.key
|
||
|
|
||
|
## License
|
||
|
|
||
|
Copyright © 2017 [Damien Ciabrini](https://github.com/dciabrin).
|
||
|
This work is derived from the original `wsrep_rsync_sst`, copyright
|
||
|
© 2010-2014 [Codership Oy](https://github.com/codership).
|
||
|
Released under the GNU GPLv2.
|