ScyllaDB 客户端与节点间 TLS/SSL 加密配置指南(Data in Transit: Client to Node)
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
导读
本文讲解如何在 ScyllaDB 集群中启用客户端到节点(Client to Node)的传输加密:一旦启用,客户端与节点之间的所有通信都将通过 TLS/SSL 进行传输,防止 CQL 流量在网络上被窃听或篡改。文中将完整覆盖节点端client_encryption_options配置、GnuTLS Priority String 对 TLS 版本与密码套件的控制、cqlsh 客户端 SSL 配置、cassandra-stress 压测客户端的 Java keystore/truststore 生成,以及热加载机制与源码级实现原理。读完本文,你可以在一套多节点集群上安全地滚动开启 CQL 加密,并让 cqlsh 与 cassandra-stress 客户端正常接入加密端口。
依据仓库文档 docs/operating-scylla/security/client-node-encryption.rst 整理。ScyllaDB 底层使用的 OpenSSL 库支持 FIPS 140-2 标准。
总体工作流程
客户端到节点的加密需要逐节点启用:每个 ScyllaDB 节点都必须单独开启 TLS/SSL 加密,因此需要为集群中的每一个节点重复执行下述流程。
1. 配置节点(Configure the Node) 2. 验证客户端(Validate the Clients)整体分两大部分:先在服务端(每个节点)完成 TLS 监听配置并重启,再在客户端(cqlsh、cassandra-stress、应用程序)侧完成证书与密钥库配置并验证连通性。
第一步:配置节点(每个节点逐一执行)
本步骤需要在每一个ScyllaDB 节点上执行,并且一次只处理一个节点(one by one),以便在不中断整个集群的前提下完成滚动升级。
注意:如果你正在搭建一个全新的集群(尚未写入任何业务数据),可以跳过下面的步骤 1 和步骤 2。
1. 排空节点并停止 ScyllaDB
nodetool drainnodetool drain会停止该节点接受新的写入,并将内存中的 memtable 数据落盘(flush),确保在停止服务期间不丢失数据。随后停止 ScyllaDB:
常规安装(受支持的操作系统):
sudo systemctl stop scylla-serverDocker 容器部署(仅停止容器内的 scylla 进程,不停止
some-scylla容器本身):docker exec -it some-scylla supervisorctl stop scylla
(以上停止命令对应仓库中的 docs/rst_include/scylla-commands-stop-index.rst。)
2. 编辑/etc/scylla/scylla.yaml中的client_encryption_options
在节点上编辑scylla.yaml,启用并配置客户端加密。可用的配置项如下:
| 配置项 | 说明 | 默认值 |
|---|---|---|
enabled | 是否启用客户端加密 | false |
certificate | PEM 格式的证书,可以是自签名证书,也可以是由证书颁发机构(CA)签发的证书 | — |
keyfile | 与证书对应的 PEM 格式私钥 | — |
truststore | 可选。PEM 格式的可信 CA 证书存储路径;若不提供,ScyllaDB 将尝试使用系统信任库来认证证书 | 未设置(使用系统信任库) |
certficate_revocation_list | 可选。PEM 编码的证书吊销列表(CRL)路径,用于在证书到期前吊销已签发的证书 | 未设置 |
require_client_auth | 是否要求客户端提供证书:true(强制要求客户端证书)、false(不要求)、optional(请求但不强制,客户端可用证书或回退到密码/SigV4 等认证方式) | false |
priority_string | GnuTLS Priority String,控制允许使用的 TLS 算法、协议版本与安全强度 | 未设置(使用默认) |
enable_session_tickets | 是否启用 TLS 1.3 session ticket 会话恢复 | true |
提示:如果使用自签名证书,则必须设置
truststore参数,指向一个包含该私有 CA 的 PEM 格式容器(即将 CA 证书本身放入 truststore)。
配置示例(完整继承自原文档并补充注释):
client_encryption_options: enabled: true certificate: /etc/scylla/db.crt # 节点证书(PEM) keyfile: /etc/scylla/db.key # 与证书配对的私钥(PEM) truststore: <path to a PEM-encoded trust store> # 可选,自签名时必须指向包含私有 CA 的 PEM 容器 certficate_revocation_list: <path to a PEM-encoded CRL file> # 可选,CRL 文件路径 require_client_auth: ... # true / false / optional priority_string: SECURE128:-VERS-TLS1.0:-VERS-TLS1.1仓库中的默认模板位于 conf/scylla.yaml,其完整默认形态为:
# enable or disable client/server encryption. # client_encryption_options: # enabled: false # certificate: conf/scylla.crt # keyfile: conf/scylla.key # truststore: <not set, use system trust> # certficate_revocation_list: <not set> # require_client_auth: False # priority_string: <not set, use default> # enable_session_tickets: <default true>关于 SSL 专用端口的说明
client_encryption_options启用后,加密默认作用于标准的 CQL 端口native_transport_port(默认 9042)。如果你希望在保留明文 9042 端口的同时,额外提供一个加密端口供客户端使用,可以设置native_transport_port_ssl(示例值 9142)以及分片感知对应的native_shard_aware_transport_port_ssl(示例值 19142)。相关说明见 conf/scylla.yaml:
# Enabling client encryption and keeping native_transport_port_ssl disabled will use encryption # for native_transport_port. Setting native_transport_port_ssl to a different value # from native_transport_port will use encryption for native_transport_port_ssl while # keeping native_transport_port unencrypted. #native_transport_port_ssl: 9142源码视角:配置是如何生效的
在 db/config.cc 的configure_tls_creds_builder()中可以看到这些配置项的实际消费逻辑:
- 默认设置
dh_params::level::MEDIUM的 DH 参数级别,并使用db::config::default_tls_priority作为默认 Priority String; - 若提供
priority_string,则以它覆盖默认值; require_client_auth会被归一化为小写后解析:true对应tls::client_auth::REQUIRE(强制校验客户端证书),optional对应tls::client_auth::REQUEST(TLS 握手时请求但不强制客户端证书,客户端未提供证书时可回退到密码认证,如 CQL 的 CertificateOrPasswordAuthenticator、Alternator 的 SigV4 认证);enable_session_tickets默认true,对应TLS13_SESSION_TICKET会话恢复模式;certificate与keyfile默认指向conf/scylla.crt与conf/scylla.key,随后通过set_x509_key_file加载 PEM 证书与私钥;- 只有显式提供
truststore时才会调用set_x509_trust_file加载自定义信任库; - 只有显式提供
certficate_revocation_list时才会调用set_x509_crl_file加载 CRL。
而在 transport/controller.cc 中,CQL server 启动时会读取cfg.client_encryption_options(),若enabled为真,则创建seastar::tls::credentials_builder并打印日志"Enabling encrypted CQL connections between client and server",随后根据native_transport_port_ssl是否独立设置来决定是在标准端口上启用加密,还是额外监听加密端口。
3. 启动 ScyllaDB
常规安装(受支持的操作系统):
sudo systemctl start scylla-serverDocker 容器部署(容器
some-scylla已处于运行状态):docker exec -it some-scylla supervisorctl start scylla
(启动命令对应仓库中的 docs/rst_include/scylla-commands-start-index.rst。)
4. 验证节点已启用加密
使用日志验证节点是否已开启加密连接:
journalctl _COMM=scylla在日志中应能看到如下消息:
storage_service - Enabling encrypted CQL connections between client and node说明:源码中实际打印的日志文本为
Enabling encrypted CQL connections between client and server(见 transport/controller.cc),不同版本文案略有差异,含义一致:客户端到节点的 CQL 加密连接已启用。
Priority String:控制 TLS 版本与密码强度
Priority String是 GnuTLS 的优先级字符串,用于控制允许使用的 TLS 协议版本、密码套件强度以及更多算法选项。完整语法与选项参见 GnuTLS 官方 Priority Strings 手册。
典型用法示例:
禁用 TLS 1.1 及更低版本,且要求最低 128 位安全性:
SECURE128:-VERS-TLS1.0:-VERS-TLS1.1其中
SECURE128表示只使用达到 128 位安全强度的算法;-VERS-TLS1.0:-VERS-TLS1.1表示从允许列表中移除 TLS 1.0 与 TLS 1.1,从而只保留 TLS 1.2 及以上。启用 128 位与 192 位安全密码套件,且仅允许 TLS 1.2 与 TLS 1.3:
SECURE128:+SECURE192:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3其中
+SECURE192在SECURE128基础上额外启用 192 位强度的算法;-VERS-ALL先禁用全部 TLS 版本,再通过+VERS-TLS1.2:+VERS-TLS1.3显式只开启 TLS 1.2 与 TLS 1.3。
在配置文件中应用:
client_encryption_options: enabled: true certificate: /etc/scylla/db.crt keyfile: /etc/scylla/db.key priority_string: SECURE128:+SECURE192:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3从源码看,priority_string会直接传给seastar::tls::credentials_builder::set_priority_string()(见 db/config.cc),由 Seastar/GnuTLS 在建立 TLS 会话时强制执行。
第二步:验证客户端
服务端启用加密后,还需要让客户端以 SSL 方式连接。本部分涵盖 cqlsh 与 cassandra-stress 两类客户端的配置。
前置条件:生成 cqlshrc 文件
为了让 cqlsh 在客户端到节点加密(SSL)模式下正常工作,需要先生成cqlshrc配置文件。完整步骤参见 docs/operating-scylla/security/gen-cqlsh-file.rst,要点如下:
安装与 Java 版本匹配的 Java Cryptography Extensions(JCE),解压到 JRE 安装目录的
lib/security子目录,例如/usr/lib/jvm/java-8-oracle/jre/lib/security/。在
~/.cassandra/cqlshrc创建 cqlsh 配置文件:[authentication] username = myusername password = mypassword [cql] version = 3.3.1 [connection] hostname = 127.0.0.1 port = 9042 factory = cqlshlib.ssl.ssl_transport_factory [ssl] certfile = path/to/rootca.crt validate = true userkey = client_key.key usercert = client_cert.crt_signed[ssl]段针对CA 签名证书场景;如果使用自签名证书,
[ssl]段应改为:[ssl] certfile = /etc/scylla/db.crt validate = true userkey = /etc/scylla/db.key usercert = /etc/scylla/db.crt若
validate = true,证书名称必须与机器的主机名匹配;若服务端配置了客户端认证(
require_client_auth = true),还需要填写userkey与usercert。
修改
username、password、version(不确定时用nodetool version查询)、certfile、userkey、usercert等参数后保存。使用
cqlsh --ssl连接节点验证配置是否正确。运行 cassandra-stress 生成所需文件并连接 SSL 集群,例如:
cassandra-stress write -node 127.0.0.1 -transport truststore=/path/to/cluster/truststore.jks truststore-password=mytruststorepassword -mode native cql3 user=username password=mypasswordcassandra-stress 会生成后续配置客户端到节点加密所需的若干文件。
验证步骤
完成 cqlshrc 生成后,按以下步骤验证并配置客户端:
复制证书文件到客户端。生成 cqlshrc 文件后,会产生以下文件:
db.keydb.crtcadb.keycadb.pem
将这些文件复制到所有运行 cassandra-stress 的客户端机器上。
为 cassandra-stress 生成 Java keystore 与 truststore。每个运行 cassandra-stress 的客户端都需要一个 Java keystore(
.jks文件),该文件可由cadb.pem生成,并且必须存在于每一个运行 cassandra-stress 的客户端上。a) 为节点证书生成 Java keystore:
openssl pkcs12 -export -out keystore.p12 -inkey /home/scylla/server_files/db.key -in /home/scylla/server_files/db.crt -password <password> keytool -importkeystore -destkeystore keystore.jks -srcstoretype PKCS12 -srckeystore keystore.p12注意:
openssl pkcs12 -export必须使用至少 1 个字符的密码,以避免 keytool 导入时出现空密码(null)问题。b) 为信任提供方生成 Java truststore:
openssl pkcs12 -export -out truststore.p12 -inkey /home/scylla/server_files/cadb.key -in /home/scylla/server_files/cadb.pem -password <password> keytool -importkeystore -destkeystore truststore.jks -srcstoretype PKCS12 -srckeystore truststore.p12c) 安装 Java 安全提供程序(JCE):下载与 Java 版本匹配的 Java Cryptography Extensions,安装到
<jre>/lib/security目录。请确保使用的是该位置提供的最新版本。运行 cassandra-stress(带 SSL 参数):
cassandra-stress write n=1000000 cl=ONE -node 10.240.0.48 -transport keystore=keystore.jks keystore-password=[password] truststore=truststore.jks truststore-password=[password] -mode native cql3 -pop -rate threads=50n=1000000:写入 100 万条记录;cl=ONE:一致性级别为 ONE;-node 10.240.0.48:目标节点地址(替换为你的实际节点 IP);-transport keystore=... truststore=...:指定 Java keystore/truststore 及其密码;-mode native cql3:使用 CQL 原生协议 v3;-rate threads=50:50 个并发线程。
注意:当集群中仍有部分节点尚未切换为 SSL 加密模式时,cassandra-stress 可能会遇到连接异常,但它会继续运行,并只连接那些可以建立加密连接的节点。
在客户端应用程序上启用加密。
一旦
internode_encryption或client_encryption_options被启用(设置为非 none 的值),scylla.yaml中指定的 SSL/TLS 证书与密钥文件会被持续监控:当这些文件在磁盘上被修改时,ScyllaDB 会自动重新加载它们,并用于后续新建的连接,无需重启节点。该机制说明见 docs/operating-scylla/security/_common/ssl-hot-reload.rst。这意味着证书轮换(renewal)可以在不停机的情况下完成——修改磁盘上的证书文件后,后续新建立的加密连接将自动使用新证书。
相关主题
- Encryption Data in Transit Node to Node(节点间传输加密)
- Generating a self-signed Certificate Chain Using openssl(使用 openssl 生成自签名证书链)
- Authorization(授权)
- Generate a cqlshrc File(生成 cqlshrc 文件)
附录:自签名证书链生成速览
若你尚未具备 CA 签发的证书,可参考 docs/operating-scylla/security/generate-certificate.rst 在本地生成一套自签名证书链(含 CA 与节点证书)。核心命令如下:
# 1. 生成 CA 私钥与自签名 CA 证书 openssl genrsa -out cadb.key 4096 openssl req -x509 -new -nodes -key cadb.key -days 3650 -config db.cfg -out cadb.pem # 2. 生成节点私钥与签名请求 openssl genrsa -out db.key 4096 openssl req -new -key db.key -out db.csr -config db.cfg # 3. 用 CA 签发节点证书 openssl x509 -req -in db.csr -CA cadb.pem -CAkey cadb.key -CAcreateserial -out db.crt -days 365 -sha256生成完毕后你会得到:
db.key— 节点使用的 PEM 私钥;db.crt— 由cadb.pem签发的节点证书;cadb.pem— 可作 truststore 的 CA 签名身份,也可用于签发连接节点的客户端证书。
将文件放置到合适目录并设置好 ScyllaDB 实例可读的权限后,更新服务端/客户端配置引用它们即可。重启 ScyllaDB 后,若客户端到节点加密生效,日志中会出现Enabling encrypted CQL connections between client and server之类的消息(对应 generate-certificate.rst 中描述的验证方式,实际日志文本与版本相关)。
总结
客户端到节点的 TLS/SSL 加密是 ScyllaDB 纵深防御体系中“传输中数据加密(Encryption in Transit)”的重要一环。本文给出的完整操作路径可以归纳为:
- 服务端:逐节点执行
nodetool drain→ 停止服务 → 在/etc/scylla/scylla.yaml中配置client_encryption_options(证书、私钥、truststore、CRL、require_client_auth、priority_string)→ 启动服务 → 通过journalctl _COMM=scylla验证加密已启用; - 客户端:生成并配置
cqlshrc使 cqlsh 支持 SSL;为 cassandra-stress 生成 Java keystore/truststore(基于cadb.pem)并以-transport参数运行压测;在应用程序侧启用 SSL 连接; - 证书轮换:利用 ScyllaDB 对证书文件的自动监控与热加载能力,在不停机的情况下更新证书。
通过 Priority String 可以精细控制 TLS 协议版本与密码强度(例如仅允许 TLS 1.2/1.3 并禁用弱算法),配合源码中configure_tls_creds_builder()的解析逻辑,你可以精确预判配置的最终效果,从而在安全性与兼容性之间取得平衡。
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考