Как настроить SSL-соединение ClickHouse

Инструкция по настройке SSL-соединения с ClickHouse с помощью самоподписных сертификатов.

Что включает эта настройка:

  • У вас должны быть установлены ClickHouse и OpenSSL
  • Нужно сгенерировать файлы, связанные с SSL
  • Настроить сервер ClickHouse
  • Протестировать SSL-соединение с клиента

Инсталляция ClickHouse и OpenSSL

Имеем следующие версии продуктов

# clickhouse-client -q "select version()"
22.3.7.28
# openssl version
OpenSSL 1.0.2k-fips  26 Jan 2017

Конфигурация кластера ClickHouse

Физически кластер состоит из трех нод. Также сконфигурирован один кластер ClickHouse с шардом на всех нодах.

    <remote_servers>
        <default_cluster>
            <shard>
                <internal_replication>true</internal_replication>
                <weight>1</weight>
                <replica>
                    <host>server1</host>
                    <port>9000</port>
                </replica>
            </shard>
            <shard>
                <internal_replication>true</internal_replication>
                <weight>1</weight>
                <replica>
                    <host>server2</host>
                    <port>9000</port>
                </replica>
            </shard>
            <shard>
                <internal_replication>true</internal_replication>
                <weight>1</weight>
                <replica>
                    <host>server3</host>
                    <port>9000</port>
                </replica>
            </shard>
        </default_cluster>
    </remote_servers>

Генерируем сертификаты SSL

На серверах ClickHouse нам нужны 3 сертификата для настройки SSL:

  • ca-cert.pem (доверенный корневой сертификат)
  • serverN-cert.pem (сертификат сервера N)
  • serverN-key.pem (закрытый ключ сервера N)

Сгенерируем закрытый ключ центра сертификации и самозаверяющий сертификат с помощью openssl.

openssl req -newkey rsa:4096 -x509 -days 3650 -nodes -batch -keyout ca-key.pem -out ca-cert.pem -subj "/C=RU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=ca"

Проверим.

openssl x509 -in ca-cert.pem -text

Сгенерируем закрытый ключ сервера и запрос на подписание сертификата (CSR). Имена выбираем произвольно, мы используем очевидное serverN.*, где N — это номер сервера. В дальнейшем, следует подставлять вмеcто N номер сервера. В параметре CN указываем имя сервера.

openssl req -newkey rsa:4096 -nodes -batch -keyout server1-key.pem -out server1-req.pem -subj "/C=RU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=server1"
openssl req -newkey rsa:4096 -nodes -batch -keyout server2-key.pem -out server2-req.pem -subj "/C=RU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=server2"
openssl req -newkey rsa:4096 -nodes -batch -keyout server3-key.pem -out server3-req.pem -subj "/C=RU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=server3"

Создадим конфигурационные файлы со списком расширений X.509, которые будут добавлены в сертификат. Укажем имена и IP адреса серверов для того, чтобы можно было использовать имена и IP для подключения к серверу.

echo "subjectAltName=DNS:server1.domain.local,IP:192.168.1.221" > server1-ext.cnf
echo "subjectAltName=DNS:server2.domain.local,IP:192.168.1.222" > server2-ext.cnf
echo "subjectAltName=DNS:server3.domain.local,IP:192.168.1.223" > server3-ext.cnf

Подписываем запрос на сертификат нашим корневым сертификатом и получим подписанный сертификат.

openssl x509 -req -days 3650 -in server1-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -extfile server1-ext.cnf -out server1-cert.pem
openssl x509 -req -days 3650 -in server2-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -extfile server2-ext.cnf -out server2-cert.pem
openssl x509 -req -days 3650 -in server3-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -extfile server3-ext.cnf -out server3-cert.pem

Проверим.

openssl x509 -in server1-cert.pem -text -noout
openssl x509 -in server1-cert.pem -text -noout | grep -A1 "Subject Alternative Name"
openssl verify -CAfile ca-cert.pem server1-cert.pem
openssl x509 -in server2-cert.pem -text -noout
openssl x509 -in server2-cert.pem -text -noout | grep -A1 "Subject Alternative Name"
openssl verify -CAfile ca-cert.pem server2-cert.pem
openssl x509 -in server3-cert.pem -text -noout
openssl x509 -in server3-cert.pem -text -noout | grep -A1 "Subject Alternative Name"
openssl verify -CAfile ca-cert.pem server3-cert.pem

Генерируем сертификат пользователя

Сгенерируйте закрытый ключ клиента и запрос на подписание сертификата (CSR).
Обратите внимание на параметр CN. Он будет использоваться при создании пользователя.

openssl req -newkey rsa:4096 -nodes -batch -keyout client1-key.pem -out client1-req.pem -subj "/C=RU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=client1"
openssl req -newkey rsa:4096 -nodes -batch -keyout client2-key.pem -out client2-req.pem -subj "/C=RU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=client2"

