ClickHouse数据库SSL配置和SSL连接测试

目录

[1.Server SSL配置介绍](#1.Server SSL配置介绍)

[2.Client SSL访问配置的介绍](#2.Client SSL访问配置的介绍)

[3.my测试环境上开启ClickHouse Server SSL配置 & 客户端SSL访问的配置流程](#3.my测试环境上开启ClickHouse Server SSL配置 & 客户端SSL访问的配置流程)

4.附录

1)SSL证书的几种类型

单域名SSL证书

通配符SSL证书

多域名SSL证书

多域名通配符SSL证书

2)单域名SSL证书生成

3)通配符SSL证书(泛域名SSL证书)生成

[4)多域名通配符SSL证书(配置了 SAN)生成](#4)多域名通配符SSL证书(配置了 SAN)生成)

[5)Java 默认内置的根证书](#5)Java 默认内置的根证书)


ClickHouse数据库SSL配置和SSL连接测试

1.Server SSL配置介绍

1)Configuring SSL User Certificate for Authentication(配置使用 SSL 用户证书进行身份验证):

英文:

https://clickhouse.com/docs/en/guides/sre/ssl-user-auth

中文:

https://clickhouse.ac.cn/docs/en/guides/sre/ssl-user-auth

2)Configuring SSL-TLS(配置 SSL-TLS):

英文:

https://clickhouse.com/docs/en/guides/sre/configuring-ssl

中文:

https://clickhouse.ac.cn/docs/en/guides/sre/configuring-ssl

3)SSL X.509 certificate authentication:

英文:

https://clickhouse.com/docs/en/operations/external-authenticators/ssl-x509

中文:

https://clickhouse.ac.cn/docs/en/operations/external-authenticators/ssl-x509

4)Global Server Settings(其中包含了 openSSL 服务器配置文件中的ssl相关配置、以及秘钥和证书文件的说明)

在 openSSL 章节描述了 privateKeyFile 、certificateFile 、caConfig、verificationMode、loadDefaultCAFile、extendedVerification 等配置参数。

英文:

https://clickhouse.com/docs/en/operations/server-configuration-parameters/settings#openssl

中文:

https://clickhouse.ac.cn/docs/en/operations/server-configuration-parameters/settings#openssl

2.Client SSL访问配置的介绍

1)JDBC Connect to ClickHouse with SSL:

英文:

https://clickhouse.com/docs/en/integrations/java/jdbc-driver

中文:

https://clickhouse.ac.cn/docs/en/integrations/java/jdbc-driver

里面介绍了JDBC SSL连接相关的SSL参数(SSL Properties)。

JDBC 连接相关的 SSL 参数:

Name | Default Value | Optional Values | Description

ssl | false | true, false | Whether to enable SSL/TLS for the connection

sslmode | strict | strict, none | Whether to verify SSL/TLS certificate

sslrootcert | -- | -- | Path to SSL/TLS root certificates

sslcert | -- | -- | Path to SSL/TLS certificate

sslkey | -- | -- | RSA key in PKCS#8 format

key_store_type | -- | JKS, PKCS12 | Specifies the type or format of the keystore/truststore file

trust_store | -- | -- | Path to the truststore file

key_store_password | -- | -- | Password needed to access the keystore file specified in the keystore config

2)关于 sslmode 参数值:

https://github.com/ClickHouse/poco/blob/master/NetSSL_OpenSSL/include/Poco/Net/Context.h

中有相更详细的介绍。

sslmode 支持: none | relaxed | strict| once。

服务器支持这四种配置,JDBC连接参数官方描述仅支持 none 和 strict 两种。

sslmode=none :

VERIFY_NONE = SSL_VERIFY_NONE。

访问走 https 加密协议。

Server:服务端不会要求客户端提供证书。服务端不会向客户端发送证书提供请求,所以,客户端压根不会发送证书给服务端。

Client:如果不使用匿名密码(默认禁用),服务端将会发送证书给客户端,客户端会校验,但校验结果将被忽略。无论校验成功还是校验失败,最终都是连接成功。

sslmode=relaxed :

VERIFY_RELAXED = SSL_VERIFY_PEER。【宽松检查】

访问走 https 加密协议。

Server: 服务端会要求客户端必须提供证书。服务端会向客户端发送证书提供请求。

客户端如果有证书:会发送证书给服务端。则服务端会校验客户端发送的证书。如果证书校验失败、则TLS/SSL握手阶段失败、连接立即失败。

客户端如果无证书:则不会发送证书给服务端。服务端不涉及证书校验。

Client: 如果服务端提供了证书、会校验服务端证书,如果证书校验失败、连接失败。如果服务端无证书,则不校验。

sslmode=strict :

VERIFY_STRICT = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT。 【严格检查】

访问走 https 加密协议。

Server: 服务端会要求客户端必须提供证书。如果客户端未提供证书、或者提供了证书但证书校验失败,则TLS/SSL握手阶段失败、连接立即失败。

Client: 和relaxed模式的Client行为相同。

sslmode=once :

VERIFY_ONCE = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE。

访问走 https 加密协议。

Server:服务端只在TLS/SSL握手阶段要求客户端必须提供证书。

Client: 和relaxed模式的Client行为相同。

ClickHouse JDBC SSL 访问格式:

Driver Class: com.clickhouse.jdbc.ClickHouseDriver

URL Syntax: jdbc:(ch|clickhouse)[:<protocol>]://endpoint1[,endpoint2,...][/<database>][?param1=value1&param2=value2][#tag1,tag2,...], for example:

jdbc:ch://localhost is same as jdbc:clickhouse:http://localhost:8123

jdbc:ch:https://localhost is same as jdbc:clickhouse:http://localhost:8443?ssl=true\&sslmode=STRICT

jdbc:ch:grpc://localhost is same as jdbc:clickhouse:grpc://localhost:9100

ClickHouse 默认端口:

http/https 端口:

8123: 默认http端口(clickhouse-client(common client)、clickhouse-http-client、clickhouse-jdbc-client 访问端口)

8443: 默认https端口(clickhouse-client(common client)、clickhouse-http-client、clickhouse-jdbc-client SSL安全访问端口)

tcp/tcps 端口:

9000: 默认tcp端口(clickhouse-cli-client、clickhouse-native-jdbc-client 访问端口)

9440:默认tcp安全端口(clickhouse-cli-client、clickhouse-native-jdbc-client SSL安全访问端口)

grpc/grpcs端口:

9100: 默认grpc(google RCP)端口,grpc/grpcs。

ClickHouse JDBC 和 Native JDBC 区别:Native JDBC 基于TCP协议,支持压缩等高级特性、性能高,但部分SQL语法该方式不支持。

示例1:

String url = "jdbc:ch://your-server:8443/default";

Properties properties = new Properties();

properties.setProperty("ssl", "true");

