Windows环境下使用自签名SSL证书连接ScyllaDB(Cassandra)节点失败排查及SSLContext替代ssl_options的实现方法
Windows环境下使用自签名SSL证书连接ScyllaDB(Cassandra)节点失败排查及SSLContext替代ssl_options的实现方法
你遇到的问题很典型,核心是Windows与Linux系统对SSL证书的处理逻辑存在差异,再加上旧版ssl_options参数的兼容性问题导致的。下面分两部分帮你解决:
一、Windows下SSL连接失败的排查与修复
从你的描述来看,去掉SSL配置能正常连接,说明网络层面是通的,问题集中在SSL握手环节。可以尝试以下几个方向:
1. 指定明确的SSL协议版本
你代码里设置ssl_version=None,这会让系统自动选择默认协议,但Windows和Ubuntu的默认SSL协议版本可能不一致,导致和ScyllaDB节点不兼容。建议手动指定兼容的TLS版本:
import ssl ssl_options = dict( ca_certs='db.crt', cert_reqs=False, ssl_version=ssl.PROTOCOL_TLS_CLIENT, # 明确指定TLS客户端协议 keyfile=None, certfile=None )
2. 检查证书文件格式与编码
Windows系统对文件编码比较敏感,确保你的db.crt是纯PEM格式且无BOM编码:
- 用记事本打开
db.crt,选择“另存为”,编码选“UTF-8”(不要选“UTF-8带BOM”),覆盖原文件 - 确认证书内容开头是
-----BEGIN CERTIFICATE-----,结尾是-----END CERTIFICATE-----,没有多余字符
3. 临时导入证书到Windows信任库(测试用)
自签名证书在Windows下可能会被系统安全策略拦截,即使设置了cert_reqs=False。你可以把db.crt导入到Windows的“受信任的根证书颁发机构”:
- 按下Win+R,输入
certmgr.msc打开证书管理器 - 展开“受信任的根证书颁发机构”→“证书”,右键选择“所有任务”→“导入”
- 按照向导导入你的
db.crt文件,完成后再测试连接
4. 排查Windows防火墙/安全软件限制
虽然无SSL能连接,但部分防火墙或安全软件可能对SSL加密流量有额外过滤规则。可以临时关闭Windows防火墙或第三方安全软件,测试是否能正常连接,排查是否是拦截导致的超时。
二、用SSLContext替代ssl_options的实现(解决弃用警告)
官方已经明确标记ssl_options为弃用,未来版本会移除,建议尽快迁移到ssl_context的方式。下面是完整的替代实现代码:
from cassandra.cluster import Cluster import ssl # 创建SSL上下文,指定服务器认证用途并加载CA证书 ssl_context = ssl.create_default_context( purpose=ssl.Purpose.SERVER_AUTH, cafile='db.crt' ) # 针对自签名证书的特殊配置(按需调整) ssl_context.check_hostname = False # 如果证书的CN与连接的IP/主机名不匹配,关闭主机名检查 ssl_context.verify_mode = ssl.CERT_NONE # 关闭证书验证(测试环境用,生产环境不建议) # 初始化Cluster并传入ssl_context cluster = Cluster( ['<my_ip>'], port=9142, ssl_context=ssl_context ) try: session = cluster.connect() print("SSL连接成功!") # 可以执行测试查询验证 rows = session.execute("SELECT release_version FROM system.local") print(f"ScyllaDB版本: {rows.one()[0]}") except Exception as e: print(f"连接失败: {e}") finally: cluster.shutdown()
代码说明:
ssl.create_default_context会自动选择安全的默认协议版本和加密套件,比手动设置ssl_version更可靠- 如果是生产环境,建议:
- 确保证书的CN字段与连接的主机名一致,开启
ssl_context.check_hostname = True - 将
ssl_context.verify_mode设为ssl.CERT_REQUIRED,强制验证证书有效性,避免中间人攻击
- 确保证书的CN字段与连接的主机名一致,开启
- 如果需要使用客户端证书(双向SSL认证),可以用
ssl_context.load_cert_chain(certfile='client.crt', keyfile='client.key')加载客户端证书和私钥
额外提示
- 确认ScyllaDB节点的
scylla.yaml配置中,client_encryption_options已正确开启,且证书/私钥路径与你使用的db.crt一致 - 尽量使用最新版本的Cassandra Python Driver,新版本对SSLContext的支持更完善,兼容性更好
备注:内容来源于stack exchange,提问作者winwin
相关产品推荐
相关产品推荐

