В том случае, если вы эксплуатируете кластер Galera с узлами, работающими в разных центрах обработки данных, соединение между которыми устанавливается по незащищенному каналу, вам необходимо обеспечить защиту данных, передаваемых между клиентами и кластером и между узлами кластера.
Кластер Galera поддерживает шифрование соединения с использованием протокола SSL. В статье мы рассмотрим, как зашифровать все соединения кластера с помощью SSL-шифрования.
Все настройки будут выполняться в реализации MySQL MariaDB. Если у вас уже есть настроенный кластер Galera с использованием MariaDB, читайте дальше. Если же вы только планируете развернуть кластер Galera, перейдите к нашему руководству для популярных дистрибутивов Linux — CentOS 7, Debian 9, Ubuntu 16.04 и 18.04.
Проверим текущую конфигурацию SSL:
$ mysql -uroot -e "SHOW VARIABLES LIKE 'have_ssl';" +---------------+----------+ | Variable_name | Value | +---------------+----------+ | have_ssl | DISABLED | +---------------+----------+
Как можно видеть, режим SSL сейчас отключен. Чтобы полностью защитить все соединения кластера необходимо шифровать:
- SSL-трафик репликации кластера Galera;
- трафик переноса снимков состояния;
- трафик между серверами базы данных и клиентом.
С помощью OpenSSL сгенерируем сертификаты и ключи SSL. Создадим каталоги для ключей:
sudo mkdir -p /etc/mysql/ssl cd /etc/mysql/ssl
Ключ и сертификат CA
openssl genrsa 2048 | sudo tee ca-key.pem
Сгенерируем сертификат CA:
sudo openssl req -new -x509 -nodes -days 3600 -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) [AU]:RU State or Province Name (full name) [Some-State]:Tomskaya Locality Name (eg, city) []:Tomsk Organization Name (eg, company) [Internet Widgits Pty Ltd]:NetPoint Organizational Unit Name (eg, section) []:NOC Common Name (e.g. server FQDN or YOUR name) []:CA Email Address []:support@netpoint-dc.com
Ключ и сертификат сервера
Внимание: Атрибут Common Name для ключа сервера должен отличаться от Common Name для ключа CA:
sudo openssl req -newkey rsa:2048 -days 3600 \ -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) [AU]:RU State or Province Name (full name) [Some-State]:Tomskaya Locality Name (eg, city) []:Tomsk Organization Name (eg, company) [Internet Widgits Pty Ltd]:NetPoint Organizational Unit Name (eg, section) []:NOC Common Name (e.g. server FQDN or YOUR name) []:Server Email Address []:support@netpoint-dc.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
Удалим из него парольную фразу:
sudo openssl rsa -in server-key.pem -out server-key.pem
Создадим сертификат сервера:
sudo openssl x509 -req -in server-req.pem -days 3600 \ -CA ca-cert.pem -CAkey ca-key.pem \ -set_serial 01 -out server-cert.pem
Ключ и сертификат клиента
Внимание: Атрибут Common Name для ключа клиента должен отличаться от Common Name для ключа сервера и ключа CA:
sudo openssl req -newkey rsa:2048 -days 3600 \ -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) [AU]:RU State or Province Name (full name) [Some-State]:Tomskaya Locality Name (eg, city) []:Tomsk Organization Name (eg, company) [Internet Widgits Pty Ltd]:NetPoint Organizational Unit Name (eg, section) []:NOC Common Name (e.g. server FQDN or YOUR name) []:Client Email Address []:support@netpoint-dc.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
Удалим пароль из ключа клиента:
sudo openssl rsa -in client-key.pem -out client-key.pem
Создадим SSL-сертификат клиента:
sudo openssl x509 -req -in client-req.pem -days 3600 \ -CA ca-cert.pem -CAkey ca-key.pem \ -set_serial 01 -out client-cert.pem
Выполним проверку корректности сертификатов:
openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem server-cert.pem: OK client-cert.pem: OK
Если проверка прошла успешно, необходимо скопировать сертификаты на оставшиеся узлы в кластере и установить корректные права доступа на каталоги:
sudo chown -R mysql:mysql /etc/mysql/ssl
Настройка защиты трафика базы данных и клиентских соединений
Добавим следующие строки в конфигурационный файл my.cnf
или другой .cnf
в каталоге /etc/mysql/conf.d
, если вы предпочитаете модульную конфигурацию.
# Сервер MySQL [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] ssl-ca=/etc/mysql/ssl/ca-cert.pem ssl-cert=/etc/mysql/ssl/client-cert.pem ssl-key=/etc/mysql/ssl/client-key.pem
Защита трафика репликации
Определите пути к ключу, сертификату и файлам центра сертификации. Кластер Galera будет использовать эти файлы для шифрования и дешифрования трафика репликации.
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"
Активация SSL для переноса состояния (SST) с помощью MySQLDump
Создайте пользователя, который требует SSL для подключения.
MariaDB [(none)]> CREATE USER 'sstssl'@'localhost' IDENTIFIED BY 'secret'; 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)
Мы будем использовать этого пользователя для репликации. Измените
в файле конфигурации my.cnf.wsrep_sst_auth
wsrep_sst_auth="sstssl:secret"
Теперь необходимо остановить и заново запустить весь кластер. Если перезапустить только один узел во время работы других, он не сможет присоединиться к существующему кластеру. Вы увидите ошибки, подобные приведенным ниже, в журнале ошибок MySQL.
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')
Активация SSL для переноса состояния (SST) с помощью Rsync
Используйте специальный обработчик secure_rsync. Сам обработчик и инструкцию по его применению можно найти в GitHub-репозитории проекта.
По сути, в настройках изменится только метод осуществления SST:
wsrep_sst_method=secure_rsync
Активация SSL для переноса состояния (SST) с помощью Percona Xtrabackup
Если вы используете Xtrabackup, то данная утилита уже имеет настройки для SSL. В конфигурационный файл my.cnf
добавьте:
[sst] encrypt=4 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 -uroot -e "SHOW VARIABLES LIKE 'have_ssl';"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | have_ssl | YES | +---------------+-------+ mysql -uroot -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster%';"; +--------------------------+--------------------------------------+ | Variable_name | Value | +--------------------------+--------------------------------------+ | wsrep_cluster_conf_id | 3 | | wsrep_cluster_size | 3 | | wsrep_cluster_state_uuid | 15a6ec3c-648e-11e9-ae72-0715b07d89d9 | | wsrep_cluster_status | Primary | | wsrep_cluster_weight | 3 | +--------------------------+--------------------------------------+
Клиентские подключения
После примененных настроек все клиентские подключения будут осуществляться с использованием шифрования SSL. Для успешного подключения клиента к серверу, он должен иметь доступ к ключам, которые указаны в его настройках:
[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
Вы можете генерировать для разных клиентов различные ключи, как мы делали ранее, если этого требует ваша политика безопасности. Обратите внимание, что SSL используется только для шифрования трафика, но не для аутентификации.