properties.setProperty("sslmode", "strict"); // NONE to trust all servers; STRICT for trusted only

properties.setProperty("sslrootcert", "/mine.crt");

try (Connection con = DriverManager

.getConnection(url, properties)) {

try (PreparedStatement stmt = con.prepareStatement(

// place your code here

}

}

3.my测试环境上开启ClickHouse Server SSL配置 & 客户端SSL访问的配置流程

准备工作

ssl 证书查看相关命令:

openssl x509 -in ca.crt -noout -text #查看CA证书内容(-text 打印其他所有信息,-noout 不打印证书信息)

openssl x509 -in ca.crt -text #查看CA证书内容(-text 打印其他所有信息)

openssl rsa -in chnode1.key -text #查看Server私钥文件中的私钥信息

openssl x509 -in chnode1.crt -noout -text #查看Server证书详细信息(包括公钥)

openssl rsa -in client1.key -text #查看Client私钥文件中的私钥信息

openssl x509 -in client1.crt -noout -text #查看Client证书详细信息(包括公钥)

1)进入容器内操作

docker exec -it clickhouse-server /bin/bash

2)先确认是否安装了 openssl,如果没有装、需要先安装

openssl

如果命令不存在、则先执行下面命令安装:

yum install -y openssl

3)创建证书目录

一般证书放在配置目录下( mkdir -p /etc/clickhouse-server/certs ) 。

我因为 docker 容器挂载没有直接挂整个配置目录、而只挂了配置文件,所以,我把证书文件在数据库目录 /var/lib/clickhouse 下了:

mkdir -p /var/lib/clickhouse/certs

4)切换到证书目录

cd /var/lib/clickhouse/certs

接下来参考 配置 SSL-TLS 的文档 https://clickhouse.ac.cn/docs/en/guides/sre/configuring-ssl 继续操作、创建和配置证书。

注意:我没有配置使用SSL用户证书进行身份验证,只是配置了 SSL-TLS 证书验证。

如果实际业务需求需要配置使用SSL用户证书进行身份验证的话,可以参考官方资料介绍:https://clickhouse.ac.cn/docs/en/guides/sre/ssl-user-auth

两者配置有区别。

1)服务端生成 CA 私钥,生成 ca.key:

openssl genrsa -out ca.key 2048

2)服务端生成自签名 CA 证书,生成 ca.crt,该证书将用于使用 CA 密钥签署其他证书:

openssl req -x509 -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=ca" -nodes -key ca.key -days 3650 -out ca.crt

注意:在创建证书请求文件的时候需要注意几点,下面生成服务器请求文件和客户端请求文件均要注意这三点:

a)根证书的CN(Common Name)填写 ca 或者 root 就可以了,而所有客户端和服务器端的证书的这个字段需要填写域名或IP;

b)一定要注意的是:根证书的这个 CN 字段和客户端证书、服务器端证书不能一样;

c)其他所有字段的填写,根证书、服务器端证书、客户端证书三者需保持一致、最后的密码可以直接回车跳过。

验证 CA 证书内容、查看所有信息:

openssl x509 -in ca.crt -text

注意:

clickhouse-server 和 clickhouse-client(clickhouse CLI命令行)用到的 ca 是 ca.crt (一般 c 语言用的是 ca.crt),

如果存在 Java 客户单使用 ca 证书时,用的是 JKS 证书、Java9及以上保本默认用 PKCS12 证书。这里可以按需选择是否要将 ca.crt 导出成 JKS、PKCS12 格式证书。

将 ca.crt(x509格式)证书导入生成 truststore(JKS),设置一个证书信息提取密码,我设置了:1q2w3e。

提示 Trust this certificate? [no]: yes 则输入 yes。生成 JKS truststore 的命令如下:

keytool -importcert -alias ca -file ca.crt -keystore truststore -storepass 1q2w3e

查看truststore中的证书信息:

keytool -list -v -keystore truststore

3)创建服务端证书请求(CSR)并生成服务端私钥(如果服务端是集群、则需要为每个节点创建一个),生成 chnode1.csr、chnode1.key:

openssl req -newkey rsa:2048 -nodes -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=chnode1.mytest01.com" -keyout chnode1.key -out chnode1.csr

关于CN和SAN:

CN(Common Name 公共名)和 SAN(Subject Alternative Name 主题备用名)匹配来增强服务器端证书验证。

如果配置文件启用服务器主机名验证时,证书中包含的 CN 和 SAN 值将与服务器的主机名进行比较。如果配置的主机名与证书中的 CN 或 SAN 值不匹配,那么与后端服务器的连接将失败。SAN 支持泛域名。

SAN 是 SSL 标准 x509 中定义的一个扩展。使用了 SAN 字段的 SSL 证书,可以扩展此证书支持的域名,使得一个证书可以支持多个不同域名的解析,不再需要为每一个域名买一个 SSL 证书了。

CN 和 SAN 的一般规则:

CN -- 一般把你的主 URL(主机域名或者 /etc/hosts 中 IP 对应的 hostname) 放在这个通用名配置中(为了兼容性)。

SAN -- 一般把你所有的域放在这个主体备用名配置中,重复 CN。

CN 字段已被弃用、但仍然被广泛使用。为了确保绝对正确,您应该将所有名称都放入 SAN 字段中。CN 字段应该包含主题名称而不是域名。

假设使用者备用名(SAN)属性包含两个 DNS 的话,例如:

mytest01.com

chnode1.mytest01.com

设置 CN 时、仅设置两者之一:CN=domain.example。不能同时设置两个 CN,因为 CN 只能保存一个名称。

您可以使用2个简单的 CN 证书而不用一个 CN + SAN 证书的话,您需要2个 IP 地址。

如果一个证书要保护多个域名或者子域名,则可以参考后面附录中的泛域名SSL证书、多域名SSL证书生成方式。

openssl rsa -in chnode1.key -text #查看Server私钥文件中的私钥信息

4)使用服务端证书请求 CSR 和 CA 根证书,创建服务端证书密钥对(如果服务端是集群、则需要为每个节点创建一对服务端密钥对),生成 chnode1.crt(指定 -CAcreateserial 参数同时会自动生成一个 ca.srl,否则会因为 ca.srl 不存在而报错)

openssl x509 -req -in chnode1.csr -out chnode1.crt -CA ca.crt -CAkey ca.key -days 3650 -CAcreateserial

验证服务端证书 & 私钥文件内容、查看所有信息:

openssl x509 -in chnode1.crt -noout -text #查看Server证书详细信息(包括公钥)

openssl rsa -in chnode1.key -text #查看Server私钥文件中的私钥信息

5)检查新生成的服务端证书是否已针对 CA 证书进行验证(通过):

openssl verify -CAfile ca.crt chnode1.crt

chnode1.crt: OK

服务端秘钥和证书生成完毕,生成的文件列表如下:

