Повышение безопасности ClickHouse

Это перевод статьи: Altinity Documentation / ClickHouse Operations Guide / Security / Hardening Guide

Содержание

  1. Повышение безопасности ClickHouse
    1. Содержание
    2. Введение
    3. Защита пользователей
      1. Настройка пользователей
        1. Настройки пользователей в XML
        2. Настройка пользователей средствами SQL
      2. Сетевые настройки пользователя
        1. Сетевые настройки пользователя SQL-запросами
        2. Сетевые настройки пользователя в XML
      3. Защита паролей
        1. Настройки защиты паролей с помощью SQL
        2. Настройка защиты паролей с помощью XML
      4. Настройка квот
        1. Настройка квот с помощью SQL
        2. Настройка квот с помощью XML
      5. Использование профилей
        1. Настройка профилей с помощью XML
      6. Ограничения баз данных
        1. Ограничения баз данных средствами XML
        2. Пример настройки ограничений с помощью XML
      7. Включение удалённой аутентификации
        1. Включение LDAP
    4. Защита сети
      1. Защита сетевого трафика ClickHouse
      2. Ограничение подключений
      3. Включение TLS
        1. Создание файлов
          1. Публичный удостоверяющий центр
          2. Создание приватного удостоверяющего центра
          3. Самозаверенный сертификат
        2. Включение TLS в ClickHouse
      4. Шифрование взаимодействий внутри кластера
    5. Защита хранилища
      1. Безопасность на уровне узла
      2. Шифрование на уровне тома
        1. Облачное хранилище
        2. Локальное хранилище
        3. Шифрование в Kubernetes
      3. Шифрование на уровне колонок
        1. Примеры шифрования колонок
      4. Защита файлов журналов

Введение

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

Повышение безопасности определённой системы ClickHouse зависит от ситуации, но описанные меры в общем применимы к любой инсталляции. Каждая из них может быть выполнена поотдельности и не обязательно в указаном порядке.

Защита пользователей

Меры повышения защиты пользователей.

Увеличение защиты ClickHouse на уровне пользователя состоит из следующих основных этапов:

ВАЖНОЕ ЗАМЕЧАНИЕ: Настройки могут храниться в файе по умолчанию /etc/clickhouse-server/config.xml. Однако в процессе обновления программного обеспечения этот файл может быть перезаписан. Для защиты настроек рекомендуется хранить конфигурацию в отдельных XML-файлах внутри /etc/clickhouse-server/config.d.

Настройка пользователей

Для защиты пользователей применимы следующие меры:

  • По возможности разрешить пользователям доступ только с узлов с определёнными именами или IP-адресами.
  • Сохранить все пароли в формате SHA256.
  • По возможности задать квоты для ресурсов пользователя.
  • Использовать профили для назначения одинаковых настроек нескольким пользователям и ограничения ресурсов пользователей наименьшими необходимыми значениями.
  • Вынести аутентификацию пользователей в LDAP или Kerberos.

Пользователей можно настроить через XML-файлы или через SQL-запросы.

Подробную информацию о настройке пользователей ClickHouse можно найти на сайте документации ClickHouse.Tech в разделе "Настройки пользователей".

Настройки пользователей в XML

Пользователи перечисляются в файле user.xml в элементе users. Каждый элемент внутри users соответствует одному пользователю.

Рекомендуется разместить всех пользователей не в одном файле user.xml, а в отдельных XML-файлах в каталоге users.d. Обычно это каталог /etc/clickhouse-server/users.d/.

Отметим, что в случае кластера ClickHouse файлы конфигурации пользователей нужно реплицировать на каждый узел. Ниже мы обсудим, как вынести часть настроек в другие системы, такие как LDAP.

Также отметим, что ClickHouse различает регистр символов в именах пользователей: John отличается от john. За подробностями обратитесь на сайт документации ClickHouse.Tech.

  • ВАЖНОЕ ЗАМЕЧАНИЕ: Если при попытке входа не было указано имя пользователя, то будет использоваться учётная запись с именем default.

