Esta guía ofrece una configuración sencilla y mínima para que ClickHouse use certificados OpenSSL para validar conexiones. Para esta demostración, se crean un certificado y una clave de una autoridad de certificación (CA) autofirmada, junto con certificados de nodo, a fin de establecer las conexiones con la configuración adecuada.
Crear una implementación de ClickHouse
Esta guía se redactó con Ubuntu 20.04 y con ClickHouse instalado en los siguientes hosts mediante el paquete DEB (con apt). El dominio es marsnet.local:
| Host | Dirección IP |
|---|---|
chnode1 |
192.168.1.221 |
chnode2 |
192.168.1.222 |
chnode3 |
192.168.1.223 |
Crear certificados TLS
-
Genere una clave que se utilizará para la nueva CA:
openssl genrsa -out marsnet_ca.key 2048 -
Genere un nuevo certificado de CA autofirmado. Lo siguiente creará un nuevo certificado que se utilizará para firmar otros certificados con la clave de la CA:
openssl req -x509 -subj "/CN=marsnet.local CA" -nodes -key marsnet_ca.key -days 1095 -out marsnet_ca.crt
-
Verifique el contenido del nuevo certificado de CA:
openssl x509 -in marsnet_ca.crt -text -
Cree una solicitud de certificado (CSR) y genere una clave para cada nodo:
openssl req -newkey rsa:2048 -nodes -subj "/CN=chnode1" -addext "subjectAltName = DNS:chnode1.marsnet.local,IP:192.168.1.221" -keyout chnode1.key -out chnode1.csr openssl req -newkey rsa:2048 -nodes -subj "/CN=chnode2" -addext "subjectAltName = DNS:chnode2.marsnet.local,IP:192.168.1.222" -keyout chnode2.key -out chnode2.csr openssl req -newkey rsa:2048 -nodes -subj "/CN=chnode3" -addext "subjectAltName = DNS:chnode3.marsnet.local,IP:192.168.1.223" -keyout chnode3.key -out chnode3.csr -
Con la CSR y la CA, cree nuevos pares de certificado y clave:
openssl x509 -req -in chnode1.csr -out chnode1.crt -CA marsnet_ca.crt -CAkey marsnet_ca.key -days 365 -copy_extensions copy openssl x509 -req -in chnode2.csr -out chnode2.crt -CA marsnet_ca.crt -CAkey marsnet_ca.key -days 365 -copy_extensions copy openssl x509 -req -in chnode3.csr -out chnode3.crt -CA marsnet_ca.crt -CAkey marsnet_ca.key -days 365 -copy_extensions copy -
Verifique en los certificados los campos subject e issuer:
openssl x509 -in chnode1.crt -text -noout -
Compruebe que los nuevos certificados se validan con el certificado de la CA:
openssl verify -CAfile marsnet_ca.crt chnode1.crt chnode1.crt: OK
Cree y configure un directorio para almacenar certificados y claves.
-
Cree una carpeta en un directorio accesible para ClickHouse en cada nodo. Recomendamos usar el directorio de configuración predeterminado (por ejemplo,
/etc/clickhouse-server):mkdir /etc/clickhouse-server/certs -
Copie el certificado de la CA, el certificado del nodo y la clave correspondientes a cada nodo en el nuevo directorio
certs. -
Actualice el propietario y los permisos para que ClickHouse pueda leer los certificados:
chown clickhouse:clickhouse -R /etc/clickhouse-server/certs chmod 600 /etc/clickhouse-server/certs/* chmod 755 /etc/clickhouse-server/certs ll /etc/clickhouse-server/certstotal 20 drw-r--r-- 2 clickhouse clickhouse 4096 Apr 12 20:23 ./ drwx------ 5 clickhouse clickhouse 4096 Apr 12 20:23 ../ -rw------- 1 clickhouse clickhouse 997 Apr 12 20:22 chnode1.crt -rw------- 1 clickhouse clickhouse 1708 Apr 12 20:22 chnode1.key -rw------- 1 clickhouse clickhouse 1131 Apr 12 20:23 marsnet_ca.crt
Configurar el entorno con clústeres básicos mediante ClickHouse Keeper
Para este entorno de implementación, se utilizan las siguientes configuraciones de ClickHouse Keeper en cada nodo. Cada servidor tendrá su propio <server_id>. (Por ejemplo, <server_id>1</server_id> para el nodo chnode1, y así sucesivamente.)
- Añada lo siguiente dentro de la etiqueta
<clickhouse>delconfig.xmldel servidor ClickHouse
<keeper_server>
<tcp_port_secure>9281</tcp_port_secure>
<server_id>1</server_id>
<log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
<snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
<coordination_settings>
<operation_timeout_ms>10000</operation_timeout_ms>
<session_timeout_ms>30000</session_timeout_ms>
<raft_logs_level>trace</raft_logs_level>
</coordination_settings>
<raft_configuration>
<secure>true</secure>
<server>
<id>1</id>
<hostname>chnode1.marsnet.local</hostname>
<port>9444</port>
</server>
<server>
<id>2</id>
<hostname>chnode2.marsnet.local</hostname>
<port>9444</port>
</server>
<server>
<id>3</id>
<hostname>chnode3.marsnet.local</hostname>
<port>9444</port>
</server>
</raft_configuration>
</keeper_server>-
Descomente y actualice la configuración de Keeper en todos los nodos, y establezca el indicador
<secure>en 1:<zookeeper> <node> <host>chnode1.marsnet.local</host> <port>9281</port> <secure>1</secure> </node> <node> <host>chnode2.marsnet.local</host> <port>9281</port> <secure>1</secure> </node> <node> <host>chnode3.marsnet.local</host> <port>9281</port> <secure>1</secure> </node> </zookeeper> -
Actualice y añada la siguiente configuración del clúster en
chnode1ychnode2.chnode3se usará para el quórum de ClickHouse Keeper.
A continuación se crea un clúster con una réplica de segmento en dos servidores (uno en cada nodo).
<remote_servers>
<cluster_1S_2R>
<shard>
<replica>
<host>chnode1.marsnet.local</host>
<port>9440</port>
<user>default</user>
<password>ClickHouse123!</password>
<secure>1</secure>
</replica>
<replica>
<host>chnode2.marsnet.local</host>
<port>9440</port>
<user>default</user>
<password>ClickHouse123!</password>
<secure>1</secure>
</replica>
</shard>
</cluster_1S_2R>
</remote_servers>-
Defina los valores de las macros para poder crear una tabla ReplicatedMergeTree de prueba. En
chnode1:<macros> <shard>1</shard> <replica>replica_1</replica> </macros>En
chnode2:<macros> <shard>1</shard> <replica>replica_2</replica> </macros>
Configurar interfaces TLS en nodos de ClickHouse
Los ajustes que aparecen a continuación se configuran en el config.xml del servidor ClickHouse
-
Establezca el nombre para mostrar de la implementación (opcional):
<display_name>clickhouse</display_name> -
Configure ClickHouse para que escuche en puertos externos:
<listen_host>0.0.0.0</listen_host> -
Configure el puerto
httpsy deshabilite el puertohttpen cada nodo:<https_port>8443</https_port> {/*<http_port>8123</http_port>*/} -
Configure el puerto TCP seguro nativo de ClickHouse y deshabilite el puerto no seguro predeterminado en cada nodo:
<tcp_port_secure>9440</tcp_port_secure> {/*<tcp_port>9000</tcp_port>*/} -
Configure el puerto
interserver httpsy deshabilite el puerto no seguro predeterminado en cada nodo:<interserver_https_port>9010</interserver_https_port> {/*<interserver_http_port>9009</interserver_http_port>*/} -
Configure OpenSSL con certificados y rutas
<openSSL>
<server>
<certificateFile>/etc/clickhouse-server/certs/chnode1.crt</certificateFile>
<privateKeyFile>/etc/clickhouse-server/certs/chnode1.key</privateKeyFile>
<verificationMode>relaxed</verificationMode>
<caConfig>/etc/clickhouse-server/certs/marsnet_ca.crt</caConfig>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
</server>
<client>
<loadDefaultCAFile>false</loadDefaultCAFile>
<caConfig>/etc/clickhouse-server/certs/marsnet_ca.crt</caConfig>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
<verificationMode>relaxed</verificationMode>
<invalidCertificateHandler>
<name>RejectCertificateHandler</name>
</invalidCertificateHandler>
</client>
</openSSL>Para obtener más información, visita esta página
-
Configura TLS para gRPC en cada nodo:
<grpc> <enable_ssl>1</enable_ssl> <ssl_cert_file>/etc/clickhouse-server/certs/chnode1.crt</ssl_cert_file> <ssl_key_file>/etc/clickhouse-server/certs/chnode1.key</ssl_key_file> <ssl_require_client_auth>true</ssl_require_client_auth> <ssl_ca_cert_file>/etc/clickhouse-server/certs/marsnet_ca.crt</ssl_ca_cert_file> <transport_compression_type>none</transport_compression_type> <transport_compression_level>0</transport_compression_level> <max_send_message_size>-1</max_send_message_size> <max_receive_message_size>-1</max_receive_message_size> <verbose_logs>false</verbose_logs> </grpc>Para obtener más información, visita https://clickhouse.com/docs/interfaces/grpc/
-
Configura ClickHouse client en al menos uno de los nodos para que use TLS en las conexiones en su propio archivo
config.xml(de forma predeterminada, en/etc/clickhouse-client/):<openSSL> <client> <loadDefaultCAFile>false</loadDefaultCAFile> <caConfig>/etc/clickhouse-server/certs/marsnet_ca.crt</caConfig> <cacheSessions>true</cacheSessions> <disableProtocols>sslv2,sslv3</disableProtocols> <preferServerCiphers>true</preferServerCiphers> <invalidCertificateHandler> <name>RejectCertificateHandler</name> </invalidCertificateHandler> </client> </openSSL> -
Deshabilita los puertos de emulación predeterminados para MySQL y PostgreSQL:
{/*mysql_port>9004</mysql_port*/} {/*postgresql_port>9005</postgresql_port*/}
Pruebas
-
Inicie todos los nodos, uno por uno:
service clickhouse-server start -
Verifique que los puertos seguros estén activos y en escucha; debería verse similar a este ejemplo en cada nodo:
root@chnode1:/etc/clickhouse-server# netstat -ano | grep tcptcp 0 0 0.0.0.0:9010 0.0.0.0:* LISTEN off (0.00/0/0) tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN off (0.00/0/0) tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN off (0.00/0/0) tcp 0 0 0.0.0.0:8443 0.0.0.0:* LISTEN off (0.00/0/0) tcp 0 0 0.0.0.0:9440 0.0.0.0:* LISTEN off (0.00/0/0) tcp 0 0 0.0.0.0:9281 0.0.0.0:* LISTEN off (0.00/0/0) tcp 0 0 192.168.1.221:33046 192.168.1.222:9444 ESTABLISHED off (0.00/0/0) tcp 0 0 192.168.1.221:42730 192.168.1.223:9444 ESTABLISHED off (0.00/0/0) tcp 0 0 192.168.1.221:51952 192.168.1.222:9281 ESTABLISHED off (0.00/0/0) tcp 0 0 192.168.1.221:22 192.168.1.210:49801 ESTABLISHED keepalive (6618.05/0/0) tcp 0 64 192.168.1.221:22 192.168.1.210:59195 ESTABLISHED on (0.24/0/0) tcp6 0 0 :::22 :::* LISTEN off (0.00/0/0) tcp6 0 0 :::9444 :::* LISTEN off (0.00/0/0) tcp6 0 0 192.168.1.221:9444 192.168.1.222:59046 ESTABLISHED off (0.00/0/0) tcp6 0 0 192.168.1.221:9444 192.168.1.223:41976 ESTABLISHED off (0.00/0/0)Puerto de ClickHouse Descripción 8443 interfaz HTTPS 9010 puerto HTTPS entre servidores 9281 puerto seguro de ClickHouse Keeper 9440 protocolo TCP Native seguro 9444 puerto Raft de ClickHouse Keeper -
Verifique el estado de ClickHouse Keeper Los comandos típicos de 4 letter word (4lW) no funcionan con
echosin TLS. A continuación se explica cómo usar estos comandos conopenssl.- Inicie una sesión interactiva con
openssl
- Inicie una sesión interactiva con
openssl s_client -connect chnode1.marsnet.local:9281CONNECTED(00000003)
depth=0 CN = chnode1
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = chnode1
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:CN = chnode1
i:CN = marsnet.local CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICtDCCAZwCFD321grxU3G5pf6hjitf2u7vkusYMA0GCSqGSIb3DQEBCwUAMBsx
...-
En la sesión de OpenSSL, envíe los comandos 4LW
mntr--- Post-Handshake New Session Ticket arrived: SSL-Session: Protocol : TLSv1.3 ... read R BLOCK zk_version v22.7.3.5-stable-e140b8b5f3a5b660b6b576747063fd040f583cf3 zk_avg_latency 0 zk_max_latency 4087 zk_min_latency 0 zk_packets_received 4565774 zk_packets_sent 4565773 zk_num_alive_connections 2 zk_outstanding_requests 0 zk_server_state leader zk_znode_count 1087 zk_watch_count 26 zk_ephemerals_count 12 zk_approximate_data_size 426062 zk_key_arena_size 258048 zk_latest_snapshot_size 0 zk_open_file_descriptor_count 187 zk_max_file_descriptor_count 18446744073709551615 zk_followers 2 zk_synced_followers 1 closed
-
Inicie el cliente de ClickHouse con la opción
--securey el puerto TLS:root@chnode1:/etc/clickhouse-server# clickhouse-client --user default --password ClickHouse123! --port 9440 --secure --host chnode1.marsnet.local ClickHouse client version 22.3.3.44 (official build). Connecting to chnode1.marsnet.local:9440 as user default. Connected to ClickHouse server version 22.3.3 revision 54455. clickhouse :) -
Inicie sesión en la UI de Play mediante la interfaz
httpsenhttps://chnode1.marsnet.local:8443/play.
-
Cree una tabla replicada:
clickhouse :) CREATE TABLE repl_table ON CLUSTER cluster_1S_2R ( id UInt64, column1 Date, column2 String ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/default/repl_table', '{replica}' ) ORDER BY (id);┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐ │ chnode2.marsnet.local │ 9440 │ 0 │ │ 1 │ 0 │ │ chnode1.marsnet.local │ 9440 │ 0 │ │ 0 │ 0 │ └───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘ -
Añade un par de filas en
chnode1:INSERT INTO repl_table (id, column1, column2) VALUES (1,'2022-04-01','abc'), (2,'2022-04-02','def'); -
Verifique la replicación consultando las filas en
chnode2:SELECT * FROM repl_table┌─id─┬────column1─┬─column2─┐ │ 1 │ 2022-04-01 │ abc │ │ 2 │ 2022-04-02 │ def │ └────┴────────────┴─────────┘
Configurar OpenSSL para ClickHouse Keeper en modo independiente
Al ejecutar ClickHouse Keeper como un proceso independiente (en lugar de estar integrado en ClickHouse server), los certificados y la configuración de OpenSSL deben configurarse por separado en el archivo de configuración de Keeper. De lo contrario, Keeper no podrá establecer conexiones seguras para la comunicación con el cliente (tcp_port_secure) ni para la replicación Raft entre nodos de Keeper.
Agregue la siguiente sección <openSSL> al archivo de configuración de ClickHouse Keeper en modo independiente en cada nodo:
<openSSL>
<server>
<certificateFile>/etc/clickhouse-keeper/certs/chnode1.crt</certificateFile>
<privateKeyFile>/etc/clickhouse-keeper/certs/chnode1.key</privateKeyFile>
<verificationMode>relaxed</verificationMode>
<caConfig>/etc/clickhouse-keeper/certs/marsnet_ca.crt</caConfig>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
</server>
<client>
<loadDefaultCAFile>false</loadDefaultCAFile>
<caConfig>/etc/clickhouse-keeper/certs/marsnet_ca.crt</caConfig>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
<verificationMode>relaxed</verificationMode>
<invalidCertificateHandler>
<name>RejectCertificateHandler</name>
</invalidCertificateHandler>
</client>
</openSSL>La sección <server> se utiliza para las conexiones entrantes de los clientes en el puerto seguro de Keeper (tcp_port_secure). La sección <client> se utiliza para las conexiones salientes entre nodos de Keeper durante la replicación de Raft.
Modos de verificación de OpenSSL y manejadores de certificados
La configuración <openSSL> admite varias opciones para <verificationMode> y <invalidCertificateHandler> que controlan cómo ClickHouse valida los certificados TLS. Estos ajustes se aplican a clickhouse-server, clickhouse-client y ClickHouse Keeper en modo independiente.
Modos de verificación
Configure <verificationMode> en la sección <server> o <client> de <openSSL>:
| Modo | Descripción |
|---|---|
none |
Sin verificación de certificados. La conexión está cifrada, pero no se comprueba la identidad del peer. Úselo solo para pruebas. |
relaxed |
Verifica el certificado del peer si se presenta, pero no falla si no se proporciona ninguno. |
once |
En el lado del servidor, verifica el certificado del cliente solo durante el handshake inicial y omite la renegociación. En el lado del cliente, se comporta igual que relaxed. |
strict |
Requiere y verifica por completo el certificado del peer. La conexión falla si el certificado no está presente, ha caducado o no está firmado por una CA de confianza. Recomendado para producción. |
Manejadores de certificados no válidos
Configura <invalidCertificateHandler> en la sección <server> o <client> de <openSSL>. Este manejador determina qué ocurre cuando falla la verificación del certificado. En el lado del servidor, controla la respuesta ante certificados de cliente no válidos. En el lado del cliente, controla la respuesta ante certificados de servidor no válidos.
| Manejador | Descripción |
|---|---|
RejectCertificateHandler |
Rechaza la conexión si el certificado no es válido. Esta es la configuración predeterminada y recomendada. |
AcceptCertificateHandler |
Acepta la conexión incluso si el certificado no es válido. Úsalo solo para pruebas. |
Ejemplo: desactivar la verificación de certificados
Para omitir por completo la verificación de certificados (por ejemplo, al usar certificados autofirmados en un entorno de pruebas), establezca verificationMode en none y use AcceptCertificateHandler.
En clickhouse-client, también puede usar la opción de CLI --accept-invalid-certificate, que aplica ambos ajustes automáticamente.
clickhouse-client (/etc/clickhouse-client/config.xml):
<openSSL>
<client>
<loadDefaultCAFile>false</loadDefaultCAFile>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
<verificationMode>none</verificationMode>
<invalidCertificateHandler>
<name>AcceptCertificateHandler</name>
</invalidCertificateHandler>
</client>
</openSSL>clickhouse-server (config.xml o un archivo en config.d/). La sección <server> aún requiere las rutas al certificado y a la clave privada, porque el servidor debe presentar su propio certificado a los clientes, incluso cuando no verifica el de estos:
<openSSL>
<server>
<certificateFile>/etc/clickhouse-server/certs/server.crt</certificateFile>
<privateKeyFile>/etc/clickhouse-server/certs/server.key</privateKeyFile>
<verificationMode>none</verificationMode>
<caConfig>/etc/clickhouse-server/certs/ca.crt</caConfig>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
</server>
<client>
<loadDefaultCAFile>false</loadDefaultCAFile>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
<verificationMode>none</verificationMode>
<invalidCertificateHandler>
<name>AcceptCertificateHandler</name>
</invalidCertificateHandler>
</client>
</openSSL>ClickHouse Keeper independiente (archivo de configuración de Keeper):
<openSSL>
<server>
<certificateFile>/etc/clickhouse-keeper/certs/keeper.crt</certificateFile>
<privateKeyFile>/etc/clickhouse-keeper/certs/keeper.key</privateKeyFile>
<verificationMode>none</verificationMode>
<caConfig>/etc/clickhouse-keeper/certs/ca.crt</caConfig>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
</server>
<client>
<loadDefaultCAFile>false</loadDefaultCAFile>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
<verificationMode>none</verificationMode>
<invalidCertificateHandler>
<name>AcceptCertificateHandler</name>
</invalidCertificateHandler>
</client>
</openSSL>Resumen
Este artículo se ha centrado en configurar un entorno de ClickHouse con TLS. Los ajustes variarán según los requisitos de cada entorno de producción; por ejemplo, los niveles de verificación de certificados, los protocolos, los cifrados, etc. Pero ahora debería tener una buena comprensión de los pasos necesarios para configurar e implementar conexiones seguras.