root@39f30b0a4934:/var/lib/clickhouse/certs# ls -l

total 28

-rw-r--r-- 1 root root 1074 Oct 31 19:25 ca.crt

-rw-r--r-- 1 root root 1675 Oct 31 19:25 ca.key

-rw-r--r-- 1 root root 17 Oct 31 19:26 ca.srl

-rw-r--r-- 1 root root 973 Oct 31 19:26 chnode1.crt

-rw-r--r-- 1 root root 899 Oct 31 19:25 chnode1.csr

-rw-r--r-- 1 root root 1704 Oct 31 19:25 chnode1.key

-rw-r--r-- 1 root root 812 Oct 31 19:27 truststore

如果前面没有生成 truststore 则文件列表如下:

root@39f30b0a4934:/var/lib/clickhouse/certs# ls -l

total 24

-rw-r--r-- 1 root root 1074 Oct 31 19:25 ca.crt

-rw-r--r-- 1 root root 1675 Oct 31 19:25 ca.key

-rw-r--r-- 1 root root 17 Oct 31 19:26 ca.srl

-rw-r--r-- 1 root root 973 Oct 31 19:26 chnode1.crt

-rw-r--r-- 1 root root 899 Oct 31 19:25 chnode1.csr

-rw-r--r-- 1 root root 1704 Oct 31 19:25 chnode1.key

6)如果是集群、请确认为每个节点都生成了服务端证书和秘钥,或者使用泛域名SSL证书。

如果访问的域名和证书秘钥库中的域名不匹配的话,会报错:

Caused by: java.security.cert.CertificateException: No name matching chnode2.mytest01.com found

at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:231)

at sun.security.util.HostnameChecker.match(HostnameChecker.java:96)

at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:462)

at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:428)

at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:209)

at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)

at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)

at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)

at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)

at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)

at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)

at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)

at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)

at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)

at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)

7)生成客户端证书和秘钥:

非必须的步骤。如果需要双向认证,可以继续为客户端创建客户端证书密钥对。如果不需要双向认证,这步可以跳过(因为后续客户端配置时无需指定客户端证书和秘钥)。

和前面服务器证书生成类似,参考前面的步骤,生成客户端的证书密钥对,命令如下:

openssl req -newkey rsa:2048 -nodes -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=client1.mytest01.com" -keyout client1.key -out client1.csr

openssl x509 -req -in client1.csr -out client1.crt -CA ca.crt -CAkey ca.key -days 3650

如果客户端应用 JDBC 连接参数 sslkey 要求使用 其他格式(PKCS#8 或 PKCS#12),RSA私钥是PKCS#1、可以通过openssl命令转换成Apache读取证书私钥格式PKCS#8、或者PKCS#12:

openssl pkcs8 -topk8 -inform PEM -in client1.key -outform PEM -nocrypt -out client1.p8 #生成 PCKS#8 格式的 Client 证书(如果需要)

openssl pkcs12 -export -in client1.crt -inkey client1.key -name client1 -out client1.p12 #生成 PCKS#12 格式的 Client 证书(如果需要)

如果客户端应用需要用到JKS格式的keystore(Java应用用JKS格式),可以将将 PCKS#12 转换成JKS keystore:

keytool -importkeystore -v -srckeystore client1.p12 -srcstoretype pkcs12 -srcstorepass 1q2w3e -destkeystore client1.keystore -deststoretype jks -deststorepass 1q2w3e #生成 jks 格式的 keystore(如果需要)

openssl rsa -in client1.key -text #查看Client私钥文件中的私钥信息

openssl x509 -in client1.crt -noout -text #查看Client证书详细信息(包括公钥)

openssl verify -CAfile ca.crt client1.crt #检查新生成的客户端证书是否已针对 CA 证书进行验证(通过)

注意:

如果后续有不同类型的客户端、需要用到不同格式的证书(例如:JKS、PKCS12 格式),生成客户端证书和私钥后,可以在这里提前同时生成或转换 PKCS12、JKS 不同格式的文件。

当然,这里非必须的步骤。也可以先跳过、直接进入下面的步骤8,等后续客户端需要用到时,再转换/生成 JKS、PKCS12 格式文件。

数字证书是公钥的载体,而密钥库可以包含公钥、私钥信息。JKS 和 PKCS12 都是比较常用的两种密钥库格式/标准。

JKS 文件:Java Key Store 密钥库文件。搞Java开发、尤其是接触过 HTTPS 平台的同学并不陌生。

JKS 文件是通过 Java 原生工具 keytool 创建或者转换其他格式证书文件而生成,通常命名为 *.jks 或 *.keystore(与扩展名无关、仅标识而已)。

有些软件SSL使用时会将 crt 和 key 分开两个文件单独存放,而 Java 应用则将他们存在一个 *.jks 或 *.keystore 文件中,再设置一个提取信息的密码。

Java8(及以前的版本)中默认的 keystore 类型是 JKS,即如果您在使用 keytool 创建 keystore 时没有指定 -storetype,那么 keystore 格式将为JKS。

Java9(及以后的版本)中默认的 密钥库类型将更改为 PKCS12,因为它与 JKS 相比具有增强的兼容性。

PKCS12 文件:通常为 *.p12 或 *.pfx。它是通过 openssl 命令生成的。

PKCS12 文件是通过 openssl 生成的。通常命名为 *.pfx 或 *.p12。使用 DRE 格式编码(二进制内容)。

有些软件SSL使用时会将 crt 和 key 分开两个文件单独存放,而 Windows IIS 则将他们存在一个 *.pfx 或 *.p12 文件中,再设置一个提取信息的密码。

JKS 和 PKCS12 这两种格式的文件可以通过导入/导出的方式进行转换,Java keytool 工具可以将其进行转换。

keytool 命令参数:

-importkeystore 导入密钥库。通过格式设置,可以将 PKCS12文件转换为JKS格式。

-v 显示详情。

-srckeystore 源密钥库文件。

-srcstoretype 源密钥库格式。

-srcstorepass 源密钥库密码。

-destkeystore 目标密钥库文件。

-deststoretype 目标密钥库格式:JKS 或 PKCS12(如果不设置该参数,默认是JKS)

-deststorepass 目标密钥库密码,设置目标秘钥库访问密码。

生成 PKCS12 格式的文件(含证书和私钥):

执行 openssl 命令将 RSA 私钥转 PKCS12 格式的文件(转换时会提示设置一个转换后的目标私钥库的密码):

执行时会提示设置密码,我设置为 1q2w3e。-name client1 我设置了别名(Alias name)为 client1。

生成的 client1.p12 文件中会包含 证书 和 私钥 两部分内容:

openssl pkcs12 -export -in client1.crt -inkey client1.key -name client1 -out client1.p12

生成 JKS 格式的文件(含证书和私钥、给Java客户端使用):

keytool 实现 PKCS12 转 JKS:

keytool -importkeystore -v -srckeystore client1.p12 -srcstoretype pkcs12 -srcstorepass 1q2w3e -destkeystore client1.keystore -deststoretype jks -deststorepass 1q2w3e

查看keystore中的证书信息:

keytool -list -v -keystore client1.keystore

keytool 也能支持将 JKS 转 PKCS12,如果有人提供了 JSK 密钥库文件,需要转 PKCS12 格式化的话,可以用 keytool 转换:

keytool -importkeystore -v -srckeystore client1.keystore -srcstoretype jks -srcstorepass 1q2w3e -destkeystore client1.p12 -deststoretype pkcs12 -deststorepass 1q2w3e

8)证书目录下证书文件生成完毕以后、重新进行一下授权:

