解决 ClickHouse 中代码 210 的 SSL 证书验证失败错误
该错误通常显示为:
Code: 210. DB::NetException: SSL Exception: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
错误原因
尝试使用 clickhouse-client 连接到 ClickHouse 服务器时,会出现此错误。其原因通常是以下之一:
- 客户端配置文件
config.xml中缺少机器默认 CA 证书存储中的根证书,或 - 存在未配置的自签名证书或内部 CA 证书
解决方案
如果使用内部 CA 或自签名 CA,请在客户端目录 (例如 /etc/clickhouse-client) 中的 config.xml 中配置 CA 根证书,并禁用从默认位置加载默认根 CA 证书。
以下是示例配置:
<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>macOS 上的 Python 客户端
Python 客户端报告此错误的方式略有不同,通常显示为:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
在 macOS 上,来自 python.org 的 Python 构建会通过 OpenSSL 的默认路径而不是系统钥匙串来验证证书。对于全新安装,这些路径默认并不指向任何根证书包:安装程序虽然附带了 certifi,但在你运行随附的 Install Certificates.command 脚本之前,不会将其链接到 OpenSSL 的默认位置。在此之前,客户端无法验证 ClickHouse Cloud 的服务器证书,即使该证书本身是有效的。这个问题普遍存在于 python.org 提供的 macOS 版 Python 构建中 (Python 3.6 及更高版本) ,并不只影响 Python 3.11。
运行 Install Certificates.command,将 certifi 链接到 OpenSSL 的默认证书路径。请根据你的安装情况调整路径中的版本号:
open "/Applications/Python 3.11/Install Certificates.command"或者,直接将客户端配置为使用 certifi 证书包。ClickHouse Connect 不会自行回退到 certifi,因此请通过 ca_cert 参数传入该证书包:
import certifi
import clickhouse_connect
client = clickhouse_connect.get_client(
host='HOSTNAME.clickhouse.cloud',
port=8443,
username='default',
password='YOUR_SECRET_PASSWORD',
ca_cert=certifi.where(),
)