Инструкция по настройке 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.