chown -R clickhouse:clickhouse /var/lib/clickhouse/certs

查看证书目录文件列表:

root@6fa485afcbf4:/var/lib/clickhouse/certs# ls -l

total 48

-rw-r--r-- 1 clickhouse clickhouse 1074 Oct 31 11:25 ca.crt

-rw-r--r-- 1 clickhouse clickhouse 1675 Oct 31 11:25 ca.key

-rw-r--r-- 1 clickhouse clickhouse 17 Oct 31 11:31 ca.srl

-rw-r--r-- 1 clickhouse clickhouse 973 Oct 31 11:26 chnode1.crt

-rw-r--r-- 1 clickhouse clickhouse 899 Oct 31 11:25 chnode1.csr

-rw-r--r-- 1 clickhouse clickhouse 1704 Oct 31 11:25 chnode1.key

-rw-r--r-- 1 clickhouse clickhouse 973 Oct 31 11:31 client1.crt

-rw-r--r-- 1 clickhouse clickhouse 899 Oct 31 11:31 client1.csr

-rw-r--r-- 1 clickhouse clickhouse 1704 Oct 31 11:31 client1.key

-rw-r--r-- 1 clickhouse clickhouse 2032 Oct 31 11:32 client1.keystore

-rw-r--r-- 1 clickhouse clickhouse 2340 Oct 31 11:32 client1.p12

-rw-r--r-- 1 clickhouse clickhouse 812 Oct 31 11:27 truststore

证书和秘钥创建完毕、记下来就是修改ClickHouse服务器配置、开启SSL。

9)ClickHouse Server 配置修改开启SSL:

ClickHouse集群环境开启SSL的配置修改,可以参考官方的文档(4、5章节有详细介绍):https://clickhouse.ac.cn/docs/en/guides/sre/configuring-ssl

我的docker环境的ClickHouse单节点的配置修改如下:

修改ClickHouse配置文件 config.xml 、使用SSL证书:

vim /etc/clickhouse-server/config.xml

如果docker内没有vi或vim命令,则退出到宿主机上修改挂载目录下的对应配置文件:

vim /data/clickhouse/conf/config.xml

修改<openSSL></openSSL>的配置如下:

<openSSL>

<server>

<certificateFile>/var/lib/clickhouse/certs/chnode1.crt</certificateFile>

<privateKeyFile>/var/lib/clickhouse/certs/chnode1.key</privateKeyFile>

<verificationMode>relaxed</verificationMode>

<loadDefaultCAFile>false</loadDefaultCAFile>

<caConfig>/var/lib/clickhouse/certs/ca.crt</caConfig>

<cacheSessions>true</cacheSessions>

<disableProtocols>sslv2,sslv3</disableProtocols>

<preferServerCiphers>true</preferServerCiphers>

</server>

</openSSL>

如果是集群节点,每个节点配置时填写各自对应的证书文件路径。

注意:

如果本节点还需要作为 Client 执行 ClickHouse CLI 登录访问 ClickHouse Server 的话,如果要使用 SSL 方式访问(非SSL方式访问、无需修改配置),

则需要配置 /etc/clickhouse-client/config.xml 中的 <client></client> 配置,指定客户端证书文件路径。

如果无需使用 ClickHouse CLI SSL 访问数据库、则无需修改客户端的 <client></client> 配置。

clickhouse-client 客户端的配置文件可以通过 --config-file 来指定,如果不指定则使用默认配置文件 /etc/clickhouse-client/config.xml 。

vim /etc/clickhouse-client/config.xml

如果docker 未提供vi命令的话,也可以宿主机执行

vim /data/clickhouse/client-conf/config.xml

<openSSL>

<client> <!-- Used for connection to server's secure tcp port -->

<loadDefaultCAFile>false</loadDefaultCAFile>

<caConfig>/var/lib/clickhouse/certs/ca.crt</caConfig>

<certificateFile>/var/lib/clickhouse/certs/client1.crt</certificateFile>

<privateKeyFile>/var/lib/clickhouse/certs/client1.key</privateKeyFile>

<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>

10)继续修改 config.xml、在每个节点上配置用于 SSL 的 gRPC:

<grpc>

<enable_ssl>1</enable_ssl>

<!-- The following two files are used only if enable_ssl=1 -->

<ssl_cert_file>/var/lib/clickhouse/certs/chnode1.crt</ssl_cert_file>

<ssl_key_file>/var/lib/clickhouse/certs/chnode1.key</ssl_key_file>

<!-- Whether server will request client for a certificate -->

<ssl_require_client_auth>true</ssl_require_client_auth>

<!-- The following file is used only if ssl_require_client_auth=1 -->

<ssl_ca_cert_file>/var/lib/clickhouse/certs/ca.crt</ssl_ca_cert_file>

<!-- Default compression algorithm (applied if client doesn't specify another algorithm).

Supported algorithms: none, deflate, gzip, stream_gzip -->

<compression>deflate</compression>

<!-- Default compression level (applied if client doesn't specify another level).

Supported levels: none, low, medium, high -->

<compression_level>medium</compression_level>

<!-- Send/receive message size limits in bytes. -1 means unlimited -->

<max_send_message_size>-1</max_send_message_size>

<max_receive_message_size>-1</max_receive_message_size>

<!-- Enable if you want very detailed logs -->

<verbose_logs>false</verbose_logs>

</grpc>

11)修改 config.xml 、开启 ssl 相关端口:

开启 https 端口、取消注释:

<https_port>8443</https_port>

开启 ClickHouse Native 安全 TCP 端口、取消注释:

<tcp_port_secure>9440</tcp_port_secure>

开启 interserver https 端口、取消注释:

<interserver_https_port>9010</interserver_https_port>

12)重启服务

docker环境,直接重启容器:

docker stop clickhouse-server

docker start clickhouse-server

如果非容器环境,执行重启ClickHouse服务命令:service clickhouse-server restart

13)连接测试

a)使用 ClickHouse CLI 连接数据库

clickhouse-client 命令行连接工具使用介绍、可参考官方资料(Command-Line Client):