Например, следующий раздел файла конфигурации описывает двух пользователей:

  • clickhouse_operator: Этот пользователь имеет пароль clickhouse_operator_password, сохранённый в виде хэша sha256, связан с профилем clickhouse_operator и может обращаться к базе данных ClickHouse с любого узла сети.

  • John: Этот пользователь может обращаться к базе данных только локально, имеет базовый пароль и связан с профилем default.

-

<users>
    <clickhouse_operator>
        <networks>
            <ip>127.0.0.1</ip>
            <ip>0.0.0.0/0</ip>
            <ip>::/0</ip>
        </networks>
        <password_sha256_hex>716b36073a90c6fe1d445ac1af85f4777c5b7a155cea359961826a030513e448</password_sha256_hex>
        <profile>clickhouse_operator</profile>
        <quota>default</quota>
    </clickhouse_operator>
    <John>
        <networks>
            <ip>127.0.0.1</ip>
        </networks>
        <password_sha256_hex>73d1b1b1bc1dabfb97f216d897b7968e44b06457920f00f2dc6c1ed3be25ad4c</password_sha256_hex>
        <profile>default</profile>
    </John>
</users>

Настройка пользователей средствами SQL

Пользователями ClickHouse можно управлять с помощью SQL-запросов к самому ClickHouse. Подробности можно найти на сайте документации ClickHouse.Tech в разделе "Аккаунт пользователя".

За включение управлением доступом на уровне пользователя отвечает опция access_management. В примере ниже управление доступом включено для пользователя John:

<users>
    <John>
        <access_management>1</access_management>
    </John>
</users>

Обычно для использования запросов DCL (Data Control Language - языка управления данными) включают access_management у одного пользователя, а остальные учётные записи создаются с помощью запросов. Обратитесь к сайту документации ClickHouse.Tech в раздел "Управление доступом".

После включения управлять доступом можно будет через SQL-запросы. Например, с помощью следующего SQL-запроса можно создать нового пользователя с именем newJohn с паролем, заданным в виде хэша sha256, и с ограничением доступа из указанной IP-сети:

CREATE USER IF NOT EXISTS newJohn
  IDENTIFIED WITH SHA256_PASSWORD BY 'secret'
  HOST IP '192.168.128.1/24' SETTINGS readonly=1;

Кроме того, с помощью SQL-запросов для управления доступом можно выполнять следующие действия:

  • Назначать роли
  • Применять политики к пользователям
  • Задавать квоты пользователей
  • Ограничивать доступ к базам данных, таблицам или отдельным строкам внутри таблиц.

Сетевые настройки пользователя

Права пользователей можно ограничить определённой сетью, из которой они будет иметь доступ к ClickHouse. Ограничить можно только адреса, с которых пользователям разрешено подключаться:

  • IP: IP-адрес или подсеть. Чтобы разрешить все IP-адреса, используйте 0.0.0.0/0 в случае IPv4 и ::/0 в случае IPv6.
  • Узел: Доменное имя узла, с которого подключается пользователь.
  • Регулярное выражение узла: Регулярное выражение, совпадающее с доменным именем узла.

По возможности стоит ограничить доступ только теми сетями, откуда могут устанавливаться подключения.

Сетевые настройки пользователя SQL-запросами

Разрешить доступ пользователя только из определённых сетей можно с помощью SQL-запросов. Подробности можно найти на сайте документации ClickHouse.Tech в разделе "CREATE USER".

Доступ из сети настраивается с помощью опции HOST при создании или изменении пользователей. Существуют следующие варианты опций:

  • ANY (по умолчанию): Пользователи могут подключаться из любого места
  • LOCAL: Пользователи могут подключаться только локально.
  • IP: Определённый IP-адрес или сеть.
  • NAME: Точное значение полностью опредлённого доменного имени.
  • REGEX: Допускает узлы, совпадающие с регулярным выражением.
  • LIKE: Допускает узлы, совпадающие с оператором LIKE.

Например, разрешим пользователю john подключаться только из локальной сети '192.168.0.0/16':

ALTER USER john
  HOST IP '192.168.0.0/16';

Для того, чтобы разрешить этому пользователю подключаться только с узлов с указанными доменными именами awesomeplace1.com, awesomeplace2.com и т.п.:

ALTER USER john
  HOST REGEXP 'awesomeplace[12345].com';

Сетевые настройки пользователя в XML

