이 가이드는 OpenSSL 인증서를 사용해 연결을 검증하도록 ClickHouse를 구성하는 간단하고 최소한의 설정을 제공합니다. 이 데모에서는 적절한 설정으로 연결할 수 있도록 자체 서명된 인증 기관(CA) 인증서와 키를 생성하고, 노드 인증서도 함께 생성합니다.
ClickHouse 배포 생성
이 가이드는 Ubuntu 20.04 환경에서 DEB 패키지(apt 사용)를 사용해 다음 호스트에 ClickHouse를 설치한 기준으로 작성되었습니다. 도메인은 marsnet.local입니다:
| 호스트 | IP 주소 |
|---|---|
chnode1 |
192.168.1.221 |
chnode2 |
192.168.1.222 |
chnode3 |
192.168.1.223 |
TLS 인증서 생성
-
새 CA에 사용할 키를 생성합니다:
openssl genrsa -out marsnet_ca.key 2048 -
새 자체 서명 CA 인증서를 생성합니다. 다음 명령은 CA 키를 사용해 다른 인증서에 서명할 때 사용할 새 인증서를 생성합니다:
openssl req -x509 -subj "/CN=marsnet.local CA" -nodes -key marsnet_ca.key -days 1095 -out marsnet_ca.crt
-
새 CA 인증서의 내용을 확인합니다:
openssl x509 -in marsnet_ca.crt -text -
각 노드에 대해 인증서 요청(CSR)을 생성하고 키를 만듭니다:
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 -
CSR과 CA를 사용해 새 인증서 및 키 쌍을 생성합니다:
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 -
subject와 issuer를 기준으로 인증서를 확인합니다:
openssl x509 -in chnode1.crt -text -noout -
새 인증서가 CA 인증서를 기준으로 검증되는지 확인합니다:
openssl verify -CAfile marsnet_ca.crt chnode1.crt chnode1.crt: OK
인증서와 키를 저장할 디렉터리를 생성하고 구성합니다.
-
각 노드에서 ClickHouse가 접근할 수 있는 디렉터리에 폴더를 생성합니다. 기본 구성 디렉터리(예:
/etc/clickhouse-server)를 사용하는 것을 권장합니다.mkdir /etc/clickhouse-server/certs -
CA 인증서, 노드 인증서, 그리고 각 노드에 해당하는 키를 새
certs디렉터리로 복사합니다. -
ClickHouse가 인증서를 읽을 수 있도록 소유자와 권한을 변경합니다.
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
ClickHouse Keeper를 사용한 기본 클러스터 환경 구성
이 배포 환경에서는 각 노드에 다음 ClickHouse Keeper 설정이 사용됩니다. 각 서버는 고유한 <server_id>를 가집니다. (예시: chnode1 노드의 경우 <server_id>1</server_id>, 나머지 노드도 동일합니다.)
- ClickHouse 서버
config.xml의<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>-
모든 노드에서 Keeper 설정의 주석 처리를 해제하고 값을 수정한 뒤
<secure>플래그를 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> -
다음 클러스터 설정을
chnode1및chnode2에 추가하고 업데이트하십시오.chnode3은 ClickHouse Keeper 쿼럼에 사용됩니다.
다음은 두 서버에 세그먼트 레플리카가 하나씩 있는 클러스터를 생성합니다(각 노드에 하나씩).
<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>-
테스트용 ReplicatedMergeTree 테이블을 생성할 수 있게 매크로 값을 정의합니다.
chnode1에서:<macros> <shard>1</shard> <replica>replica_1</replica> </macros>chnode2에서:<macros> <shard>1</shard> <replica>replica_2</replica> </macros>
ClickHouse 노드에서 TLS 인터페이스 구성
아래 설정은 ClickHouse 서버의 config.xml에서 구성합니다.
-
배포의 표시 이름을 설정합니다(선택 사항):
<display_name>clickhouse</display_name> -
ClickHouse가 외부 포트에서 수신하도록 설정합니다:
<listen_host>0.0.0.0</listen_host> -
각 노드에서
https포트를 구성하고http포트를 비활성화합니다:<https_port>8443</https_port> {/*<http_port>8123</http_port>*/} -
각 노드에서 ClickHouse 네이티브 보안 TCP 포트를 구성하고 기본 비보안 포트를 비활성화합니다:
<tcp_port_secure>9440</tcp_port_secure> {/*<tcp_port>9000</tcp_port>*/} -
각 노드에서
interserver https포트를 구성하고 기본 비보안 포트를 비활성화합니다:<interserver_https_port>9010</interserver_https_port> {/*<interserver_http_port>9009</interserver_http_port>*/} -
인증서와 경로를 사용하도록 OpenSSL을 구성합니다
<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>자세한 내용은 이 페이지를 참조하십시오.
-
모든 노드에서 gRPC에 TLS를 구성합니다:
<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>자세한 내용은 https://clickhouse.com/docs/interfaces/grpc/ 를 참조하십시오.
-
최소 하나의 노드에서 ClickHouse client가 연결에 TLS를 사용하도록 해당 노드의
config.xml파일(기본 경로:/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> -
MySQL 및 PostgreSQL의 기본 에뮬레이션 포트를 비활성화합니다:
{/*mysql_port>9004</mysql_port*/} {/*postgresql_port>9005</postgresql_port*/}
테스트
-
모든 노드를 하나씩 시작하십시오:
service clickhouse-server start -
보안 포트가 열려 있고 수신 대기 상태인지 확인하십시오. 각 노드에서 다음 예시와 비슷하게 표시되어야 합니다:
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)ClickHouse 포트 설명 8443 HTTPS 인터페이스 9010 서버 간 HTTPS 포트 9281 ClickHouse Keeper 보안 포트 9440 보안 네이티브 TCP 프로토콜 9444 ClickHouse Keeper Raft 포트 -
ClickHouse Keeper 상태 확인 일반적인 4 letter word (4lW) 명령은 TLS 없이
echo로는 작동하지 않습니다. 아래는openssl을 사용해 해당 명령을 실행하는 방법입니다.openssl을 실행해 대화형 세션을 시작합니다
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
...-
OpenSSL 세션에서 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
-
--secure플래그와 TLS 포트를 사용해 clickhouse client를 시작하십시오: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 :) -
https인터페이스를 통해https://chnode1.marsnet.local:8443/play의 Play UI에 로그인하세요.
-
복제된 테이블(Replicated Table)을 생성하세요:
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 │ └───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘ -
chnode1에 두어 개의 행을 추가하세요:INSERT INTO repl_table (id, column1, column2) VALUES (1,'2022-04-01','abc'), (2,'2022-04-02','def'); -
chnode2에서 행을 확인하여 복제가 제대로 되었는지 확인합니다:SELECT * FROM repl_table┌─id─┬────column1─┬─column2─┐ │ 1 │ 2022-04-01 │ abc │ │ 2 │ 2022-04-02 │ def │ └────┴────────────┴─────────┘
독립 실행형 ClickHouse Keeper용 OpenSSL 구성
ClickHouse Keeper를 독립 실행형 ClickHouse Keeper 프로세스(ClickHouse 서버에 내장되지 않은 형태)로 실행하는 경우, OpenSSL 인증서와 설정은 Keeper 설정 파일에서 별도로 구성해야 합니다. 이를 구성하지 않으면 Keeper는 클라이언트 통신(tcp_port_secure)이나 Keeper 노드 간 Raft 복제를 위한 보안 연결을 설정할 수 없습니다.
각 노드의 독립 실행형 ClickHouse Keeper 설정 파일에 다음 <openSSL> 섹션을 추가하십시오:
<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><server> 섹션은 보안 Keeper 포트(tcp_port_secure)로 들어오는 클라이언트 연결에 사용됩니다. <client> 섹션은 Raft 복제 중 Keeper 노드 간에 이루어지는 아웃바운드 연결에 사용됩니다.
OpenSSL 검증 모드 및 인증서 핸들러
<openSSL> 구성은 ClickHouse가 TLS 인증서를 검증하는 방식을 제어하는 <verificationMode> 및 <invalidCertificateHandler>에 대해 여러 옵션을 지원합니다. 이러한 설정은 clickhouse-server, clickhouse-client 및 독립 실행형 ClickHouse Keeper에 적용됩니다.
검증 모드
<openSSL>의 <server> 또는 <client> 섹션에서 <verificationMode>를 설정합니다:
| 모드 | 설명 |
|---|---|
none |
인증서를 검증하지 않습니다. 연결은 암호화되지만 피어의 아이덴티티는 확인하지 않습니다. 테스트에만 사용하십시오. |
relaxed |
피어 인증서가 제시되면 이를 검증하지만, 인증서가 제공되지 않아도 실패하지 않습니다. |
once |
server 측에서는 초기 핸드셰이크에서만 client 인증서를 검증하고 재협상은 건너뜁니다. client 측에서는 relaxed와 동일하게 동작합니다. |
strict |
피어 인증서를 요구하고 완전히 검증합니다. 인증서가 없거나 만료되었거나 신뢰할 수 있는 CA가 서명하지 않은 경우 연결이 실패합니다. 프로덕션 환경에 권장됩니다. |
유효하지 않은 인증서 핸들러
<openSSL>의 <server> 또는 <client> 섹션 내에 <invalidCertificateHandler>를 설정합니다. 이 핸들러는 인증서 검증에 실패했을 때 어떻게 처리할지를 결정합니다. server 측에서는 유효하지 않은 클라이언트 인증서에 대한 응답을 제어합니다. client 측에서는 유효하지 않은 server 인증서에 대한 응답을 제어합니다.
| 핸들러 | 설명 |
|---|---|
RejectCertificateHandler |
인증서가 유효하지 않으면 connection을 거부합니다. 기본값이며 권장되는 설정입니다. |
AcceptCertificateHandler |
인증서가 유효하지 않아도 connection을 허용합니다. 테스트 용도로만 사용하십시오. |
예시: 인증서 검증 비활성화
인증서 검증을 완전히 건너뛰려면(예를 들어 테스트 환경에서 자체 서명 인증서를 사용하는 경우) verificationMode를 none으로 설정하고 AcceptCertificateHandler를 사용하십시오.
clickhouse-client에서는 --accept-invalid-certificate CLI 플래그를 사용할 수도 있으며, 이 경우 두 설정이 모두 자동으로 적용됩니다.
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 또는 config.d/의 파일). 서버가 클라이언트의 인증서를 검증하지 않더라도 자체 인증서를 클라이언트에 제시해야 하므로, <server> 섹션에는 여전히 인증서와 개인 키 경로가 필요합니다:
<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 (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>요약
이 문서에서는 TLS가 적용된 ClickHouse 환경을 구성하는 방법을 중점적으로 살펴보았습니다. 프로덕션 환경에서는 요구 사항에 따라 설정이 달라질 수 있습니다. 예를 들어 인증서 검증 수준, 프로토콜, 암호군 등이 달라질 수 있습니다. 이제 보안 연결을 구성하고 구현하는 데 필요한 단계는 충분히 이해할 수 있을 것입니다.