SSL для всех (пользователей MariaDB), даром, и пусть никто не уйдёт обиженный

Kate

Administrator
Команда форума
MySQL научился использовать OpenSSL, чтобы шифровать трафик между клиентом и сервером году где-то в 1999. В принципе работало оно нормально, свою задачу выполняло, трафик шифровало. Но был там один фатальный недостаток. SSL в MySQL, а позже и в MariaDB, не работал сам, сразу. Его надо было настроить. И это было непросто.

Вначале надо было сгенерировать сертификаты. Это был самый простой шаг, всего-то скопировать несколько строчек из документации. MySQL даже потом научился делать это автоматически. Потом надо было прописать их в my.cnf, тоже ничего сложного. Но для правильного использования SSL клиент должен проверить серверный сертификат и убедиться, что он правильный. Только так можно обеспечить защиту от атак "человек посередине" (MitM), а если посередине никого нет, то зачем вообще шифровать?

Чтоб проверить серверный сертификат, клиенту нужен доступ к доверенному корневому сертификату, которым был подписан (напрямую или по цепочке) данный серверный. Такой можно сгенерировать и самому (да, опять скопировав пару строчек из документации) и вручную проинсталлировать его на всех клиентах. Вот этот последний шаг — скопировать свой корневой сертификат на все клиентские компьютеры (устройства, виртуалки, докер-образы) — это уже обычно значительно превышает тот уровень неудобства, на который готовы пойти пользователи ради, условно, "немножко более безопасного подключения". Или можно правильно подписать свой серверный сертификат сертификатом одного из всем известных удостоверяющих центров сертификации. Там свой отдельный список грабель, на которые надо наступить и барьеров, через которые надо перепрыгнуть. Желающих это делать, подозреваю, ещё меньше, чем любителей возиться с самоподписанными сертификатами. Хотя может я и не прав, в конце статьи — опрос.

Ну а что делать, сертификат-то проверять надо. Иначе это не защита, а пшик. Приходится терпеть. Так мы и терпели почти четверть века, и очень небольшое количество пользователей проходило квест настройки SSL до конца. Это должно измениться новом релизе MariaDB 11.3 (пока доступен только в виде превью тут).

Пару месяцев назад я внезапно осознал что это только в общем случае нельзя проверить сертификат без подписи удостоверяющего центра. В случае же MariaDB обычно у клиента и сервера есть общий секрет — что-то, что они оба знают, а "человек посередине" — нет. Это пароль от аккаунта. Его ж всё равно надо указывать, чтоб залогиниться. И это обычно происходит довольно надёжным challenge-response способом, никто пароли в открытом виде не посылает. Это можно использовать!

Теперь SSL в MariaDB 11.3 работает так: клиент подключается к серверу, происходит TLS handshake, сервер посылает свой сертификат. Клиент его проверяет — если он подписан, хорошо. Если же он не подписан, сертификат объявляется "сомнительным", но, в отличие от всех предыдущих версий, это ещё не причина сразу рвать соединение. Вот если сервер попросит пароль в открытом виде — тогда да, под сомнительным сертификатом клиент пароль в открытом виде слать откажется и отключится. Если же там "двойной SHA1" или ed25519 (подробности тут) то аутентификация продолжается и если пароль был правильный, сервер пошлёт клиенту дополнительно подпись SHA2("хэш пароля" + scramble + "fingerprint сертификата"). "Человек посередине" знает scramble (это случайная строка, она передаётся в открытом виде) и fingerprint. Но он не знает хэш пароля и не сможет подделать эту подпись. Клиент же знает все три части, может посчитать такое же значение и убедиться, что да, сервер реально знает пароль, и да, сертификат никто по дороге не подменил.

То есть в MariaDB 11.3 мы можем проверить сертификат сервера без третьей доверенной стороны. И раз мы умеем такой фокус, нам больше не надо грузить юзеров созданием сертификатов, можно включить SSL по умолчанию и сервер будет сам генерировать сертификаты в памяти если надо. И тогда можно включить SSL на всех клиентах, чтоб они требовали SSL, проверяли сертификаты, и отключались, если сертификат неправильный. Problem solved.

Недостатки у такого решения, конечно, есть. Если у какого-то аккаунта пустой пароль, то сертификат проверить будет нельзя. Тогда придётся вручную или автоматически отключать проверку сертификатов. Безопасность пострадает, хотя какая может быть безопасность, если атакующему можно не возиться с подменой сертификатов, а просто легально залогиниться без пароля? Если какой-то аккаунт использует аутентификацию через PAM или gssapi — то же самое, или отключать проверку сертификатов или настраивать её старым способом с граблями. На скорость включённый SSL влияет незначительно, но если кто работает с базой по модели "подключился, SELECT 1, отключился", то TLS handshake может заметно замедлить работу, надо или отключать SSL или использовать connection pool. Но ожидается, что таких пострадавших будет мало, а подавляющее большинство юзеров получит надёжный SSL, ничего не делая, то есть даром, и пусть никто не уйдёт незащищённый.

 
Сверху