Сетевые настройки пользователя хранятся в файлах конфигурации в каталоге /etc/clickhouse-server/config.d внутри элемента <networks>. С помощью следующих опций этого элемента можно укзаать источники, из которых пользователь может установить подключения:

  • <ip>: IP-адрес или сеть.
  • <host>: Доменное имя узла.
  • <host_regexp>: Регулярное выржение для доменного имени.

Например, следующие настройки разрешают доступ только с узла localhost:

<networks>
    <ip>127.0.0.1</ip>
</networks>

Следующие настройки разрешают пользователю подключаться только с узлов с доменными именами example.com или supercool1.com, supercool2.com и т.д.:

<networks>
    <host>example.com</host>
    <host_regexp>supercool[1234].com</host_regexp>
</networks>

Если есть узлы или другие настройки, которые нужно применить к нескольким учётным записям, то для этого можно воспользоваться опцией подстановки, описанной на сайте документации ClickHouse.Tech на странице "Конфигурационные файлы". Например, в файле /etc/metrika.xml, который используется для подстановок, можно создать элемент local_networks:

<local_networks>
    <ip>192.168.1.0/24</ip>
</local_networks>

Подстановку можно применить к одному или нескольким пользователям с помощью атрибута incl при настройке сетевого доступа:

<networks incl="local_networks" replace="replace">
</networks>

Защита паролей

Пароли могут храниться в открытом виде или в виде хэша SHA256 (в шестнадцатеричном формате).

Пароли в формате SHA256 помечаются элементом <password_sha256_hex>. Пароль SHA256 можно сгенерировать с помощью следующей команды:

echo -n "secret" | sha256sum | tr -d '-'

Или с помощью такой:

echo -n "secret" | shasum -a 256 | tr -d '-'
  • ВАЖНОЕ ПРИМЕЧАНИЕ: Опция -n удаляет из вывода символ новой строки.

Например:

echo -n "clickhouse_operator_password" | shasum -a 256 | tr -d '-'
716b36073a90c6fe1d445ac1af85f4777c5b7a155cea359961826a030513e4

Настройки защиты паролей с помощью SQL

Пароли можно задавать с помощью выражений CREATE USER или ALTER USER с опцией IDENTIFIED WITH. За исчерпывающими подробностями обратитесь к сайту документации ClickHouse.Tech на страницу "CREATE USER". Доступны следующие варианты защиты паролей:

  • sha256password BY 'СТРОКА': Преобразует переданное значение СТРОКА в хэш sha256.
  • sha256_hash BY ‘ХЭШ’ (лучший вариант): Сохраняет переданный ХЭШ как значение хэша sha256 пароля.
  • double_sha1_password BY ‘СТРОКА’ (используется только при разрешённом входе через порт MySQL): Преобразует переданное значение СТРОКА в двойной хэш sha256.
  • double_sha1_hash BY ‘ХЭШ’ (используется только при разрешённом входе через порт MySQL): Сохраняет переданный ХЭШ как значение двойного хэша sha256 пароля.

Например, чтобы задать для пользователя John значение "password", хэшированное по алгоритму sha256:

ALTER USER John IDENTIFIED WITH sha256_hash BY '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8';

Настройка защиты паролей с помощью XML

Пароли можно задать вместе с другими настройками пользователя в файлах конфигурации /etc/clickhouse-server/config.d. За исчерпывающими подробностями обратитесь к сайту ClickHouse.Tech на страницу "Настройки пользователей".

Для задания хэша sha256 пароля пользователя воспользуйтесь веткой password_sha256_hex. Например, чтобы задать для пользователя John значение "password", хэшированное по алгоритму sha256:

<users>
    <John>
        <password_sha256_hex>5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8</password_sha256_hex>
    </John>
</users>

Настройка квот

Квоты ограничивают количество системных ресурсов, которое разрешено использовать пользователю в единицу времени. Дополнительные подробности можно найти на сайте документации ClickHouse.Tech на странице "Квоты".

Настройка квот с помощью SQL

Квоты можно создать или изменить с помощью выражений SQL, применимых к пользователям.

За дополнительной информацией по квотам в ClickHouse обратиесь к сайту документации ClickHouse.Tech в раздел "Квота" на странице "Управление доступом".

