配置 SSL-TLS
此页面不适用于 ClickHouse Cloud。此处记录的步骤在 ClickHouse Cloud 服务中是自动化的。
本指南提供简单且最少的设置,用于配置 ClickHouse 使用 OpenSSL 证书来验证连接。为了演示,创建了自签名证书颁发机构 (CA) 证书和密钥以及节点证书,以便使用适当的设置进行连接。
TLS 的实现很复杂,需要考虑许多选项以确保完全安全和稳健的部署。这是一个包含基本 SSL/TLS 配置示例的基础教程。请咨询您的 PKI/安全团队,为您的组织生成正确的证书。
查看这个关于证书使用的基础教程,以获得入门概述。
1. 创建 ClickHouse 部署
本指南使用 Ubuntu 20.04 和 ClickHouse 编写,ClickHouse 使用 DEB 包(使用 apt)安装在以下主机上。域名为 marsnet.local
主机 | IP 地址 |
---|---|
chnode1 | 192.168.1.221 |
chnode2 | 192.168.1.222 |
chnode3 | 192.168.1.223 |
查看快速入门以获取有关如何安装 ClickHouse 的更多详细信息。
2. 创建 SSL 证书
使用自签名证书仅用于演示目的,不应在生产环境中使用。应创建证书请求,以便由组织签名,并使用将在设置中配置的 CA 链进行验证。但是,这些步骤可用于配置和测试设置,然后可以替换为将要使用的实际证书。
-
生成将用于新 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 证书备份到集群之外的安全位置。生成节点证书后,应从集群节点中删除密钥。
-
验证新 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 -
验证证书的主题和颁发者
openssl x509 -in chnode1.crt -text -noout
-
检查新证书是否针对 CA 证书进行验证
openssl verify -CAfile marsnet_ca.crt chnode1.crt
chnode1.crt: OK
3. 创建和配置目录以存储证书和密钥。
这必须在每个节点上完成。在每个主机上使用适当的证书和密钥。
-
在每个节点中 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
4. 使用 ClickHouse Keeper 配置具有基本集群的环境
对于此部署环境,每个节点都使用以下 ClickHouse Keeper 设置。每台服务器都有自己的 <server_id>
。(例如,节点 chnode1
的 <server_id>1</server_id>
,依此类推。)
建议 ClickHouse Keeper 使用端口 9281
。但是,该端口是可配置的,如果环境中的另一个应用程序已在使用此端口,则可以设置该端口。
有关所有选项的完整说明,请访问 https://clickhouse.ac.cn/docs/en/operations/clickhouse-keeper/
-
将以下内容添加到 ClickHouse 服务器
config.xml
中<clickhouse>
标签内注意对于生产环境,建议在
config.d
目录中使用单独的.xml
配置文件。有关更多信息,请访问 https://clickhouse.ac.cn/docs/en/operations/configuration-files/<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 仲裁。注意对于此配置,仅配置了一个示例集群。测试示例集群必须删除、注释掉,或者如果存在正在测试的现有集群,则必须更新端口并添加
<secure>
选项。如果默认用户最初配置为在安装或 users.xml 文件中设置密码,则必须设置<user>
和<password>
。以下命令创建一个集群,该集群在两台服务器(每个节点一台)上具有一个分片副本。
<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>
5. 在 ClickHouse 节点上配置 SSL-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 Native 安全 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
注意每个文件名和路径都必须更新以匹配正在配置的节点。例如,在
chnode2
主机中进行配置时,将<certificateFile>
条目更新为chnode2.crt
。<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> -
在每个节点上为 SSL 配置 gRPC
<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.ac.cn/docs/en/interfaces/grpc/
-
在至少一个节点上配置 ClickHouse 客户端,以在其自己的 config.xml 文件(默认情况下在
/etc/clickhouse-client/
中)中使用 SSL 进行连接<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-->
6. 测试
-
一次启动所有节点
service clickhouse-server start
-
验证安全端口已启动并在监听,在每个节点上应类似于此示例
root@chnode1:/etc/clickhouse-server# netstat -ano | grep tcp
tcp 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 interserver https 端口 9281 ClickHouse Keeper 安全端口 9440 安全 Native TCP 协议 9444 ClickHouse Keeper Raft 端口 -
验证 ClickHouse Keeper 健康状况。典型的 4 字母单词 (4lW) 命令在使用不带 TLS 的
echo
时不起作用,以下是如何将openssl
与命令一起使用。- 使用 openssl 启动交互式会话
openssl s_client -connect chnode1.marsnet.local:9281
CONNECTED(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
标志和 SSL 端口启动 ClickHouse 客户端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。注意浏览器将显示不受信任的证书,因为它从工作站访问,并且证书不在客户端计算机上的根 CA 存储中。当使用公共机构或企业 CA 颁发的证书时,它应该显示受信任。
-
创建一个复制表
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 │
└────┴────────────┴─────────┘
总结
本文重点介绍如何配置具有 SSL/TLS 的 ClickHouse 环境。生产环境中不同要求的设置会有所不同;例如,证书验证级别、协议、密码等。但是您现在应该对配置和实施安全连接所涉及的步骤有很好的了解。