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