Настройка квот с помощью XML

Квоты определяются в файле users.xml внутри элемента quotas. Каждая квота определяется под собственным именем и является веткой элемента quotas.

Квоты определяют ограничения за интервалы времени. Например, квота по имени limited задаёт ограничение максимального количества запросов - 1000 запросов за интервал в 1 час и другое ограничение, разрешающее всего 10000 запросов за интервал в 24 часа.

<quotas>
    <limited>
        <interval>
            <duration>3600</duration>
            <queries>1000</queries>
        </interval>
        <interval>
            <duration>86400</duration>
            <queries>10000</queries>
        </interval>
    </limited>
</quotas>

Использование профилей

Профили позволяют применять настройки к нескольким пользователям. За дополнительными подробностями обратитесь к сайту документации ClickHouse.Tech на страницу "Профили настроек".

Настройка профилей с помощью XML

Профили применяются к пользователю с элементом profile. Например, назначим профиль restricted пользователю John:

<users>
    <John>
        <networks>
            <ip>127.0.0.1</ip>
            <ip>0.0.0.0/0</ip>
            <ip>::/0</ip>
        </networks>
        <password_sha256_hex>716b36073a90c6fe1d445ac1af85f4777c5b7a155cea359961826a030513e448</password_sha256_hex>
        <profile>restricted</profile>

Профили описываются в файле users.xml внутри элемента profiles. Каждая ветка этого элемента является именем профиля. Профиль restricted, приведённый ниже, разрешает пользователям с этим профилям использовать одновременно не более восьми потоков:

<profiles>
    <restricted>
        <!-- Максимальное количество потоков при выполнении одного запроса. -->
        <max_threads>8</max_threads>
    </default>
</profiles>

Рекомендуется определять в профиле следующие настройки:

  • readonly: Пользователь с таким профилем не имеет право вносить изменения.
  • max_execution_time: Ограничение времени работы процесса перед его принудительным завершением.
  • max_bytes_before_external_group_by: Максимальный объём оперативной памяти, выделяемой для сортировки одним выражением GROUP BY.
  • max_bytes_before_external_sort: Максимальный объём оперативной памяти, выделяемой для команд сортировки.

Ограничения баз данных

Разрешите пользователям работать только с нужными им базами данных, а при возможности - только с нужными им таблицам и строками.

Полную информацию можно найти на сайте ClickHouse.Tech в разделе "Настройки пользователей".

Ограничения баз данных средствами XML

Для ограничения доступа пользователя к данным с помощью XML-файла:

  1. Обновите файлы конфигурации пользователя в каталоге /etc/clickhouse-server/config.d или обновите их права с помощью SQL-запросов.
  2. Для каждого из польователей внесите изменения:
    1. Добавьте элемент <databases> со следующими ветками:
      1. Имя базы данных, к которой разрешён доступ.
      2. Внутри элемента базы данных перечислите имена таблиц, доступных пользователю.
      3. Внутри элемента таблицы добавьте элемент <filter>, совпадающий со строками, доступ к которым нужно разрешить.

Пример настройки ограничений с помощью XML

Следующие выражения разрешают пользователю John работать только с базой данных sales, а в ней - только с таблицей clients, в строках которой salesman = 'John':

<John>
    <databases>
        <sales>
            <clients>
                <filter>salesman = 'John'</filter>
            </clients>
        </sales>
    </databases>
</John>

Включение удалённой аутентификации

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

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

Включение LDAP

Серверы LDAP описываются в файлах конфигурации ClickHouse, таких как /etc/clickhouse-server/config.d/ldap.xml. За дополнительными подробностями обратитесь на сайт документации ClickHouse.Tech в раздел "Конфигурационные параметры сервера".

При использовании серверов LDAP в ClickHouse можно использовать один источник учётных данных, управлять политикой паролей и другими настройками безопасности с сервера LDAP. Кроме того, пропадает необходимость хранить информацию о паролях, даже в виде хэшей SHA256, на сервере ClickHouse или на узлах кластера.

Чтобы добавить один или больше серверов LDAP в ClickHouse, на каждом узле нужно прописать настройки ldap:

<ldap>
   <server>доменное_имя_сервера_ldap</server>
    <roles>
        <my_local_role1 />
        <my_local_role2 />
    </roles>
