Вопрос или проблема
У меня трудности с MySQL и OpenSSL. Я использую MySQL 5.7 и OpenSSL 1.1.0g на Ubuntu 16.04.
Независимо от того, какие сертификаты я загружаю, MySQL запускается, но не устанавливает соединение через SSL, если сертификаты проверяются. Например, если я разрешаю ему создать собственные сертификаты, в /var/log/mysql/error.log появляется следующее:
2019-02-17T09:42:25.666293Z 0 [Note] Обнаружены ca.pem, server-cert.pem и server-key.pem в каталоге данных. Пытаюсь включить поддержку SSL, используя их.
2019-02-17T09:42:25.666543Z 0 [Warning] Сертификат CA ca.pem самоподписан.
Нормально. Но:
/usr/bin/openssl s_client -connect localhost:3306
выдает мне следующее:
CONNECTED(00000003)
140234876264896:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:252:
Если я создаю отдельный CA и самоподписанные сертификаты с помощью openssl, это не имеет значения – та же ошибка. Как последнюю меру я пытался использовать сертификат LetsEncrypt моего веб-сервера с сертификатом CA LE, чтобы избежать использования самоподписанного сертификата, с тем же результатом.
Оказывается, любое приложение, пытающееся подключиться, например, phpMyAdmin, также выдает ошибку OpenSSL, если только ему не позволено подключаться небезопасно.
Если я установлю $cfg['Servers'][$i]['ssl_verify'] = false;
в phpMyAdmin/admin/config.inc.php
, он подключается через SSL, но с предупреждением “не проверено”.
Из этого я думаю, что это похоже на ошибку CA, а не на ошибку сертификата, но поскольку я получаю тот же результат независимо от того, какой сертификат CA настроен, я в тупике. Есть предложения?
SSL-соединения MySQL — это не просто стандартные SSL-соединения с подключением MySQL внутри.
При установлении такого соединения MySQL-клиент сначала проводит рукопожатие с сервером, используя текстовый протокол MySQL, (если обе стороны соглашаются использовать SSL), затем начинает SSL-соединение на этом же TCP-соединении.
OpenSSL или другие универсальные SSL-клиенты не могут понять текстовый протокол MySQL, они сразу же устанавливают SSL-соединение без этого специфического рукопожатия MySQL, затем сообщают об ошибке версии, потому что это вовсе не стандартный SSL-сервер.
Документ о том, как MySQL устанавливает SSL-соединение: https://dev.mysql.com/doc/internals/en/ssl.html
.
Ответ или решение
Теория
Проблема, с которой вы столкнулись, связана с установлением SSL-соединения между MySQL и клиентом, в данном случае через OpenSSL. Ошибка "wrong version number" при попытке установить SSL-соединение указывает на несоответствие версий или протоколов связи, используемых сервером и клиентом. MySQL не использует стандартное SSL-соединение. Вместо этого, процесс подключения включает в себя первоначальный обмен данными с использованием внутреннего протокола MySQL и последующую установку SSL-соединения только после успешного согласования между клиентом и сервером.
При обычном SSL-соединении между сервером и клиентом инициируется прямое SSL-рукопожатие (handshake), но в случае MySQL требуется пройти начальную фазу обмена данными и команд, чтобы обе стороны согласились использовать SSL. Поскольку OpenSSL не знает об этом процессе обмена, прямая попытка подключения к MySQL-порту через OpenSSL приводит к ошибке версии, так как ожидается именно стандартный SSL-сервер.
Пример
Рассмотрим журнальные записи, которые говорят о нахождении и использовании SSL-сертификатов:
2019-02-17T09:42:25.666293Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
2019-02-17T09:42:25.666543Z 0 [Warning] CA certificate ca.pem is self signed.
Эти записи указывают на то, что сервер MySQL нашел необходимые файлы сертификатов и пытается включить поддержку SSL. Но позже, при попытке установления соединения через OpenSSL:
140234876264896:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:252:
Мы видим ошибку, связанную с несоответствием версии — это искомая проблема.
Применение
Теперь, когда вы понимаете природу проблемы, необходимо предпринять несколько шагов для успешного решения:
-
Использование MySQL-клиента для проверок: Поскольку MySQL имеет специфический процесс начала SSL-сессии, необходимо использовать клиент, поддерживающий данный процесс, например, MySQL клиентские библиотеки или утилиту
mysql
. -
Проверка и настройка конфигурации MySQL: Убедитесь, что все соответствующие параметры конфигурации в файле
my.cnf
настроены правильно. Вот несколько параметров, которые следует проверить:[mysqld] ssl-ca=/path/to/ca.pem ssl-cert=/path/to/server-cert.pem ssl-key=/path/to/server-key.pem
-
Настройка PhpMyAdmin: Поскольку PhpMyAdmin может также испытывать проблемы с верификацией сертификатов, необходимо убедиться, что все пути к сертификатам заданы верно, а также что находятся в актуальных версиях те библиотеки PHP, которые обрабатывают SSL.
-
Обновление OpenSSL: Убедитесь, что у вас установлены последние исправления и обновления как для OpenSSL, так и для MySQL. Это минимизирует вероятность наличия уязвимостей и несовместимостей.
-
Диагностика и тестирование: Используйте встроенные утилиты MySQL для тестирования SSL-соединений. К примеру, команда:
mysql --ssl-ca=/path/to/ca.pem --ssl-cert=/path/to/client-cert.pem --ssl-key=/path/to/client-key.pem -u [USERNAME] -p
позволит вам протестировать соединение вручную.
-
Использование современного CA: Если возможно, используйте сертификационный центр, который будет признан большинством современных систем. Это может помочь устранить ошибки, связанные с самоподписанными сертификатами.
Следуя предложенным шагам, вы сможете правильно настроить SSL-соединение для вашей специфической конфигурации MySQL, что обеспечит безопасное и проверенное соединение без ошибок версии.