跳到主要内容

配置 SSL-TLS

注意

此页面不适用于 ClickHouse 云。此处记录的过程在 ClickHouse 云服务中是自动化的。

本指南提供了简单的最小设置,以配置 ClickHouse 使用 OpenSSL 证书验证连接。为了演示,使用节点证书创建自签名证书颁发机构 (CA) 证书和密钥,以便通过适当的设置进行连接。

注意

TLS 实现很复杂,并且有许多选项需要考虑,以确保完全安全和强大的部署。这是一个关于基本 SSL/TLS 配置示例的基本教程。咨询您的 PKI/安全团队以生成适合您组织的正确证书。

查看此 证书使用基础教程,以了解入门概述。

1. 创建 ClickHouse 部署

本指南使用 Ubuntu 20.04 编写,并使用 DEB 包(使用 apt)在以下主机上安装了 ClickHouse。域名是 marsnet.local

主机IP 地址
chnode1192.168.1.221
chnode2192.168.1.222
chnode3192.168.1.223
注意

查看 快速入门,了解有关如何安装 ClickHouse 的更多详细信息。

2. 创建 SSL 证书

注意

使用自签名证书仅用于演示目的,不应用于生产环境。应创建证书请求以由组织签名并使用将在设置中配置的 CA 链进行验证。但是,这些步骤可用于配置和测试设置,然后可以由将要使用的实际证书替换。

  1. 生成将用于新 CA 的密钥

    openssl genrsa -out marsnet_ca.key 2048
  2. 生成一个新的自签名 CA 证书。以下将创建一个新的证书,该证书将用于使用 CA 密钥签署其他证书

    openssl req -x509 -subj "/CN=marsnet.local CA" -nodes -key marsnet_ca.key -days 1095 -out marsnet_ca.crt
    注意

    将密钥和 CA 证书备份到集群中没有的安全位置。生成节点证书后,应从集群节点中删除密钥。

  3. 验证新 CA 证书的内容

    openssl x509 -in marsnet_ca.crt -text
  4. 为每个节点创建证书请求 (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
  5. 使用 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
  6. 验证证书的主题和颁发者

    openssl x509 -in chnode1.crt -text -noout
  7. 检查新的证书是否已针对 CA 证书进行验证

    openssl verify -CAfile marsnet_ca.crt chnode1.crt
    chnode1.crt: OK

3. 创建并配置一个目录来存储证书和密钥。

注意

这必须在每个节点上完成。在每个主机上使用适当的证书和密钥。

  1. 在每个节点上,在 ClickHouse 可访问的目录中创建一个文件夹。我们建议使用默认的配置目录(例如 /etc/clickhouse-server

    mkdir /etc/clickhouse-server/certs
  2. 将与每个节点对应的 CA 证书、节点证书和密钥复制到新的证书目录中。

  3. 更新所有者和权限以允许 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/certs
    total 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>。(例如,<server_id>1</server_id> 用于节点 chnode1,依此类推。)

注意

推荐的端口是 ClickHouse Keeper 的 9281。但是,端口是可配置的,如果此端口已被环境中的另一个应用程序使用,则可以设置该端口。

有关所有选项的完整说明,请访问 https://clickhouse.ac.cn/docs/en/operations/clickhouse-keeper/

  1. 在 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>
  2. 取消注释并在所有节点上更新 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>
  3. 更新并将以下集群设置添加到 chnode1chnode2chnode3 将用于 ClickHouse Keeper 仲裁。

    注意

    对于此配置,只配置了一个示例集群。测试样本集群必须被删除、注释掉,或者如果存在正在测试的现有集群,则必须更新端口,并且必须添加 <secure> 选项。如果 default 用户最初在安装过程中或在 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>
  4. 定义宏值以能够创建 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 中配置

  1. 设置部署的显示名称(可选)

    <display_name>clickhouse</display_name>
  2. 设置 ClickHouse 侦听外部端口

    <listen_host>0.0.0.0</listen_host>
  3. 配置 https 端口并在每个节点上禁用 http 端口

    <https_port>8443</https_port>
    <!--<http_port>8123</http_port>-->
  4. 配置 ClickHouse Native 安全 TCP 端口并在每个节点上禁用默认的非安全端口

    <tcp_port_secure>9440</tcp_port_secure>
    <!--<tcp_port>9000</tcp_port>-->
  5. 配置 interserver https 端口并在每个节点上禁用默认的非安全端口

    <interserver_https_port>9010</interserver_https_port>
    <!--<interserver_http_port>9009</interserver_http_port>-->
  6. 使用证书和路径配置 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>

    有关更多信息,请访问 https://clickhouse.ac.cn/docs/en/operations/server-configuration-parameters/settings/#server_configuration_parameters-openssl

  1. 在每个节点上配置用于 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/

  2. 在至少一个节点上配置 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>
  3. 禁用 MySQL 和 PostgreSQL 的默认模拟端口

    <!--mysql_port>9004</mysql_port-->
    <!--postgresql_port>9005</postgresql_port-->

6. 测试

  1. 一次启动所有节点

    service clickhouse-server start
  2. 验证安全端口已启动并正在侦听,应该类似于每个节点上的此示例

    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 端口描述
    8443https 接口
    9010interserver https 端口
    9281ClickHouse Keeper 安全端口
    9440安全 Native TCP 协议
    9444ClickHouse Keeper Raft 端口
  3. 验证 ClickHouse Keeper 运行状况。典型的 四字母字 (4lW) 命令将无法使用 echo 在没有 TLS 的情况下工作,以下是使用 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
  4. 使用 --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 :)
  5. 使用 https 接口登录 Play UI,地址为 https://chnode1.marsnet.local:8443/play

    Play UI

    注意

    浏览器将显示一个不受信任的证书,因为它是从工作站访问的,并且证书不在客户端机器上的根 CA 存储中。使用从公共机构或企业 CA 颁发的证书时,它应该显示为受信任的。

  6. 创建复制表

    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 │
    └───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
  7. chnode1 上添加几行

    INSERT INTO repl_table
    (id, column1, column2)
    VALUES
    (1,'2022-04-01','abc'),
    (2,'2022-04-02','def');
  8. 通过查看 chnode2 上的行来验证复制

    SELECT * FROM repl_table
    ┌─id─┬────column1─┬─column2─┐
    │ 1 │ 2022-04-01 │ abc │
    │ 2 │ 2022-04-02 │ def │
    └────┴────────────┴─────────┘

摘要

本文重点介绍了如何配置支持 SSL/TLS 的 ClickHouse 环境。生产环境中的设置会因不同需求而异,例如证书验证级别、协议、密码等。但您现在应该对配置和实现安全连接的步骤有了很好的了解。