</ldap>

При создании пользователя укажите сервер ldap:

CREATE USER IF NOT EXISTS newUser
  IDENTIFIED WITH LDAP BY 'доменное_имя_сервера_ldap'
  HOST ANY;

Когда пользователь попытается пройти аутентфикацию в ClickHouse, его данные проверятся с помощью сервера LDAP, указанного в файлах конфигурации.

Защита сети

Защита сетевого трафика ClickHouse

Защита сетевого трафика ClickHouse уменьшает вероятность злоупотребления перехваченным трафиком. Защита сетевого трафика состоит из следующих важных этапов:

ВАЖНОЕ ЗАМЕЧАНИЕ: Настройки можно сохранить в файле по умолчанию /etc/clickhouse-server/config.xml. Однако, при обновлении пакета этот файл может быть перезаписан. Для защиты настроек рекомендуется хранить их в отдельных файлах XML в каталоге /etc/clickhouse-server/config.d с таким же корневым элементом, обычно это <yandex>. В этом документе используются только файлы конфигурации внутри каталога /etc/clickhouse-server/config.d.

Ограничение подключений

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

В ClickHouse есть встроенная поддержка клиентов MySQL, PostgreSQL и других. Включение портов настраивается в файлах в каталоге /etc/clickhouse-server/config.d.

Для ограничения подключений ClickHouse:

  1. Пересмотрите список необходимых портов. Полный список портов и настроек можно найти на сайте с документацией ClickHouse в разделе "Конфигурационные параметры сервера".
  2. Закомментируйте в файлах конфигурации все ненужные порты. Например, если не нужен порт для клиентов MySQL, то его можно закомментировать:

-

<!-- <mysql_port>9004</mysql_port> -->

Включение TLS

ClickHouse поддерживает как зашифрованные, так и незашифрованные сетевые подключения. Для защиты сетевого трафика нужно отключить незашифрованные порты и включить порты с TLS.

Для шифрования TLS требуется сертификат, полученный от публичный или приватного удостоверяющего центра.

  • Публичный удостоверяющий центр: Рекомендуется для внешних сервисов или подключений, источник которых не находится под вашим контролем.
  • Приватный удостоверяющий центр: Лучше подходит для случаев, когда ClickHouse используется только в локальной сети, а источники подключений находятся под вашим контролем.
  • Самозаверенный сертификат: Рекомендуется только для тестирования.

Какой бы метод ни использовался, для включения TLS в ClickHouse необходимы следующие файлы:

  • Сертификат сервера X509: По умолчанию используется файл server.crt
  • Приватный ключ: По умолчанию используется файл server.key
  • Параметры Диффи-Хеллмана: По умолчанию используется файл dhparam.pem

Создание файлов

Вне зависимости от того, какой из подходов используется, необходимы файлы с приватным ключом и параметрами Диффи-Хеллмана. Приведённые инструкции можно доработать в соответствии с требованиями используемого удостоверяющего центра. Для приведённых ниже инструкций потребуется openssl, инструкции были проверены с OpenSSL версии 1.1.1j.

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

    openssl genrsa -aes256 -out server.key 2048
    
  2. Создайте dhparam.pem с 4096-битным параметром. Процедура длительная, но выполнить её нужно всего один раз:

    openssl dhparam -out dhparam.pem 4096
    
  3. Создайте запрос на подписание сертификата из созданного приватного ключа. Введите запрашиваемую информацию, такую как страна и т.п.:

    openssl req -new -key server.key -out server.csr
    
  4. Сохраните файлы server.key, server.csr и dhparam.pem в безопасном месте, обычно это каталог /etc/clickhouse-server/.

Публичный удостоверяющий центр

Получение сертификатов от публичного или внутреннего удостоверяющих центров происходит путём регистрации в публичном удостоверяющем центре, таком как Let's Encrypt или Verisign или во внутреннем удостоверяющем центре компании. Затем нужно:

  1. Отправить запрос на подписание сертификата в удостоверяющий центр. Удостоверяющий центр подпишет сертификат и вернёт его, обычно как файл с именем server.crt.
  2. Сохраните файл server.crt в безопасное место, обычно это каталог /etc/clickhouse-server/.
