Без TLS запити, результати й (залежно від плагіна) облікові дані передаються мережею у відкритому вигляді. Для бази на тому ж хості через сокет це не проблема; для бази в іншій мережі, хмарі чи між дата-центрами - обов'язково.
Сторона сервера. MySQL 8 при першому старті сам генерує самопідписані сертифікати й вмикає TLS за замовчуванням: клієнт, що підтримує TLS, використає його. Але:
- самопідписаний сертифікат захищає від прослуховування, але не від підміни сервера (атака посередника), якщо клієнт його не перевіряє;
- клієнт може підключитися й без TLS, якщо сервер цього не забороняє.
Заборонити незашифровані підключення:
SET PERSIST require_secure_transport = ON; -- для всіх, крім сокета
-- або для окремого облікового запису
ALTER USER 'app'@'%' REQUIRE SSL;
ALTER USER 'app'@'%' REQUIRE X509; -- ще й клієнтський сертифікат
Сторона Laravel. Підключення налаштовується через опції PDO в config/database.php:
'options' => extension_loaded('pdo_mysql') ? array_filter([
(PHP_VERSION_ID >= 80500 ? Pdo\Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'),
(PHP_VERSION_ID >= 80500 ? Pdo\Mysql::ATTR_SSL_VERIFY_SERVER_CERT : PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT) => true,
]) : [],
ATTR_SSL_CA- сертифікат центру сертифікації, яким підписано сертифікат сервера. У хмарних провайдерів (RDS, Cloud SQL, PlanetScale) це їхній публічний CA-бандл;ATTR_SSL_VERIFY_SERVER_CERT = true- перевіряти сертифікат сервера. Без цього TLS є, але підключитися можна й до підставного сервера;- для взаємної автентифікації -
ATTR_SSL_CERTіATTR_SSL_KEY(клієнтські сертифікат і ключ).
У PHP 8.5 константи PDO::MYSQL_ATTR_* оголошено застарілими на користь Pdo\Mysql::ATTR_* - звідси перевірка версії в типовому конфігу Laravel.
Як перевірити, що з'єднання справді зашифроване:
SHOW SESSION STATUS LIKE 'Ssl_cipher'; -- непорожнє значення = TLS
SHOW SESSION STATUS LIKE 'Ssl_version'; -- TLSv1.3 / TLSv1.2
З Laravel - тим самим запитом: DB::select("SHOW SESSION STATUS LIKE 'Ssl_cipher'"). А які з усіх поточних підключень ідуть без шифрування, показує performance_schema.status_by_thread зі змінною Ssl_cipher для кожного потоку.
Для консольного клієнта аналогічний рівень дає --ssl-mode=VERIFY_IDENTITY (перевіряє і ланцюжок, і що ім'я хоста збігається з сертифікатом), а --ssl-mode=REQUIRED лише шифрує без перевірки.
Ротація сертифікатів у MySQL 8 можлива без перезапуску: замінити файли й виконати ALTER INSTANCE RELOAD TLS.