https://clickhouse.com/docs/en/interfaces/cli#clickhouse-client

非SSL连接:

clickhouse-client --host 127.0.0.1 --port 9000 --user root --password <PASSWORD>

SSL连接:

clickhouse-client --host 127.0.0.1 --port 9440 --user root --password <PASSWORD> --secure

clickhouse-client --host 127.0.0.1 --port 9440 --user root --password <PASSWORD> --secure --query "show tables"

注意:如果客户端配置文件中的<client></client>配置的CA证书有误(配置指定的不是签发所用的对应CA证书,例如:使用了默认证书或者其他CA证书),则会因为证书校验失败而连接失败,报错如下:

Code: 210. DB::NetException: SSL Exception: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED (127.0.0.1:9440)

注意:

> clickhouse-cli 工具 connect to ClickHouse with native TCP。因此,连接时需要指定 native TCP 端口(默认TCP非安全端口是 9000、默认TCP安全端口是9440)。

> 如果不指定数据库默认为default数据内裤、如果不指定用户名默认为default用户。

> --config-file : 可指定配置文件,如果不指定、则默认使用客户端配置文件 /etc/clickhouse-client/config.xml

> clickhouse-client 工具的主要参数(更多参数,参考官方介绍 https://clickhouse.com/docs/en/interfaces/cli#clickhouse-client):

--host, -h -- The server name, 'localhost' by default. You can use either the name or the IPv4 or IPv6 address.

--port -- The port to connect to. Default value: 9000. Note that the HTTP interface and the native interface use different ports.

--user, -u -- The username. Default value: default.

--password -- The password. Default value: empty string.

--ask-password - Prompt the user to enter a password.

--query, -q -- The query to process when using non-interactive mode. --query can be specified multiple times, e.g. --query "SELECT 1" --query "SELECT 2". Cannot be used simultaneously with --queries-file.

--database, -d -- Select the current default database. Default value: the current database from the server settings ('default' by default).

--config-file -- The name of the configuration file.

--secure -- If specified, will connect to server over secure connection (TLS). You might need to configure your CA certificates in the configuration file. The available configuration settings are the same as for server-side TLS configuration.

进入容器操作、ClickHouse容器内默认携带了 clickhouse-client 命令

docker exec -it clickhouse-server /bin/bash

i)ClickHouse CLI tcp 非安全端口(9000)连接

注意:ClickHouse CLI 通过TCP非安全端口连接时,对SSL配置无要求。

clickhouse-client --host 127.0.0.1 --port 9000 --user root --password 1q2w3e

clickhouse-client --host 127.0.0.1 --port 9000 --user root --password 1q2w3e --query "show tables"

root@39f30b0a4934:/# clickhouse-client --host 127.0.0.1 --port 9000 --user root --password 1q2w3e

ClickHouse client version 21.8.13.6 (official build).

Connecting to 127.0.0.1:9000 as user root.

Connected to ClickHouse server version 21.8.13 revision 54449.

clickhouse :) select version();

SELECT version()

Query id: f560fc43-b5f0-469f-b9ef-295416b76138

┌─version()─┐

│ 21.8.13.6 │

└───────────┘

1 rows in set. Elapsed: 0.003 sec.

clickhouse :)

ii)ClickHouse CLI tcp 安全端口(9440)连接

clickhouse-client --host 127.0.0.1 --port 9440 --user root --password 1q2w3e --secure

clickhouse-client --host 127.0.0.1 --port 9440 --user root --password 1q2w3e --secure --query "show tables"

客户端配置文件 /etc/clickhouse-client/config.xml 中配置了CA证书、客户端证书、客户端秘钥,SSL连接成功

root@6fa485afcbf4:/# clickhouse-client --host 127.0.0.1 --port 9440 --user root --password 1q2w3e --secure

ClickHouse client version 21.8.13.6 (official build).

Connecting to 127.0.0.1:9440 as user root.

Connected to ClickHouse server version 21.8.13 revision 54449.

clickhouse :) select version();

SELECT version()

Query id: de89fbbb-cd2e-482a-a1c0-88bdc565da27

┌─version()─┐

│ 21.8.13.6 │

└───────────┘

1 rows in set. Elapsed: 0.002 sec.

clickhouse :)

iii)ClickHouse CLI tcp 安全端口(9440)连接

clickhouse-client --host 127.0.0.1 --port 9440 --user root --password 1q2w3e --secure

clickhouse-client --host 127.0.0.1 --port 9440 --user root --password 1q2w3e --secure --query "show tables"

客户端配置文件 /etc/clickhouse-client/config.xml 中只配置CA证书,不配置(注释掉)客户端证书和客户端秘钥,SSL连接成功

iv)ClickHouse CLI tcp 安全端口(9440)连接

clickhouse-client --host 127.0.0.1 --port 9440 --user root --password 1q2w3e --secure

clickhouse-client --host 127.0.0.1 --port 9440 --user root --password 1q2w3e --secure --query "show tables"

客户端配置文件 /etc/clickhouse-client/config.xml 中不配配置CA证书、客户端证书和客户端秘钥(三个配置项全部注释掉),SSL连接失败:

Code: 210. DB::NetException: SSL Exception: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED (127.0.0.1:9440)

vi)ClickHouse CLI tcp 安全端口(9440)连接

clickhouse-client --host 127.0.0.1 --port 9440 --user root --password 1q2w3e --secure --config-file=/var/lib/clickhouse/config_invalid_crt.xml

客户端配置文件 --config-file=/var/lib/clickhouse/config_invalid_crt.xml 指定配置文件、配置文件中配置了CA(正确的)、客户端私钥 和 客户端证书。

只有CA是正确的,客户端私钥和客户端证书为非法(其他环境生成的客户端证书)。

满足预期、连接失败:Code: 210. DB::NetException: SSL Exception: error:10000418:SSL routines:OPENSSL_internal:TLSV1_ALERT_UNKNOWN_CA, while reading from socket (127.0.0.1:9440)

b)使用第三方客户端工具连接数据库

DBeaver 客户端连接数据库,测试普通连接(http)和SSL安全连接(https)

ClickHouse 官方有介绍 DBeaver 客户端 SSL 连接的配置:https://clickhouse.com/docs/en/integrations/dbeaver

JDBC 连接 8123 (http)端口,URL:

jdbc:clickhouse://192.168.100.250:8123/default

连接成功

JDBC 连接 8443 (https/SSL)安全端口,URL:

jdbc:clickhouse://192.168.100.250:8443/default?ssl=true&sslmode=none

ssl=true&sslmode=none、Client证书未配置:SSL连接成功。

JDBC 连接 8443 (https/SSL)安全端口,URL:

jdbc:clickhouse://192.168.100.250:8443/default?ssl=true&sslmode=strict

ssl=true&sslmode=strict、只配置CA证书,Client证书&秘钥未配置,用IP:SSL连接失败。报错:doesn't match any of the subject alternative names