Создание приватного удостоверяющего центра

Если у вас нет внутреннего удостоверяющего центра или не нужен публичный удостоверяющий центр, создать приватный удостоверяющий центр можно следующим образом:

  1. Создайте приватный ключ сертификата:

    openssl genrsa -aes256 -out internalCA.key 2048
    
  2. Создайте самозаверенный корневой сертификат из ключа сертификата:

    openssl req -new -x509 -days 3650 -key internalCA.key \
        -sha256 -extensions v3_ca -out internalCA.crt
    
  3. Сохраните приватный ключ сертификата и самозаверенный корневой сертификат в безопасное место.

  4. Подпишите файл server.csr самозаверенным корневым сертификатом:

    openssl x509 -sha256 -req -in server.csr -CA internalCA.crt \
        -CAkey internalCA.key -CAcreateserial -out server.crt -days 365
    
  5. Сохраните файл server.crt в безопасное место, обычно это каталог /etc/clickhouse-server/.

Самозаверенный сертификат

Чтобы создать сразу самозаверенный сертификат, воспользуйтесь следующими инструкциями.

ВАЖНОЕ ЗАМЕЧАНИЕ: Не рекомендуется использовать его в производственных средах, используйте только в тестовых средах.

  1. Возьмите файл server.key, созданный на одном из предыдущих этапов, создайте самозаверенный сертификат. Замените my.host.name на действительное имя сетевого узла:

    openssl req -subj "/CN=my.host.name" -new -key server.key -out server.crt
    
  2. Сохраните файл server.crt в безопасное место, обычно это каталог /etc/clickhouse-server/.

  3. Каждый пользователь clickhouse-client, который подключается к серверу с самозаверенным сертификатом, должен разрешить опцию invalidCertificateHandler, изменив файл конфигурации своего clickhouse-client в каталоге /etc/clickhouse-server/config.d:

    <config>
        <openSSL>
            <client>
            ...
            <invalidCertificateHandler>
                <name>AcceptCertificateHandler</name>
            </invalidCertificateHandler>
            </client>
        </openSSL>
    

Включение TLS в ClickHouse

Как только будут готовы файлы server.crt, server.crt и dhparam.dem и расположены соответствующим образом, обновите файлы конфигурации сервера ClickHouse, находящиеся в каталоге /etc/clickhouse-server/config.d.

Для включения TLS и отключения незашифрованных портов:

  1. Пересмотрите файлы конфигурации в каталоге /etc/clickhouse-server/config.d. Закомментируйте незашифрованные порты, включая порты http_port и tcp_port:

    <!-- <http_port>8123</http_port> -->
    <!-- <tcp_port>9000</tcp_port> -->
    
  2. Включите порты с шифрованием. Полный список портов и настроек доступен на сайте документации ClickHouse в разделе "Конфигурационные параметры сервера". Например:

    <https_port>8443</https_port>
    <tcp_port_secure>9440</tcp_port_secure>
    
  3. Укажите используемые файлы сертификата:

    <openSSL>
        <server>
            <!-- Используется для сервера https и для защищённого порта tcp -->
            <certificateFile>/etc/clickhouse-server/server.crt</certificateFile>
            <privateKeyFile>/etc/clickhouse-server/server.key</privateKeyFile>
            <dhParamsFile>/etc/clickhouse-server/dhparams.pem</dhParamsFile>
            ...
        </server>
        ...
    </openSSL>
    

Шифрование взаимодействий внутри кластера

