ИТ Блог. Администрирование серверов на основе Linux (Ubuntu, Debian, CentOS, openSUSE)

Как настроить SSL/TLS для MySQL на Ubuntu 16.04

MySQL является наиболее популярной системой управления реляционными базами данных с открытым исходным кодом в мире. Современные менеджеры пакетов сократили некоторые проблемы установки MySQL, но есть еще некоторые настройки, которые необходимо сделать после установки. Одним из наиболее важных, это провести некоторое дополнительное время на безопасность.

По умолчанию MySQL настроен на прием только локальных соединений. Если вам необходимо разрешить удаленные подключения, важно сделать это надежно. В этом руководстве мы покажем, как настроить MySQL на Ubuntu 16.04, для удаленного соединения с помощью шифрования SSL/TLS.

Предпосылки

Для того, чтобы следовать вместе с этим руководством, вам потребуется два сервера Ubuntu 16.04. Мы будем использовать один в качестве сервера MySQL, а другой в качестве клиента. Создайте некорневого пользователя с sudo привилегиями на каждом из этих серверов. Следуйте нашему руководству по первоначальной настройке сервера Ubuntu 16.04, чтобы получить ваш сервер в соответствующем начальном состоянии.

На первой машине, вы должны иметь установленный и настроенный сервер MySQL. Следуйте нашему руководство по установке MySQL на Ubuntu 16.04 для установки и настройки программного обеспечения.

На второй машине установите пакет клиент MySQL. Вы можете обновить индекс пакетов apt и установить необходимое программное обеспечение, набрав:

sudo apt-get update
sudo apt-get install mysql-client

 

Когда ваш сервер и клиент готов, продолжайте дальше следовать нашему гиду.

Проверьте текущий статус SSL/TLS

Прежде чем мы начнем, мы можем проверить текущее состояние SSL/TLS на нашем экземпляре MySQL сервера.

Войдите в сеанс MySQL с помощью пользователя root в MySQL. Мы будем использовать -h чтобы указать локальный интерфейс обратной петли IPv4 для того , чтобы заставить клиента соединиться с TCP вместо использования локального файла сокета. Это позволит нам проверить состояние SSL для TCP соединений:

mysql -u root -p -h 127.0.0.1

 

Вам будет предложено ввести MySQL пароль root, который вы выбрали в процессе установки. После этого вы попадёте в интерактивную сессию MySQL.

Показать состояние переменных SSL/TLS, набрав:

mysql> SHOW VARIABLES LIKE '%ssl%';

 

Вывод
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |
| have_ssl      | DISABLED |
| ssl_ca        |          |
| ssl_capath    |          |
| ssl_cert      |          |
| ssl_cipher    |          |
| ssl_crl       |          |
| ssl_crlpath   |          |
| ssl_key       |          |
+---------------+----------+
9 rows in set (0.01 sec)

 

Переменные have_openssl и have_ssl помечены как DISABLED. Это означает, что функциональность SSL собран в сервере, но еще не включена.

Проверьте состояние нашего текущего соединения, чтобы подтвердить:

mysql> \s

 

Вывод
--------------
mysql  Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using  EditLine wrapper

Connection id:      30
Current database:   
Current user:       root@localhost
SSL:         Not in use
Current pager:      stdout
Using outfile:      ''
Using delimiter:    ;
Server version:     5.7.17-0ubuntu0.16.04.1 (Ubuntu)
Protocol version:   10
Connection:      127.0.0.1 via TCP/IP
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    utf8
Conn.  characterset:    utf8
TCP port:       3306
Uptime:         3 hours 38 min 44 sec

Threads: 1  Questions: 70  Slow queries: 0  Opens: 121  Flush tables: 1  Open tables: 40  Queries per second avg: 0.005
--------------

 

Как показано выше, указывает на то, что SSL не используется в настоящее время для нашей связи, даже если мы соединены через TCP.

Закройте текущую сессию MySQL, когда вы закончите:

mysql> exit

 

Теперь мы можем приступить к настройке MySQL для SSL, чтобы обеспечить наши связи.

Генерация SSL/TLS сертификатов и ключей

Чтобы включить SSL соединения с MySQL, нам в первую очередь необходимо сформировать соответствующий сертификат и файлы ключей. Утилита называется mysql_ssl_rsa_setup снабжена MySQL 5.7 и выше, чтобы упростить этот процесс. Ubuntu 16.04 имеет совместимую версию MySQL, поэтому мы можем использовать эту команду, чтобы создать необходимые файлы.