JDBC 连接 8443 (https/SSL)安全端口,URL:

jdbc:clickhouse://chnode1.mytest01.com:8443/default?ssl=true&sslmode=strict

ssl=true&sslmode=strict(连接驱动属性中配置、URL中不指定?参数)、只配置CA证书(连接驱动属性中配置),Client证书&秘钥未配置,用域名:SSL连接成功。

注意:要修改/etc/hosts。

改成用域名访问:

修改 c:\Windows\System32\drivers\etc\

添加:

192.168.100.250 chnode1.mytest01.com

继续测试:尝试客户单指定CA证书、客户端证书和秘钥的方式连接:

把证书拷贝到本地电脑 && dbeaver 配置指定ssl证书文件。

注意:如果用DBeaver客户端以SSL方式访问数据库的话,由于步骤7)中生成的客户端私钥是RSA格式的,而 clickhouse-jdbc 需要的客户端私钥格式是 PKCS 8,因此需要将生成的 client1.key 转换成 PKCS 8 格式的私钥。

jdbc:clickhouse://chnode1.mytest01.com:8443/default?ssl=true&sslmode=strict

ssl=true&sslmode=strict(连接驱动属性中配置、URL中不指定?参数)、配置CA证书、Client证书和秘钥(连接驱动属性中配置),用域名:SSL连接失败,报错如下:

Code: 516, e.displayText() = DB::Exception: root: Authentication failed: password is incorrect or there is no user with such name (version 21.8.13.6 (official build))

网上有人说是DBeaver连接ClickHouse SSL需要的私钥格式是 PKCS8 格式,尝试生产 PKCS8 格式私钥文件:

RSA 私钥转 PKCS 8 格式的转换命令:

openssl pkcs8 -topk8 -inform PEM -in client1.key -outform PEM -nocrypt > client1.key.pkcs8

但连接还是报错。

原因不清楚。

c)Java 开发 Demo 进行JDBC连接测试:

String url = "jdbc:ch://chnode2.mytest01.com:8443/default";

Properties properties = new Properties();

properties.put("user", user);

properties.put("password", pwd);

properties.setProperty("ssl", "true");

properties.setProperty("sslmode", "strict"); // NONE to trust all servers; STRICT for trusted only

properties.setProperty("sslrootcert", "./ssl-cert-clickhouse/ca.crt"); //同时设置ca证书(ca.crt)、cert和JKS混用

properties.setProperty("key_store_type", "JKS");

properties.setProperty("trust_store", "./ssl-cert-clickhouse/client1.keystore"); //clickhouse/jdbc 实际当做 keystore 用

properties.setProperty("key_store_password", "1q2w3e");

Class.forName(this.driverClassName);

connection = DriverManager.getConnection(url, properties);

注意:ClickHouse JDBC SSL 参数和 传统数据库 例如 MySQL SSL 等提供的参数有比较大的差异。

1)官方介绍:https://clickhouse.com/docs/en/integrations/java/jdbc-driver

2)ClickHouse JDBC SSL 连接参数对于JKS类型的证书密钥库配置参数,提供了 trust_store、key_store_password,但没有提供 key_store 和 trust_store_password 参数。

3)ClickHouse JDBC SSL 连接参数 trust_store 实际是被 ClickHouse/JDBC 当做了 key_store 使用,因此需要传 key_store 配置文件路径、而不是 trust_store 文件路径。

4)ClickHouse JDBC SSL 连接参数 key_store_password 是 key_store 的文件密码。

5)ClickHouse JDBC SSL 连接参数,有两种设置方式:

方式1)Java系统Properties属性设置方式:

System.setProperty("javax.net.ssl.keyStore", keyStoreFile);

System.setProperty("javax.net.ssl.keyStorePassword", keyStorePwd);

System.setProperty("javax.net.ssl.trustStore", trustStoreFile);

System.setProperty("javax.net.ssl.trustStorePassword", trustStorePwd);

String url = "jdbc:ch://chnode1.mytest01.com:8443/default";

Properties properties = new Properties();

properties.put("user", user);

properties.put("password", pwd);

properties.setProperty("ssl", "true");

properties.setProperty("sslmode", "strict");

Class.forName("com.clickhouse.jdbc.ClickHouseDriver");

connection = DriverManager.getConnection(url, properties);

Statement st = connection.createStatement();

ResultSet rs = st.executeQuery("SELECT version()");

...

方式2)连接级Properteis参数设置方式:

String url = "jdbc:ch://chnode1.mytest01.com:8443/default";

Properties properties = new Properties();

properties.put("user", user);

properties.put("password", pwd);

properties.setProperty("ssl", "true");

properties.setProperty("sslmode", "strict"); // NONE to trust all servers; STRICT for trusted only

properties.setProperty("sslrootcert", "./ssl-cert-clickhouse/ca.crt"); //同时设置ca证书(ca.crt),JDBC连接参数没有提供JKS格式的truststore文件和truststore密码参数

properties.setProperty("key_store_type", "JKS");

properties.setProperty("trust_store", "./ssl-cert-clickhouse/client1.keystore"); //clickhouse jdbc 的 trust_store 参数实际要传 keystore

properties.setProperty("key_store_password", "1q2w3e"); //keystore密码

Class.forName("com.clickhouse.jdbc.ClickHouseDriver");

connection = DriverManager.getConnection(url, properties);

Statement st = connection.createStatement();

ResultSet rs = st.executeQuery("SELECT version()");

...

客户端的不同配置测试如下:

ssl=true&sslmode=none: 无需证书,连接成功

ssl=true&sslmode=strict:配置CA证书、不配客户端证书&私钥,连接成功;

ssl=true&sslmode=strict:配置CA证书、配置Client证书&私钥(crt&key),连接失败,Java应用需要用JKS证书秘钥文件;

ssl=true&sslmode=strict:配置CA证书、配置JKS格式的Client证书密钥库文件 keystore(trust_store=keystore文件路径,ClickHouse trust_store 参数对应的是 keystore 文件)、配置 keystore 密码(key_store_password参数),连接成功;

ssl=true&sslmode=strict:不配CA证书、不配客户端证书&私钥,连接失败。如果是CA签发证书的话,理论上不配CA证书应该能连成功。自签发证书必须配置CA证书。

4.附录

1)SSL证书的几种类型

单域名SSL证书

标准SSL证书,保护一个明确的域名,例如:www.mytest01.com

通配符SSL证书

Wildcard Certificates 也叫泛域名SSL证书。单个证书可以保护一个主域名(例如:mytest01.com)以及其所有的二级子域名(例如:www.mytest01.commail.mytest01.com 等),不限制子域名数量,但不能保护该主域名下的三级子域名(例如:shop.mail.mytest01.com)。通配符SSL证书可以保护通用域名和您在提交申请时指定的级别下的所有子域。只需在通用域名左侧的子域区域添加星号 (*) 即可。泛域名SSL证书只能保护同一级别的多个子域。

