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