Файлы будут создаваться в директории данных MySQL, расположенных в /var/lib/mysql. Нам нужен процесс MySQL, чтобы иметь возможность читать генерируемые файлы, так что мы будем заходить как mysql в качестве пользователя, который должен владеть сгенерированными файлами:

mysql-server$ sudo mysql_ssl_rsa_setup --uid=mysql

 

Генерирование будет производить вывод, который выглядит примерно так:

Вывод
Generating a 2048 bit RSA private key
...................................+++
.....+++
writing new private key to 'ca-key.pem'
-----
Generating a 2048 bit RSA private key
......+++
.................................+++
writing new private key to 'server-key.pem'
-----
Generating a 2048 bit RSA private key
......................................................+++
.................................................................................+++
writing new private key to 'client-key.pem'
-----

 

Проверьте созданные файлы, набрав:

mysql-server$ sudo find /var/lib/mysql -name '*.pem' -ls

 

Вывод
   256740      4 -rw-r--r--   1 mysql    mysql        1078 Mar 17 17:24 /var/lib/mysql/server-cert.pem
   256735      4 -rw-------   1 mysql    mysql        1675 Mar 17 17:24 /var/lib/mysqlsql/ca-key.pem<^>
   256739      4 -rw-r--r--   1 mysql    mysql         451 Mar 17 17:24 /var/lib/mysqlsql/public_key.pem<^>
   256741      4 -rw-------   1 mysql    mysql        1679 Mar 17 17:24 /var/lib/mysqlsql/client-key.pem<^>
   256737      4 -rw-r--r--   1 mysql    mysql        1074 Mar 17 17:24 /var/lib/mysqlsql/ca.pem<^>
   256743      4 -rw-r--r--   1 mysql    mysql        1078 Mar 17 17:24 /var/lib/mysqlsql/client-cert.pem<^>
   256736      4 -rw-------   1 mysql    mysql        1675 Mar 17 17:24 /var/lib/mysqlsql/private_key.pem<^>
   256738      4 -rw-------   1 mysql    mysql        1675 Mar 17 17:24 /var/lib/mysqlsql/server-key.pem<^>

 

В последнем столбце показаны сгенерированные имена файлов. Центральные столбцы, которые показывают “MySQL” указывают, что генерируемые файлы имеют правильного пользователя и группы владельца.

Эти файлы являются ключевыми и сертификат пары для сертификации (начиная с “ca”), процесс сервера MySQL (начиная с “server”), так и для клиентов MySQL (начиная с “client”). Кроме того, файлы private_key.pem и public_key.pem используются MySQL для безопасной передачи пароля, если не используется SSL.

Включение SSL соединений на сервере MySQL

Современные версии MySQL будут искать соответствующие файлы сертификатов в пределах каталога данных MySQL при запуске сервера. Из-за этого нам на самом деле не нужно изменить конфигурацию MySQL, чтобы включить SSL.

Мы можем просто перезапустить службу MySQL вместо этого:

sudo systemctl restart mysql

 

После перезагрузки, откройте новый сеанс MySQL, используя ту же команду, как и раньше. Клиент MySQL автоматически попытается подключиться с помощью SSL, если она поддерживается сервером:

mysql -u root -p -h 127.0.0.1

 

Давайте посмотрим на ту же информацию, которую мы запрашивали в прошлый раз. Проверьте значения переменных, связанных с SSL:

mysql> SHOW VARIABLES LIKE '%ssl%';

 

Вывод
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| have_openssl  | YES             |
| have_ssl      | YES             |
| ssl_ca        | ca.pem          |
| ssl_capath    |                 |
| ssl_cert      | server-cert.pem |
| ssl_cipher    |                 |
| ssl_crl       |                 |
| ssl_crlpath   |                 |
| ssl_key       | server-key.pem  |
+---------------+-----------------+
9 rows in set (0.00 sec)

 

Переменные have_openssl и have_ssl чтения “YES” вместо “ОТКЛ” на этот раз. Кроме того, переменные ssl_ca, ssl_cert и ssl_key были указаны с именами соответствующих сертификатов, которые мы получили.

Затем проверьте параметры соединения снова:

mysql> \s

 

Вывод
--------------
. . .
SSL:            Cipher in use is DHE-RSA-AES256-SHA
. . .
Connection:      127.0.0.1 via TCP/IP
. . .
--------------

 

На этот раз, отображается конкретный SSL, указывая, что SSL используется для того чтобы обеспечить наше соединение.

Выход обратно в оболочку:

mysql> exit

 

Наш сервер теперь может использовать шифрование, но требуется некоторая дополнительная настройка для обеспечения возможности удаленного доступа и использования безопасного соединения.