Используя закрытый ключ CA для подписи CSR клиента, получим подписанный сертификаты

openssl x509 -req -days 3650 -in client1-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out client1-cert.pem
openssl x509 -req -days 3650 -in client2-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out client2-cert.pem

Сгенерируйте еще один самозаверяющий сертификат и закрытый ключ для использования в качестве неправильного сертификата (не подписанный центром сертификации)

openssl req -newkey rsa:4096 -x509 -days 3650 -nodes -batch -keyout wrong-key.pem -out wrong-cert.pem -subj "/C=RU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=client"

Настроим сервер ClickHouse

Скопируем файлы

  • ca-cert.pem (доверенный корневой сертификат)
  • serverN-cert.pem (сертификат сервера N)
  • serverN-key.pem (закрытый ключ сервера N)

в директорию /etc/clickhouse-server/certs и изменим права на файлы на всех нодах кластера.

mkdir /etc/clickhouse-server/certs
cp ca-cert.pem /etc/clickhouse-server/certs
cp server*-cert.pem /etc/clickhouse-server/certs
cp server*-key.pem /etc/clickhouse-server/certs
chown clickhouse:clickhouse -R /etc/clickhouse-server/certs
chmod 600 /etc/clickhouse-server/certs/*
chmod 755 /etc/clickhouse-server/certs
ll /etc/clickhouse-server/certs

Настроим httpsпорт и отключим httpпорт на каждом узле в файле config.xml:

    <https_port>8443</https_port>
    <!--<http_port>8123</http_port>-->

Настроим OpenSSL с помощью сертификатов и путей (исправьте имена ключей serverN).

<openSSL>
        <server> <!-- Used for https server AND secure tcp port -->
            <certificateFile>/etc/clickhouse-server/certs/serverN-cert.pem</certificateFile>
            <privateKeyFile>/etc/clickhouse-server/certs/serverN-key.pem</privateKeyFile>
            <caConfig>/etc/clickhouse-server/certs/ca-cert.pem</caConfig>
            <verificationMode>relaxed</verificationMode>
        </server>
        <client> <!-- Used for connecting to https dictionary source and secured Zookeeper communication -->
            <loadDefaultCAFile>true</loadDefaultCAFile>
            <cacheSessions>true</cacheSessions>
            <disableProtocols>sslv2,sslv3</disableProtocols>
            <preferServerCiphers>true</preferServerCiphers>
            <!-- Use for self-signed: <verificationMode>none</verificationMode> -->
            <invalidCertificateHandler>
                <!-- Use for self-signed: <name>AcceptCertificateHandler</name> -->
                <name>RejectCertificateHandler</name>
            </invalidCertificateHandler>
        </client>
</openSSL>

Создадим пользователей с возможностью аутентификации по сертификату. Обратите внимание на параметры common_name и CN. Их указывали при создании сертификатов в параметре CN.

Одного пользователя в файле users.xml добавив строчки в секцию <users>.

        <john>
            <ssl_certificates>
                <common_name>client1</common_name>
            </ssl_certificates>
        </john>

И на каждой ноде выполним команду в clickhouse-client.

CREATE USER lucy IDENTIFIED WITH ssl_certificate CN 'client2';
GRANT ALL ON *.* TO lucy WITH GRANT OPTION;

Выполняем рестарт кластера.

systemctl restart clickhouse-server
sleep 10
systemctl status clickhouse-server

И выполняем проверку действительных сертификатов для разных пользователей...

echo 'SELECT currentUser();' |  \
curl   'https://server1.domain.local:8443/' \
--cert ./client1-cert.pem \
--key ./client1-key.pem \
--cacert ./ca-cert.pem \
-H "X-ClickHouse-SSL-Certificate-Auth: on"  \
-H "X-ClickHouse-User: john" \
--data-binary @-

# вывод john

echo 'SELECT currentUser();' |  \
curl   'https://server2.domain.local:8443/' \
--cert ./client2-cert.pem \
--key ./client2-key.pem \
--cacert ./ca-cert.pem \
-H "X-ClickHouse-SSL-Certificate-Auth: on"  \
-H "X-ClickHouse-User: lucy" \
--data-binary @-
# вывод lucy

Если мы попробуем проверить недействительные сертификаты, то получим ошибку.

echo 'SELECT currentUser();' |  \
curl   'https://server3.domain.local:8443/' \
--cert ./wrong-cert.pem \
--key ./wrong-key.pem \
--cacert ./ca-cert.pem \
-H "X-ClickHouse-SSL-Certificate-Auth: on"  \
-H "X-ClickHouse-User: john" \
--data-binary @-
# вывод curl: (35) Peer does not recognize and trust the CA that issued your certificate.

Добавить комментарий

Ваш адрес email не будет опубликован.