Если в вашей компании используется кластер ClickHouse, то подключения внутри кластера стоит шифровать. В том числе распределённые запросы и межсервисную репликацию. Для защиты соединений кластера:

  1. Создайте пользователя для распределённых запросов. Этот пользователь должен иметь возможность подключаться только внутри кластера, поэтому ограничьте доступ и разрешите подключаться с IP-адресов только из подсети или ограничьте имена узлов, используемых в сети. Например, если кластер целиком содержится в поддомене под именами logos1, logos2 и т.п. Такого внутреннего пользователя можно настроить с указанием пароля или без него:

    CREATE USER IF NOT EXISTS internal ON CLUSTER 'my_cluster'
      IDENTIFIED WITH NO_PASSWORD
      HOST REGEXP '^logos[1234]$'
    
  2. Включите TLS для межсервисной репликации и закомментируйте межсерверный порт без шифорвания, изменив файлы в каталоге /etc/clickhouse-server/config.d:

    <!-- <interserver_http_port>9009</interserver_http_port> -->
    <interserver_https_port>9010</interserver_https_port> -->
    
  3. Настройте учётные данные для межсерверного взаимодействия по протоколу HTTP в разделе interserver_http_credentials в файле в каталоге /etc/clickhouse-server/config.d и добавьте внутренние имя пользователя и пароль:

    <interserver_http_credentials>
        <user>internal</user>
        <password></password>
    </interserver_http_credentials>
    
  4. Включите TLS для распределённых запросов, отредактировав файл /etc/clickhouse-server/config.d/remote_servers.xml

    1. В случае с ClickHouse 20.10 или более поздней версией, задайте общий секретный текст и настройте порт для защиты каждого сервера:

      <remote_servers>
          <my_cluster>
              <shard>
                  <secret>общий секретный текст</secret> <!-- Замените его -->
                  <internal_replication>true</internal_replication>
                  <replica>
                      <host>logos1</host> <!-- Замените тут -->
                      <port>9440</port> <!-- Безопасный порт -->
                      <secure>1</secure> <!-- Обновите тут, настройте порт как защищённый -->
                  </replica>
              </shard>
              ...
      
    2. Для предыдущих версий ClickHouse настройте внутреннего пользователя и включите безопасный обмен данными:

      <remote_servers>
          <my_cluster>
              <shard>
                  <internal_replication>true</internal_replication>
                  <replica>
                      <host>logos1</host> <!-- Замените это -->
                      <port>9440</port> <!-- Безопасный порт -->
                      <secure>1</secure> <!-- Замените это -->
                      <user>internal</port> <!-- Замените это -->
                  </replica>
                  ...
              </shard>
              ...
      

Защита хранилища

Защита данных, хранящихся в ClickHouse

Данные ClickHouse хранятся в файловой системе. Данные, находящиеся в состоянии покоя, необходимо поддерживать в защищённом виде, чтобы предотвратить доступ посторонних к частным данным вашей компании.

Защитим данные ClickHouse, разделив их на следующе категории:

  • Безопасность на уровне узла
  • Шифрование на уровне тома
  • Шифрование на уровне колонки
  • Защита файла журнала

ВАЖНОЕ ПРИМЕЧАНИЕ: Настройки можно сохранить в файле по умолчанию /etc/clickhouse-server/config.xml. Однако, этот файл может быть заменён в процессе установки обновлений. Для защиты настроек рекомендуется сохранить их в отдельных XML-файлах в каталоге /etc/clickhouse-server/config.d с таким же корневым элементом, обычно это <yandex>. В этом руководстве мы ссылаемся только на файлы конфигурации в каталоге /etc/clickhouse-server/config.d.

Безопасность на уровне узла

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

  • ClickHouse не требует прав пользователя root при работе с файловой системой и по умолчанию работает от имени пользователя clickhouse.
  • Доступ к следующим каталогам стоит ограничить минимальным количеством пользователей:
    • /etc/clickhouse-server: Используется для настройки ClickHouse и учётных записей, созданных по умолчанию.
    • /var/lib/clickhouse: Используется для хранения данных и новых учётных записей ClickHouse.
    • /var/log/clickhouse-server: Файлы журналов, которые могут содержать запросы, раскрывающие секретную информацию. За подробностями обратитесь к главе "Защита файлов журналов".

Шифрование на уровне тома

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

Облачное хранилище

Если база данных ClickHouse хранится в облачном сервисе вроде AWS или Azure, узнайте, поддерживает ли облако шифорвание тома. Например, Amazon AWS предоставляет возможность шифрования новых томов Amazon EBS по умолчанию.

Сервис Altinity.Cloud предоставляет возможность задать тип тома gp2-encrypted. За подробностями обратитесь к документу "Настройки кластера Altinity.Cloud".

Локальное хранилище