Настройка безопасных соединений для удаленных клиентов

Теперь, когда мы имеем доступный SSL на сервере, мы можем приступить к настройке безопасного удаленного доступа. Для этого нам необходимо:

Настройка удаленного доступа с обязательным SSL

В настоящее время сервер MySQL настроен на прием SSL соединения от клиентов. Тем не менее, он все равно будет разрешить нешифрованные соединения, по требованию клиента.

Мы можем исправить это путем включения опции require_secure_transport. Это требует, чтобы все соединения должны быть сделаны либо с помощью SSL или с локального сокета Unix. Так как Unix сокеты доступны только внутри самого сервера, единственный вариант подключения открыт для удаленных пользователей будет с помощью SSL.

Чтобы включить эту настройку, откройте файл /etc/mysql/my.cnf в текстовом редакторе:

sudo nano /etc/mysql/my.cnf

 

Внутри будет две директивы !includedir, используемые для источника дополнительных конфигурационных файлов. Нам нужно будет поставить нашу собственную конфигурацию под этими линиями так, чтобы они отменяли любые конфликтующие параметры.

Начните с создания раздела [mysqld] целевого процесса сервера MySQL. Под этим заголовком раздела, установите require_secure_transport на ON:

/etc/mysql/my.cnf
. . .

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

[mysqld]
# Require clients to connect either using SSL
# or through a local socket file
require_secure_transport = ON

 

Эта линия является единственным значением, которое требуется для обеспечения безопасных соединений.

По умолчанию MySQL настроен на прослушивание только для подключений, происходящих на локальном компьютере. Для того, чтобы настроить его для прослушивания удаленных соединений, мы можем установить bind-address с другим интерфейсом.

Чтобы разрешить MySQL принимать соединения на любой из его интерфейсов, мы можем установить bind-address на “0.0.0.0”:

/etc/mysql/my.cnf
. . .

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

[mysqld]
# Require clients to connect either using SSL
# or through a local socket file
require_secure_transport = ON
bind-address = 0.0.0.0

 

Сохраните и закройте файл, когда вы закончите.

Затем перезапустите MySQL, чтобы применить новые параметры:

sudo systemctl restart mysql

 

Убедитесь в том, что MySQL прослушивает “0.0.0.0” вместо “127.0.0.1”, набрав:

sudo netstat -plunt

 

Вывод
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      4330/mysqld     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1874/sshd       
tcp6       0      0 :::22                   :::*                    LISTEN      1874/sshd

 

“0.0.0.0” в приведенном выше выводе указывает на то, что MySQL прослушивает подключения на всех доступных интерфейсов.

Далее, нам необходимо разрешить соединения MySQL через наш брандмауэр. Создайте исключение, набрав:

sudo ufw allow mysql

 

Вывод
Rule added
Rule added (v6)

 

Теперь попытки удаленного подключения должны быть в состоянии достигнуть нашим сервером MySQL.

Настройка удаленного пользователя MySQL

Сервер MySQL теперь слушает удаленные подключения, но у нас в настоящее время нет никаких пользователей, настроенных, которые могут подключаться с внешнего компьютера.

Войдите в MySQL как root, чтобы начать работу:

mysqlserver$ mysql -u root -p

 

Внутри, вы можете создать нового удаленного пользователя с помощью команды CREATE USER. Мы будем использовать IP – адрес машины у нашего клиента в принимающей части спецификации пользователя, чтобы ограничить возможность соединения с этой машиной.

Для некоторых в случае, если опция require_secure_transport выключена в будущем, мы можем также указать при создании учетной записи, что данный пользователь требует SSL, включив пункт REQUIRE SSL:

mysql> CREATE USER 'remote_user'@'mysql_client_IP' IDENTIFIED BY 'password' REQUIRE SSL;

 

Далее, предоставить новые разрешения пользователя к базам данных или таблиц, к которым они должны иметь доступ. Чтобы продемонстрировать это, мы создадим базу данных example и выдадим разрешение пользователю:

mysql> CREATE DATABASE example;
mysql> GRANT ALL ON example.* TO 'remote_user'@'mysql_client_IP';

 

Затем сбросьте привилегии, чтобы применить все эти настройки:

mysql> FLUSH PRIVILEGES;

 

Выйдите обратно к оболочке:

mysql> exit

 

Наш сервер настроен, чтобы разрешить подключения к нашему удаленному пользователю.

Тестирование удаленных подключений

На машине клиента MySQL, проверьте, что вы можете подключиться к серверу успешно. Используйте опцию -u для определения удаленного пользователя и -h возможность указать IP – адрес сервера в MySQL:

