目录
[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)多域名通配符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¶m2=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 的话,例如:
设置 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.com、mail.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的证书