多域名SSL证书

SAN SSL证书。单个证书可以跨多个主域名、多个子域名提供安全保护。只要这些域名属于同一主体,就可申请一张多域名证书管理多个主域名和多个子域名网站。一般而言,多域名证书默认保护3个域名、超过默认域名数量,可支持付费增加。

多域名通配符SSL证书

SAN SSL证书。一张证书保护一个主域名和多个其二级子域名,对同级子域名数量无限制,新增子域名也无需额外付费。多域名证书集泛域名SSL和多域名SSL证书的优点于一身,一张SSL证书上可绑定多个通配符主域名,例如:*.mytest01.com; *.mytest02.cn; *.mytest03.com等。

2)单域名SSL证书生成

bash 复制代码
rm -rf ca.*  truststore  chnode*.*  client*.* 

#CA证书生成
openssl genrsa -out ca.key 2048
openssl req -x509 -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=ca" -nodes -key ca.key -days 3650 -out ca.crt
keytool -importcert -alias ca -file ca.crt -keystore truststore -storepass 1q2w3e  #生成 jks 格式的 truststore(如果需要)

#Server证书秘钥生成
openssl req -newkey rsa:2048 -nodes -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=chnode1.mytest01.com" -keyout chnode1.key -out chnode1.csr
openssl x509 -req -in chnode1.csr -out chnode1.crt -CA ca.crt -CAkey ca.key -days 3650 -CAcreateserial


#Client证书秘钥对生成
openssl req -newkey rsa:2048 -nodes -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=client1.mytest01.com" -keyout client1.key -out client1.csr
openssl x509 -req -in client1.csr -out client1.crt -CA ca.crt -CAkey ca.key -days 3650
openssl pkcs8 -topk8 -inform PEM -in client1.key -outform PEM -nocrypt -out client1.p8   #生成 PCKS#8  格式的 Client 证书(如果需要)
openssl pkcs12 -export -in client1.crt -inkey client1.key -name client1 -out client1.p12 #生成 PCKS#12 格式的 Client 证书(如果需要)
keytool -importkeystore -v -srckeystore client1.p12 -srcstoretype pkcs12 -srcstorepass 1q2w3e -destkeystore client1.keystore -deststoretype jks -deststorepass 1q2w3e #生成 jks 格式的 keystore(如果需要)


#查看证书、测试/校验证书
openssl x509 -in ca.crt -text             #查看CA证书详细信息
keytool -list -v -keystore truststore     #查看JKS格式的truststore证书详细信息

openssl x509 -in chnode1.crt -noout -text #查看Server证书详细信息(包括公钥)
openssl rsa -in chnode1.key -text         #查看Server私钥文件中的私钥信息
openssl verify -CAfile ca.crt chnode1.crt #测试/校验证书

openssl x509 -in client1.crt -noout -text #查看Client证书详细信息(包括公钥)
openssl rsa -in client1.key -text         #查看Client私钥文件中的私钥信息
openssl verify -CAfile ca.crt client1.crt #检查新生成的客户端证书是否已针对 CA 证书进行验证(通过)

keytool -list -v -keystore client1.keystore #查看JKS格式的keystore证书详细信息


#文件权限授权
chown -R clickhouse:clickhouse /var/lib/clickhouse/certs


#证书生成(或修改替换)以后,确认配置数据库使用正确后、需要重启数据库(docker环境则重启容器),生效配置:
docker stop clickhouse-server 
docker start clickhouse-server 
#SSL连接测试
docker exec -it clickhouse-server /bin/bash
clickhouse-client --user root --password 1q2w3e --port 9440 --secure --host 127.0.0.1 --query "select version()"
clickhouse-client --user root --password 1q2w3e --port 9440 --secure --host 127.0.0.1 --query "show tables"

#如果远程访问通过域名访问,别忘了配置本地DNS或者修改主机hosts
echo '192.168.100.250  chnode1.mytest01.com  chnode2.mytest01.com  chnode3.mytest02.com' >> /etc/hosts

3)通配符SSL证书(泛域名SSL证书)生成

bash 复制代码
rm -rf ca.*  truststore  chnode*.*  client*.* 

#CA证书生成
openssl genrsa -out ca.key 2048
openssl req -x509 -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=ca" -nodes -key ca.key -days 3650 -out ca.crt
keytool -importcert -alias ca -file ca.crt -keystore truststore -storepass 1q2w3e  #生成 jks 格式的 truststore(如果需要)


#Server证书秘钥生成
openssl req -newkey rsa:2048 -nodes -subj "/CN=*.mytest01.com" -keyout chnode1.key -out chnode1.csr
openssl x509 -req -in chnode1.csr -out chnode1.crt -CA ca.crt -CAkey ca.key -days 3650 -CAcreateserial


#Client证书秘钥对生成
openssl req -newkey rsa:2048 -nodes -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=*.mytest01.com" -keyout client1.key -out client1.csr
openssl x509 -req -in client1.csr -out client1.crt -CA ca.crt -CAkey ca.key -days 3650
openssl pkcs8 -topk8 -inform PEM -in client1.key -outform PEM -nocrypt -out client1.p8   #生成 PCKS#8  格式的 Client 证书(如果需要)
openssl pkcs12 -export -in client1.crt -inkey client1.key -name client1 -out client1.p12 #生成 PCKS#12 格式的 Client 证书(如果需要)
keytool -importkeystore -v -srckeystore client1.p12 -srcstoretype pkcs12 -srcstorepass 1q2w3e -destkeystore client1.keystore -deststoretype jks -deststorepass 1q2w3e #生成 jks 格式的 keystore(如果需要)


#查看证书、测试/校验证书
openssl x509 -in ca.crt -text             #查看CA证书详细信息
keytool -list -v -keystore truststore     #查看JKS格式的truststore证书详细信息

openssl x509 -in chnode1.crt -noout -text #查看Server证书详细信息(包括公钥)
openssl rsa -in chnode1.key -text         #查看Server私钥文件中的私钥信息
openssl verify -CAfile ca.crt chnode1.crt #测试/校验证书

openssl x509 -in client1.crt -noout -text #查看Client证书详细信息(包括公钥)
openssl rsa -in client1.key -text         #查看Client私钥文件中的私钥信息
openssl verify -CAfile ca.crt client1.crt #检查新生成的客户端证书是否已针对 CA 证书进行验证(通过)

keytool -list -v -keystore client1.keystore #查看JKS格式的keystore证书详细信息


#文件权限授权
chown -R clickhouse:clickhouse /var/lib/clickhouse/certs