mysql-client$ mysql -u remote_user -p -h mysql_server_IP

 

После указания пароля, вы будете авторизованы на удаленном сервере.

Убедитесь, что соединение является безопасным:

mysql> \s

 

Вывод
--------------
. . .
SSL:         Cipher in use is DHE-RSA-AES256-SHA
. . .
Connection:      mysql_server_IP via TCP/IP
. . .
--------------

 

Выйдите обратно в оболочку:

mysql> exit

 

Далее, попытка соединиться небезопасно:

mysql-client$ mysql -u remote_user -p -h mysql_server_IP --ssl-mode=disabled

 

После того, как был запрос на ввод пароля, ваше соединение должно быть отказано:

Вывод
ERROR 1045 (28000): Access denied for user 'remote_user'@'mysql_server_IP' (using password: YES)

 

Это показывает, что SSL соединения разрешены, в то время как незашифрованные соединения отказывались.

На данный момент, наш сервер MySQL был настроен, чтобы надежно фиксировать удаленные соединения. Вы можете остановиться здесь, если это отвечает вашим требованиям к безопасности, но есть некоторые дополнительные части, которые мы можем поставить на место, чтобы повысить нашу безопасность и доверие дальше.

Настройка проверки для MySQL соединений (Необязательно)

В настоящее время наш сервер MySQL настроен с помощью сертификата SSL, подписанного локально сгенерированной центром сертификации (CA). Сертификат сервера и пара ключей достаточно для обеспечения шифрования для входящих соединений.

Тем не менее, мы в настоящее время не использовать доверительные отношения, которые орган сертификат может обеспечить. Распределяя сертификат CA для клиентов, а также сертификат клиента и ключ, обе стороны могут предоставить доказательства того, что их сертификаты были подписаны взаимоприемлемым доверенным центром сертификации. Это может помочь предотвратить фальсифицируемые соединений на вредоносные серверы.

Для реализации этого дополнительной гарантии, нам нужно будет:

Передача клиентских сертификатов на клиентский компьютер

Для начала, нам нужно передать в MySQL CA и файлы сертификатов клиента с сервера MySQL и поместить их на машину клиента MySQL.

Начните с создания каталога на клиенте MySQL в домашнем каталоге пользователя, который будет использоваться для подключения. Назовем client-ssl:

mysql-client$ mkdir ~/client-ssl

 

Так как сертификат ключа чувствителен, мы должны заблокировать доступ к этому каталогу, так что только текущий пользователь может получить доступ к нему:

mysql-client$ chmod 700 ~/client-ssl

 

Теперь мы можем скопировать информацию о сертификате в новый каталог.

На машине сервере MySQL, отобразим содержимое сертификата CA, набрав:

mysql-client$ sudo cat /var/lib/mysql/ca.pem

 

Вывод
-----BEGIN CERTIFICATE-----

. . .

-----END CERTIFICATE-----

 

Скопируйте весь вывод, в том числе линии BEGIN CERTIFICATE и END CERTIFICATE в буфер обмена.

На клиенте MySQL , создайте файл с таким же именем внутри нового каталога:

mysql-client$ nano ~/client-ssl/ca.pem

 

Внутри, вставить скопированное содержимое сертификата из буфера обмена. Сохраните и закройте файл, когда вы закончите.

Затем отобразите сертификат клиента на сервере MySQL :

mysql-client$ sudo cat /var/lib/mysql/client-cert.pem

 

Вывод
-----BEGIN CERTIFICATE-----

. . .

-----END CERTIFICATE-----

 

Опять же, скопируйте содержимое в буфер обмена. Не забудьте включить первую и последнюю строку.

Откройте файл с тем же именем на клиенте MySQL в пределах директории client-ssl:

mysql-client$ nano ~/client-ssl/client-cert.pem

 

Вставить содержимое из буфера обмена. Сохраните и закройте файл.

И, наконец, отобразите содержимое файла ключа клиента на сервере MySQL:

mysql-client$ sudo cat /var/lib/mysql/client-key.pem

 

Вывод
-----BEGIN RSA PRIVATE KEY-----

. . .

-----END RSA PRIVATE KEY-----

 

Скопируйте отображаемые содержимое, в том числе первую и последнюю строку, в буфер обмена.

На клиенте MySQL, откройте файл с тем же именем в каталоге client-ssl:

mysql-client$ nano ~/client-ssl/client-key.pem

 

Вставьте содержимое из буфера обмена. Сохраните и закройте файл.

Теперь клиент машина должна иметь все учетные данные, необходимые для доступа к серверу MySQL. Далее, мы должны изменить нашего удаленного пользователя.

