As database security is very important you must ensure that traffic between nodes is fully secured.
Galera Cluster supports encrypted connections between nodes using SSL protocol and in this post I want to show how to encrypt all cluster communication using SSL encryption.
Check current SSL configuration.
MariaDB [(none)]> SHOW VARIABLES LIKE 'have_ssl'; +---------------+----------+ | Variable_name | Value | +---------------+----------+ | have_ssl | DISABLED | ###==> SSL Disabled +---------------+----------+ 1 row in set (0.01 sec) MariaDB [(none)]> status -------------- mysql Ver 15.1 Distrib 10.0.29-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2 Connection id: 56 Current database: Current user: marko@localhost SSL: Not in use ###==> SSL is not used Current pager: stdout Using outfile: '' Using delimiter: ; Server: MariaDB Server version: 10.0.17-MariaDB-1~trusty-wsrep-log mariadb.org binary distribution, wsrep_25.10.r4144 Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: utf8 Db characterset: utf8 Client characterset: utf8 Conn. characterset: utf8 UNIX socket: /var/run/mysqld/mysqld.sock Uptime: 7 days 42 min 29 sec Threads: 52 Questions: 10 Slow queries: 0 Opens: 0 Flush tables: 1 Open tables: 63 Queries per second avg: 0.000 --------------SSL is currently disabled.
To fully secure all cluster communication we must SSL-encrypt replication traffic within Galera Cluster, State Snapshot Transfer and traffic between database server and client.
We will create SSL Certificates and Keys using openssl.
# Create new folder for certificates mkdir -p /etc/mysql/ssl cd /etc/mysql/ssl # Create CA certificate # Generate CA key openssl genrsa 2048 > ca-key.pem # Using the CA key, generate the CA certificate openssl req -new -x509 -nodes -days 3600 \ > -key ca-key.pem -out ca-cert.pem ----- Country Name (2 letter code) [AU]:HR State or Province Name (full name) [Some-State]:Zagreb Locality Name (eg, city) []:Zagreb Organization Name (eg, company) [Internet Widgits Pty Ltd]:Dummycorp Organizational Unit Name (eg, section) []:IT Common Name (e.g. server FQDN or YOUR name) []:myu1.localdomain Email Address []:marko@dummycorp.com # Create server certificate, remove passphrase, and sign it # Create the server key openssl req -newkey rsa:2048 -days 3600 \ > -nodes -keyout server-key.pem -out server-req.pem ----- Country Name (2 letter code) [AU]:HR State or Province Name (full name) [Some-State]:Zagreb Locality Name (eg, city) []:Zagreb Organization Name (eg, company) [Internet Widgits Pty Ltd]:Dummycorp Organizational Unit Name (eg, section) []:IT ##==> Use the ".localdomain" only on the first certificate. Common Name (e.g. server FQDN or YOUR name) []:myu1 Email Address []:marko@dummycorp.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:secretpassword An optional company name []: # Process the server RSA key openssl rsa -in server-key.pem -out server-key.pem # Sign the server certificate openssl x509 -req -in server-req.pem -days 3600 \ > -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem # Create client certificate, remove passphrase, and sign it # Create the client key openssl req -newkey rsa:2048 -days 3600 \ > -nodes -keyout client-key.pem -out client-req.pem ----- Country Name (2 letter code) [AU]:HR State or Province Name (full name) [Some-State]:Zagreb Locality Name (eg, city) []:Zagreb Organization Name (eg, company) [Internet Widgits Pty Ltd]:Dummycorp Organizational Unit Name (eg, section) []:IT Common Name (e.g. server FQDN or YOUR name) []:myu1 Email Address []:marko@dummycorp.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:secretpassword An optional company name []: # Process client RSA key openssl rsa -in client-key.pem -out client-key.pem # Sign the client certificate openssl x509 -req -in client-req.pem -days 3600 \ > -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem # Verify certificates openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem server-cert.pem: OK client-cert.pem: OK
If verification succeeds copy certificates to all nodes in the cluster.
Set mysql as owner of the files.
# Copy scp -r /etc/mysql/ssl node1:/etc/mysql scp -r /etc/mysql/ssl node2:/etc/mysql scp -r /etc/mysql/ssl node3:/etc/mysql # Change owner node1: chown -R mysql:mysql /etc/mysql/ssl node2: chown -R mysql:mysql /etc/mysql/ssl node3: chown -R mysql:mysql /etc/mysql/ssl
Secure database and client connections.
Add following lines in my.cnf configuration file.
# MySQL Server [mysqld] ssl-ca=/etc/mysql/ssl/ca-cert.pem ssl-cert=/etc/mysql/ssl/server-cert.pem ssl-key=/etc/mysql/ssl/server-key.pem # MySQL Client [client] ssl-ca=/etc/mysql/ssl/ca-cert.pem ssl-cert=/etc/mysql/ssl/client-cert.pem ssl-key=/etc/mysql/ssl/client-key.pem
Secure replication traffic.
Define paths to the key, certificate and certificate authority files. Galera Cluster will use this files for encrypting and decrypting replication traffic.
wsrep_provider_options="socket.ssl_key=/etc/mysql/ssl/server-key.pem;socket.ssl_cert=/etc/mysql/ssl/server-cert.pem;socket.ssl_ca=/etc/mysql/ssl/ca-cert.pem"
Enable SSL for mysqldump and Xtrabackup.
Create user which requires SSL for connection.
MariaDB [(none)]> CREATE USER 'sstssl'@'localhost' IDENTIFIED BY 'sstssl'; Query OK, 0 rows affected (0.03 sec) MariaDB [(none)]> GRANT PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'sstssl'@'localhost' REQUIRE ssl; Query OK, 0 rows affected (0.02 sec) MariaDB [(none)]> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
I will use this user for replication.
Change wsrep_sst_auth in my.cnf configuration file.
wsrep_sst_auth="sstssl:sstssl"
Now we must recreate whole cluster.
If I restart only one node, while others are running, node won't join to existing cluster.
You can notice this errors in mysql error log.
171017 3:20:29 [ERROR] WSREP: handshake with remote endpoint ssl://192.168.56.22:4567 failed: asio.ssl:336031996: 'unknown protocol' ( 336031996: 'error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol') 171017 3:20:29 [ERROR] WSREP: handshake with remote endpoint ssl://192.168.56.23:4567 failed: asio.ssl:336031996: 'unknown protocol' ( 336031996: 'error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol')Shutdown the cluster and bootstrap it.
Check.
MariaDB [(none)]> status -------------- mysql Ver 15.1 Distrib 10.0.29-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2 Connection id: 87 Current database: Current user: marko@localhost SSL: Cipher in use is DHE-RSA-AES256-SHA ###==> SSL is used Current pager: stdout Using outfile: '' Using delimiter: ; Server: MariaDB Server version: 10.0.17-MariaDB-1~trusty-wsrep-log mariadb.org binary distribution, wsrep_25.10.r4144 Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: utf8 Db characterset: utf8 Client characterset: utf8 Conn. characterset: utf8 UNIX socket: /var/run/mysqld/mysqld.sock Uptime: 1 min 4 sec Threads: 52 Questions: 676 Slow queries: 16 Opens: 167 Flush tables: 1 Open tables: 31 Queries per second avg: 10.562 -------------- MariaDB [(none)]> SHOW VARIABLES LIKE 'have_ssl'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | have_ssl | YES | +---------------+-------+ 1 row in set (0.01 sec)
REFERENCES
6.4.3.2 Creating SSL Certificates and Keys Using openssl
MySQL : Configure SSL Connections
Hi there, It is really helpful.
ReplyDeleteI want to share another information, i hope you don't mind because this is for safety purpose. There is an app which helps us to keep our communication safe and secure and prevent it from unauthorized access.
you can check from EnKryptonite app. Download from:App store & Google Play
Hi,
ReplyDeleteI've followed your aforementioned guide to enable ssl encryption for mariadb galera cluster(2 node) but still when I checked MariaDB status it shows "SSL: Not in use". Kindly advise.
5 stars. Thanks
ReplyDelete