#证书生成(或修改替换)以后,确认配置数据库使用正确后、需要重启数据库(docker环境则重启容器),生效配置:
docker stop clickhouse-server 
docker start clickhouse-server 
#SSL连接测试
docker exec -it clickhouse-server /bin/bash
clickhouse-client --user root --password 1q2w3e --port 9440 --secure --host 127.0.0.1 --query "select version()"
clickhouse-client --user root --password 1q2w3e --port 9440 --secure --host 127.0.0.1 --query "show tables"

#如果远程访问通过域名访问,别忘了配置本地DNS或者修改主机hosts
echo '192.168.100.250  chnode1.mytest01.com  chnode2.mytest01.com  chnode3.mytest02.com' >> /etc/hosts

4)多域名通配符SSL证书(配置了 SAN)生成

bash 复制代码
rm -rf ca.*  truststore  chnode*.*  client*.* 

#CA证书生成
openssl genrsa -out ca.key 2048
openssl req -x509 -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=ca" -nodes -key ca.key -days 3650 -out ca.crt
keytool -importcert -alias ca -file ca.crt -keystore truststore -storepass 1q2w3e  #生成 jks 格式的 truststore(如果需要)


#Server证书秘钥生成
openssl req -newkey rsa:2048 -nodes \
        -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=*.mytest01.com" \
        -reqexts SAN \
        -config <(cat /etc/pki/tls/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:localhost,DNS:*.mytest01.com,DNS:*.mytest02.com")) \
        -keyout chnode1.key  -out chnode1.csr

openssl x509 -req -in chnode1.csr -out chnode1.crt -CA ca.crt -CAkey ca.key -days 3650 -CAcreateserial -extensions SAN -extfile <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:localhost,DNS:*.mytest01.com,DNS:*.mytest02.com"))

#注意 openssl.cnf 位置可能因为系统不同而不同,Centos7: /etc/pki/tls/openssl.cnf 其他有的系统可能是: /etc/ssl/openssl.cnf


#Client证书秘钥对生成
openssl req -newkey rsa:2048 -nodes \
        -subj "/C=CN/ST=ZJ/L=HZ/O=mytest01/OU=RD/CN=*.mytest01.com" \
        -reqexts SAN \
        -config <(cat /etc/pki/tls/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:localhost,DNS:*.mytest01.com,DNS:*.mytest02.com")) \
        -keyout client1.key -out client1.csr

openssl x509 -req -in client1.csr -out client1.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 \
        -extensions SAN \
        -extfile <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:localhost,DNS:*.mytest01.com,DNS:*.mytest02.com"))

#注意 openssl.cnf 位置可能因为系统不同而不同,Centos7: /etc/pki/tls/openssl.cnf 其他有的系统可能是: /etc/ssl/openssl.cnf

openssl pkcs8 -topk8 -inform PEM -in client1.key -outform PEM -nocrypt -out client1.p8   #生成 PCKS#8  格式的 Client 证书(如果需要)
openssl pkcs12 -export -in client1.crt -inkey client1.key -name client1 -out client1.p12 #生成 PCKS#12 格式的 Client 证书(如果需要)
keytool -importkeystore -v -srckeystore client1.p12 -srcstoretype pkcs12 -srcstorepass 1q2w3e -destkeystore client1.keystore -deststoretype jks -deststorepass 1q2w3e #生成 jks 格式的 keystore(如果需要)


#查看证书、测试/校验证书
openssl x509 -in ca.crt -text             #查看CA证书详细信息
keytool -list -v -keystore truststore     #查看JKS格式的truststore证书详细信息

openssl x509 -in chnode1.crt -noout -text #查看Server证书详细信息(包括公钥)
openssl rsa -in chnode1.key -text         #查看Server私钥文件中的私钥信息
openssl verify -CAfile ca.crt chnode1.crt #测试/校验证书

openssl x509 -in client1.crt -noout -text #查看Client证书详细信息(包括公钥)
openssl rsa -in client1.key -text         #查看Client私钥文件中的私钥信息
openssl verify -CAfile ca.crt client1.crt #检查新生成的客户端证书是否已针对 CA 证书进行验证(通过)

keytool -list -v -keystore client1.keystore #查看JKS格式的keystore证书详细信息


#文件权限授权
chown -R clickhouse:clickhouse /var/lib/clickhouse/certs


#证书生成(或修改替换)以后,确认配置数据库使用正确后、需要重启数据库(docker环境则重启容器),生效配置:
docker stop clickhouse-server 
docker start clickhouse-server 
#SSL连接测试
docker exec -it clickhouse-server /bin/bash
clickhouse-client --user root --password 1q2w3e --port 9440 --secure --host 127.0.0.1 --query "select version()"
clickhouse-client --user root --password 1q2w3e --port 9440 --secure --host 127.0.0.1 --query "show tables"

#如果远程访问通过域名访问,别忘了配置本地DNS或者修改主机hosts
echo '192.168.100.250  chnode1.mytest01.com  chnode2.mytest01.com  chnode3.mytest02.com' >> /etc/hosts

5)Java 默认内置的根证书

bash 复制代码
#jdk8: %JAVA_HOME%/jire/lib/security
#jdk11:%JAVA_HOME%/lib/security/ 
#对应目录下Java会默认内置根证书密钥库文件 cacerts (JKS格式),默认密码为 changeit
#查看内置默认根证书的内容:keytool -list -v -keystore cacerts 
#如果想要把自己生成的自签发CA证书导入进去,命令如下:
cp cacerts cacerts.back  #修改前先备份一下
keytool -importcert -alias mytest02ClickHouseCA -file /opt/test/ssl-cert-clickhouse/ca.crt -keystore cacerts -storepass changeit  #导入
keytool  -list -v -alias mytest02ClickHouseCA -keystore cacerts  #查看导入结果
keytool  -delete -alias mytest02ClickHouseCA -keystore cacerts -storepass changeit #删除指定alias的证书
相关推荐
NineData26 分钟前
NineData云原生智能数据管理平台新功能发布|2025年5月版
数据库·云原生·oracle·devops·ninedata
不会编程的猫星人26 分钟前
Oracle杀进程注意事项
数据库·microsoft·oracle
GUIQU.30 分钟前
【Oracle】安装单实例
数据库·oracle
老胖闲聊35 分钟前
Python Django完整教程与代码示例
数据库·python·django
践行见远41 分钟前
django之请求处理过程分析
数据库·django·sqlite
行星0081 小时前
Postgresql常用函数操作
数据库·postgresql
程序员葵安1 小时前
【Java Web】9.Maven高级
java·数据库·后端·maven
斯普信云原生组1 小时前
K8S主机漏洞扫描时检测到kube-服务目标SSL证书已过期漏洞的一种永久性修复方法
https·kubernetes·ssl
海棠一号2 小时前
Android Settings 数据库生成、监听与默认值配置
android·数据库
新时代苦力工2 小时前
MVCC机制:Undo Log版本链与ReadView机制
数据库·mysql