Среди настроек безопасности ClickHouse имеет хорошую поддержку шифрования данных с помощью SSL. Его подключение и настройку мы рассмотрим в этом задании. Но перед этим хотелось бы рассказать в каких случаях следуюет использовать tls подключение. На самом деле любой безопасник ответит - что использовать его необходимо всегда. Я же попробую немного дополнить данный ответ и сказать, что в целом если вы доверяете сети по которой передаются данные - то использовать tls большого смысла нет. Это добавит дополнительных расходов на cpu, тем самым нагрузив дополнительно сервер. Но если же вы берете выделенные железки на хецнере и обмениваетесь трафиком с кликхаусом по внешним адресам, то я бы точно вам посоветовал включить TLS для защиты вашего трафика.
Итак, для включения шифрования нам нужно сделать следующее:
- Заставить кликхаус слушать на всех tls secured портах
- Подключить сертификаты и параметры Диффи-Хеллмана для включения шифрования на стороне сервера.
- Убедиться, что защищенный клиент работает.
Для того чтобы включить защищенное соединение, нам необходимо раскомментировать нужные строки в конфигурации config.xml
.
<yandex>
<https_port>8443</https_port>
<tcp_port_secure>9440</tcp_port_secure>
<!--
<http_port>8123</http_port>
<tcp_port>9000</tcp_port>
-->
</yandex>
Также хорошей практикой является комментирование портов, которые не используются. Так мы и сделали, включив HTTPS
, и TLS
поверх TCP
.
Для подключения SSL нам нужны валидный X509 сертификат и приватный ключ, который можно сгенерировать несколькими способами, используя тот же openssl
или letsencrypt
. Главный вопрос в том хотите ли вы использовать самодподписанный сертификат или публичный. В нашем примере мы остановимся на самоподписанном сертификате. Сгенерировать его можно одной командой:
openssl req -subj "/CN=localhost" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /etc/clickhouse-server/server.key -out /etc/clickhouse-server/server.crt
Главное задать common name равным адресу сервера, к которому мы будем подключаться. Мы указали CN=localhost
при создании - то есть клиент будет проверять имя сервера к которому он подключился, сравнивая его с common name равное localhost.
Дополнительно мы будем использовать параметры Диффи-Хеллмана (dhParamsFile
), которые генерируются следующей командой:
openssl dhparam -out /etc/clickhouse-server/dhparam.pem 4096
Данная операция будем выполняться некоторое время, но запустить ее нужно только один раз.
Итак, все необходимое подготовили - теперь лезем в настройки кликхаус и добавляем следующие опции:
<yandex>
<openSSL>
<server>
<certificateFile>/etc/clickhouse-server/server.crt</certificateFile
<privateKeyFile>/etc/clickhouse-server/server.key</privateKeyFile>
<dhParamsFile>/etc/clickhouse-server/dhparam.pem</dhParamsFile>
<verificationMode>none</verificationMode>
<loadDefaultCAFile>true</loadDefaultCAFile>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
</server>
</openSSL>
</yandex>
Для удобства мы поместили их рядом с конфигурацией сервера в директории /etc/clickhouse-server/
. Также следует позаботиться, чтобы ClickHouse имел права на доступ ко всем 3-м файлам. Теперь пройдемся по параметрам.
Путь к файлу с приватным ключом сертификата. Файл может содержать и ключ, и сертификат одновременно.
Путь к файлу с сертификатом Х509, может не указываться, если privateKeyFile
уже содержит сертификат.
Путь к файлу с параметрами Диффи-Хеллмана. Этот параметр не обязателен и может быть закомментирован, хотя делать этого настоятельно не рекомендуется.
Параметр, который отвечает за способ проверки сертификата. Допустимые значения — none
, relaxed
, strict
, once
. Рассмотрим, чем они отличаются:
- none — не запрашивает сертификат для проверки;
- relaxed — запрашивает сертификат для проверки, если при процессе верификации произошла ошибка, то TLS/SSL соединение разрывается с сообщением об ошибке;
- strict — метод очень похож на relaxed, но если сертификат не возвращается, то соединение также разрывается и будет показано сообщение об ошибке;
- once — сертификат на проверку запрашивается и верифицируется один раз при подключении. При переподключении сертификат дополнительно не запрашивается.
Определяет, будут ли использоваться встроенные CA-сертификаты для OpenSSL. Допустимые значения — true
, false
.
Определяет, будет ли включено кеширование TLS сессии. Допустимые значения — true
, false
.
В этом параметре перечислены протоколы, которые не будут использоваться.
Предпочтение серверных шифров на клиенте. Допустимые значения — true
, false
.
В данном примере рассмотрены не все параметры, а только самые основные. Дополнительные опции вы можете найти здесь.
Теперь, когда мы закончили с конфигурацией SSL, применяем конфигурацию перезапуском сервиса. Чтобы убедиться, что все работает корректно, можно проверить логи, статус сервиса и доступность защищенных портов, которые мы открыли.
Последним пунктом нужно проверить, успешно ли подключается ClickHouse клиент к серверу.
# chown clickhouse:clickhouse dhparam.pem server.*
# chmod 0400 server.key
# clickhouse-client --secure
ClickHouse client version 21.2.5.5 (official build).
Connecting to localhost:9440 as user default.
Code: 210. DB::NetException: SSL Exception: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED (localhost:9440)
А вот и ошибочка! Происходит это потому что наш клиент не может проверить валидность ssl сертификата, который отдает нам сервер. Исправить это можно двумя путями - либо подложить клиенту в /etc/clickhouse-client/config.xml CA сертификат, который подписал сертификат сервера. Или же в том же файле можно отключить проверку сертификта на клиенте:
<verificationMode>none</verificationMode>
Теперь можем попробовать подключиться еще раз:
# clickhouse-client --secure
ClickHouse client version 21.2.5.5 (official build).
Connecting to localhost:9440 as user default.
Connected to ClickHouse server version 21.2.5 revision 54447.
ch1.ru-central1.internal :)
Подключение прошло успешно!