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