Требуйте сертификат из доверенного центра сертификации для удаленных пользователей

В настоящее время клиент MySQL имеет файлы, доступные, чтобы представить свой сертификат на сервер при подключении. Тем не менее, сервер еще не настроен требовать сертификат клиента от доверенного центра сертификации

Чтобы изменить это, необходимо войти с корневой учетной записи MySQL на сервер MySQL :

mysql-client$ mysql -u root -p

 

Далее, нам необходимо изменить требования к нашему удаленному пользователю. Вместо пункта REQUIRE SSL, мы должны применить пункт REQUIRE X509. Это подразумевает все обеспечения, предоставленного предыдущим требованием, но дополнительно требуется соединенному клиенту представить сертификат, подписанный центром сертификации, которому сервер доверяет MySQL.

Для того, чтобы настроить требования пользователя, используйте команду ALTER USER:

mysql> ALTER USER 'remote_user'@'mysql_client_IP' REQUIRE X509;

 

Очистите изменения, чтобы гарантировать, что они применяются немедленно:

mysql> FLUSH PRIVILEGES;

 

Выйдите обратно в оболочку, когда вы закончите:

mysql> exit

 

Далее, мы можем проверить, чтобы убедиться, что мы все еще можем подключиться.

Тестирование сертификата при подключении

Сейчас хорошее время, чтобы проверить обе стороны, когда мы соединяемся.

На клиенте MySQL, сначала попытайтесь подключиться без предоставления клиентских сертификатов:

mysql> mysql -u remote_user -p -h mysql_server_IP

 

Вывод
ERROR 1045 (28000): Access denied for user 'remote_user'@'mysql_client_IP' (using password: YES)

 

Без предоставления сертификата клиента, сервер отклоняет соединение.

Теперь соединитесь при использовании параметров --ssl-ca, --ssl-cert и --ssl-key, чтобы указать на соответствующие файлы внутри каталога  ~/client-ssl:

mysql-client$ mysql -u remote_user -p -h mysql_server_IP --ssl-ca=~/client-ssl/ca.pem --ssl-cert=~/client-ssl/client-cert.pem --ssl-key=~/client-ssl/client-key.pem

 

Вы должны войти успешно в систему. Выйдите обратно, чтобы восстановить доступ к вашей оболочки:

mysql> exit

 

Теперь, когда мы подтвердили доступ к серверу, мы можем реализовать небольшое улучшение юзабилити.

Создание файла конфигурации клиента MySQL

Для того, чтобы избежать необходимости указать файлы сертификата каждый раз при подключении к сети, мы можем создать простой файл конфигурации клиента MySQL.

Внутри вашей домашней директории на машине клиенте MySQL, создайте скрытый файл с именем ~/.my.cnf:

mysql-client$ nano ~/.my.cnf

 

В верхней части файла, создайте раздел под названием [client]. Внизу, мы можем установить параметры ssl-ca, ssl-cert и ssl-key, чтобы указать на файлы, которые мы копируем с сервера. Он должен выглядеть следующим образом :

~ / .my.cnf
[client]
ssl-ca = ~/client-ssl/ca.pem
ssl-cert = ~/client-ssl/client-cert.pem
ssl-key = ~/client-ssl/client-key.pem

 

Опция ssl-ca сообщает клиенту, чтобы убедиться, что сертификат, представленный сервером MySQL подписывается центром сертификации, который мы указали. Это позволяет клиенту верить, что он подключается к доверенному серверу MySQL.

параметры ssl-cert и ssl-key указывают на файлы, необходимые для доказательства сервера MySQL, что он тоже имеет сертификат, подписанный тем же органом сертификации. Нам это нужно, если мы хотим, чтобы сервер MySQL убедиться, что клиент был доверенным центром сертификации.

Сохраните и закройте файл, когда вы закончите.

Теперь вы можете подключиться к серверу MySQL, не добавляя опции --ssl-ca, --ssl-cert и --ssl-key к командной строке:

mysql-client$ mysql -u remote_user -p -h mysql_server_ip

 

Ваш клиент и сервер должны каждому из них будет предоставлять сертификаты при согласовании подключения. Каждая сторона настроена для проверки удалённого сертификата от сертификата CA он имеет локально.

Вывод

Сервер MySQL должен теперь настроен на требование защищенных соединений для удаленных клиентов. Кроме того, если вы следовали шагfv для проверки соединения с использованием центра сертификации, некоторый уровень доверия устанавливается с обеих сторон.

Как настроить SSL/TLS для MySQL на Ubuntu 16.04

Exit mobile version