Организациям, использующим кластеры ClickHouse на их собственных сиситемах, рекомендуется использовать LUKS. Имеются инструкции для дистрибутивов Linux Red Hat и Ubuntu. Поищите инструкции по шифрованию томов для дистрибутива, используемого в компании.

Шифрование в Kubernetes

Если кластер ClickHouse управляется Kubernetes, можно зашифровать StorageClass. За подробностями обратитесь к документации Kubernetes Storage Class.

Шифрование на уровне колонок

Организации, использующие ClickHouse версии 20.11 или новее, могут шифровать отдельные колонки с помощью функций AES. За полной информацией обратитесь на сайт ClickHouse.tech к документу "Функции шифрования".

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

Доступны следующие функции:

Функция Совместимость с MySQL AES
encrypt(mode, plaintext, key, [iv, aad])
decrypt(mode, ciphertext, key, [iv, aad])
aes_encrypt_mysql(mode, plaintext, key, [iv]) *
aes_decrypt_mysql(mode, ciphertext, key, [iv]) *

Аргументы функций шифрования:

Аргумент Описание Тип
mode Режим шифрования Строка
plaintext Текст для шифрования Строка
key Ключ шифрования Строка
iv Вектор инициализации. Нужен для режимов -gcm, а для других не обязателен Строка
aad Дополнительные данные для аутентификации. Они не зашифрованы, но влияют на расшифровку. Работают только с режимами -gcm, в остальных случаях выбрасывают исключение Строка

Примеры шифрования колонок

В этом примере показано, как шифровать информацию с помощью хэшированного ключа.

  1. Берём шестнадцатеричное значение, преобразуем его в двоичное и сохраняем как ключ.
  2. Выбираем значение и шифруем его с помощью ключа, а затем отображаем зашифрованное значение.

    WITH unhex('658bb26de6f8a069a3520293a572078f') AS key
    SELECT hex(encrypt('aes-128-cbc', 'Hello world', key)) AS encrypted
    ┌─encrypted────────────────────────┐
    │ 46924AC12F4915F2EEF3170B81A1167E │
    └──────────────────────────────────┘
    

Ниже показано, как расшифровать зашифрованные данные:

  1. Берём шестнадцатеричное значение, преобразуем его в двоичное и сохраняем как ключ.
  2. Расшифровываем выбранное значение ключом, получаем текст.

    WITH unhex('658bb26de6f8a069a3520293a572078f') AS key SELECT decrypt('aes-128-cbc',
    unhex('46924AC12F4915F2EEF3170B81A1167E'), key) AS plaintext
    ┌─plaintext───┐
    │ Hello world │
    └─────────────┘
    

Защита файлов журналов

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

2021.01.26 19:11:23.526691 [ 1652 ] {4e196dfa-dd65-4cba-983b-d6bb2c3df7c8}
<Debug> executeQuery: (from [::ffff:127.0.0.1]:54536, using production
parser) WITH unhex('658bb26de6f8a069a3520293a572078f') AS key SELECT
decrypt(???), key) AS plaintext

Эти запросы можно скрыть с помощью правил маскировки запросов, применяя регулярные выражения для замены требуемых команд. За подробностями обратитесь на сайт ClickHouse.tech к документу "Конфигурационные параметры сервера".

Чтобы защитить отдельные запросы от попадания в файл журнала или для сокрытия секретной информации, выполните следующие действия:

  1. Измените файлы конфигурации, которые по умолчанию находятся в каталоге /etc/clickhouse-server/config.d.
  2. Добавьте элемент query_masking_rules.
  3. Задайте для каждого правила следующие настройки:
    1. name: Имя правила.
    2. regexp: Регулярное выражение для поиска.
    3. replace: Значение, которое заменит соответствие, найденное регулярным выражением.

Например, следующие правила скроют из файла журнала функции шифрования и дешифрования:

<query_masking_rules>
    <rule>
        <name>сокрытие аргументов encrypt/decrypt</name>
        <regexp>
            ((?:aes_)?(?:encrypt|decrypt)(?:_mysql)?)\s*\(\s*(?:'(?:\\'|.)+'|.*?)\s*\)
        </regexp>
        <!-- или более безопасно, но и более радикально:
            (aes_\w+)\s*\(.*\)
        -->
        <replace>\1(???)</replace>
    </rule>
</query_masking_rules>