數(shù)據(jù)庫入門:SSL/TLS 入門:
这次又将带来一些我在ScyllaDB担任Developer Advocate日常工作中获得的知识,这次我要教你们关于安全及加密连接的知识。这通常是新手感到焦虑的话题,但我来帮你们简化这个过程。
如果你刚刚开始接触数据库(不管是数据库的基础概念还是具体主题),可以先从我的第一篇文章《数据库101:初学者的数据一致性入门》读起,详见此处(https://dev.to/danielhe4rt/database-101-why-so-interesting-1344)。
这篇文章记录了在我之前仅接触过SQL和MySQL的情况下,我对更多数据库范式的探索。我将通过这一系列的Database 101进行记录和学习,更好地反映我的学习过程中的记录。
目录-
1. 序言
-
2. 什么是SSL和TLS?
-
3. 新手入门OpenSSL
-
4. 数据库认证
-
4.1 无认证
-
4.2 用户名/密码认证
-
4.3 创建用户和角色
-
4.4 证书/角色证书认证
-
4.4.1 更改认证方式
-
4.4.2 启用加密端口
-
4.4.3 启用客户端端口加密
-
5. 测试加密连接
- 6. 结论
在 NoSQL 数据库上工作确实很有挑战性,因为我必须学习一些作为普通 web 开发者根本碰不到或学不到的东西。我的意思是,通常你只是构建一个 CRUD 应用,尽量别把数据库索引搞砸了(对吧 ??????),再画几个按钮就行了。
但如果你一直关注我的数据库101之旅,你可能知道,我对数据库一无所知,只知道MySQL是什么以及如何用Laravel构建东西,然后我来到了Scylla。而现在我已经开始上手了。
- 使用 ScyllaDB 构建高度可扩展的应用程序
- 仍在学习 Rust - 1 年 6 个月 (感觉还是像个新手一样)。
- 开始学习 ShellScript、Go、Python、JavaScript 以及任何有 ScyllaDB 驱动的编程语言
- 学习了使用 Grafana/Prometheus 的基本可观察性知识
- 以及最近新接触的 传输层安全 (TLS)
如果你自己搭服务器,你可能已经使用了certbot来安装证书以顺利运行HTTPS,这就是我过去6~7年一直在使用的工具。说实话,知道怎么用工具就是我们这些_开发者_平时做的事情。
这甚至看起来像是一个征兆,但我正在开发一个使用 Rust 编写的浏览器扩展的后端,在那里我没能使用 certbot
,因此我不得不使用一些奇怪的命令来创建我的证书,并向我的项目添加了一个奇怪的 openssl
库:我的项目,并相信它会有效。
let mut certs_file = BufReader::new(File::open(cert_path).unwrap());
let mut key_file = BufReader::new(File::open(key_path).unwrap());
// 接下来,我们将加载 TLS 证书和密钥,生成一个自签名的临时证书用于测试:
// `openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj '/CN=localhost'`
let tls_certs = rustls_pemfile::certs(&mut certs_file)
.collect::<Result<Vec<_>, _>>()
.unwrap();
let tls_key = rustls_pemfile::pkcs8_private_keys(&mut key_file)
.next()
.unwrap()
.unwrap();
切换到全屏模式, 退出全屏
经过几个小时的调试后,我终于成功使用证书部署了API,但我并没有学到任何相关知识。几天后,我的老板要求我扩展 ScyllDB 安全页面,并了解基于证书的连接是如何工作的,我从未使用过它。
我花了10个小时才让它跑起来,但主要是因为我不太懂这个领域,这已经不再是问题了,现在我可以教你所有我目前学到的东西了!
2. SSL和TLS是什么呢?TLDR: 这部分可以直接跳过。
SSL(安全套接层)在1995年由Netscape公司推出,旨在为互联网通信提供隐私保护、身份验证和数据完整性,主要在浏览器中使用。其后续版本TLS(传输层安全),现在已成为互联网上电子邮件、消息传递和VoIP等应用的标准安全协议。
没有 SSL/TLS,客户端和服务器之间传输的数据是未加密的,并且容易被拦截和滥用,从而容易受到网络钓鱼和其他攻击的攻击。SSL/TLS 确保在数据传输前有一个安全的“握手”过程,这样在这个特定连接中所有的数据都会被加密。
然而,尽管 SSL/TLS 提供了加密,它并不能确保服务器本身完全可信或安全。由于其存在漏洞,SSL 自 1996 年起已被弃用,但因为其历史重要性,开发人员在提及 TLS 时,仍然常常使用 "SSL/TLS" 这个术语。
了解了SSL/TLS之后,来看看帮助我们管理安全连接的一些工具。
3. OpenSSL 初学者指南如今有很多数据加密工具可以使用,但今天我们要聊的是一个特别具体的工具:openssl-library.org。
这个库自1998年首次发布以来,常伴随于每个单独的数据加密教程,并被开源和闭源环境中的许多其他工具使用,例如Let's Encrypt和Certbot,我们这里也将使用这个库。
此工具的目的是生成密钥链和凭证,以授权他们做你想让他们做的任何事。
想象你在一家商业大楼里工作,每次进去都得向大楼的保安出示你的徽章。
- 您的公司会创建一个 “主密钥” 并为其生成证书。
- 您还为门卫生成一个 密钥和证书,并将这些证书连同所有员工的证书清单一并交给门卫。
- 门卫有一个 信任存储密钥链,上面挂满了各种标签。
- 当您到达入口时,他会检查您的标签是否与他的根证书匹配,从而决定是否让您通行。
看看这个加密的目的示意图
关于命令,我们是这样做的之类的:
# 创建根/主密钥和证书
# -----
openssl genpkey -algorithm RSA -out root_key.pem -pkeyopt rsa_keygen_bits:2048 # 生成根密钥
openssl req -x509 -new -key root_key.pem -days 3650 -out root_cert.pem -subj "/CN=管理员" # 生成根证书
# -----
# 创建员工密钥和证书
# -----
openssl genpkey -algorithm RSA -out employee_key.pem -pkeyopt rsa_keygen_bits:2048 # 生成员工密钥
openssl req -new -key employee_key.pem -out employee.csr -subj "/CN=员工" # 生成员工证书请求(CSR)
openssl x509 -req -in employee.csr -CA root_cert.pem -CAkey root_key.pem -CAcreateserial -out employee_cert.pem -days 365 # 使用根/主密钥和证书对CSR进行签名并生成员工证书
cat root_cert.pem employee_cert.pem > employee_truststore.pem # 创建信任库
# -----
# 创建安全(服务器)密钥和证书
# -----
openssl genpkey -algorithm RSA -out security_key.pem -pkeyopt rsa_keygen_bits:2048 # 生成服务器密钥
openssl req -new -key security_key.pem -out security.csr -subj "/CN=服务器" # 生成服务器证书请求(CSR)
openssl x509 -req -in security.csr -CA root_cert.pem -CAkey root_key.pem -CAcreateserial -out security_cert.pem -days 365 # 使用根/主密钥和证书对CSR进行签名并生成服务器证书
cat root_cert.pem security_cert.pem > security_truststore.pem # 创建信任库
# -----
# 创建恶意根密钥和客户端证书
# -----
openssl genpkey -algorithm RSA -out malicious_key.pem -pkeyopt rsa_keygen_bits:2048 # 生成恶意根密钥
openssl req -x509 -new -key malicious_key.pem -days 3650 -out malicious_cert.pem -subj "/CN=假管理员" # 生成恶意根证书
cat root_cert.pem malicious_cert.pem > malicious_truststore.pem # 合并为信任库文件
# -----
进入/退出全屏模式
命令太多,但大致就是这样的情况。
-
创建了
root_key.pem
和root_cert.pem
这两个文件。 -
这些密钥和证书被用来为员工签署新的密钥和证书:
-
security_key.pem
通过root_key.pem
签署。 -
employee_key.pem
通过root_key.pem
签署。 -
server_key.pem
通过root_key.pem
签署。 -
所有这些密钥都包含在
security_truststore.pem
文件中。 - 有人试图使用
root_cert.pem
创建一个 假密钥 叫做malicious_key.pem
。
现在我们来验证一下。理论上,只有这些在 security_truststore.pem
中的密钥才能被允许加入。
# 验证证书的有效性,使用信任存储
# -----
openssl verify -CAfile security_truststore.pem employee_cert.pem # 检查证书是否有效
# employee_cert.pem: OK
openssl verify -CAfile security_truststore.pem malicious_cert.pem # 检查证书是否有效
# CN = fake-admin
# 错误18,深度为0时的查找:自签名证书
# 恶意证书.pem: 验证失败
# -----
全屏模式 退出全屏
正如预料的那样,由于恶意密钥(malicious key)未被根用户签名,因此验证失败,此人被踢出。
现在我们知道了一些加密的基本概念。那么,加密在现实生活中究竟有哪些应用场景呢?让我告诉你我现在的工作内容,你就会更清楚了。这样你就明白了。
4. 数据库认证过程如果你在 Docker 中运行任何数据库(例如 MySQL、Postgres、Scylla 数据库、Redis 等等)。当你在容器化环境中启动这些实例时,通常不需要设置密码,除非你自己设置了。当我们谈论现代 web 中的认证时,我们有许多选择,谈到数据库时也是如此。
我们将在这个例子中使用ScyllaDB,不过这种流程在很多数据库中都非常常见。
在这一步,我们将了解:
- 无认证: 完全不需要任何凭证,直接启动实例就好,不用操心;
- 用户名/密码认证: 简单的用户名和密码就能防止别人访问你的数据;
- 证书/角色证书认证: 这就是大公司喜欢用的地方,你也应该了解这个道理。
在简短介绍了加密基础知识之后,我们可以开始讲具体内容了。
4.1 无需身份验证
在 Scylla 环境中,如果你正在本地或使用 Docker 的开发环境中运行节点或集群,默认情况下不设密码。此外,ScyllaDB 默认在 9042 端口上使用 CQL 协议,这一点可以在配置文件中轻松更改。
为什么我要告诉你这些端口的信息?因为这些信息后面会很有用,相信我好了。
你可以通过运行以下命令来启动并运行一个Docker容器:
# 使用 Docker 运行 ScyllaDB 节点
docker run --name some_scylla -p 9042:9042 -p 9142:9142 -d scylladb/scylla:6.1.2 \
--overprovisioned 1 --smp 1 # 这里的 --overprovisioned 1 表示过度配置,--smp 1 表示单处理器模式
# 检查节点的状态 -> 期望看到 UN (运行正常)
docker exec -it some_scylla nodetool status
# 数据中心: datacenter1
# =======================
# 状态=Up/Down
# |/ 状态=Normal/Leaving/Joining/Moving
# -- 地址 负载 令牌 份额 主机 ID 机架
# UN 10.10.5.2 509.46 KB 256 ? 9f597eb5-a77f-493f-9835-85dd1e571fcc rack1
# --
全屏显示。退出全屏
然后,你可以通过输入命令登录到 cqlsh (CQL Shell):
cqlsh
docker exec -it some_scylla cqlsh
# 已连接到 10.10.5.5:9042
# [cqlsh 6.0.18 | Scylla 6.0.1-0.20240612.bc89aac9d017 | CQL spec 3.3.1 | Native protocol v4]
# 需要帮助请使用 HELP
# cqlsh> select address, port, client_type, username from system.clients;
#
# address | port | client_type | username
# -----------+-------+-------------+-----------
# 10.10.5.5 | 50854 | cql | anonymous
# 10.10.5.5 | 50868 | cql | anonymous
# -----------+-------+-------------+-----------
全屏 / 退出
嗯,我们是以 匿名用户 的身份连接的!非常适合开发新东西和 本地测试一下。但你决定将相同的配置部署到生产环境……
当然,在一小时内,你就会被某个随机的数据库爬虫给收录了,lol
如果你想了解更多关于this ransomware的信息,可以点击链接查看。不管怎样,接下来我们在下一步中添加一些基本凭证,正确配置它。
真的,不要用默认配置将数据库直接暴露到互联网,也不要访问它时没有绑定一个特定的IP地址。
4.2:用户名/密码登录验证
运行这些其他数据库时,您可以通过更改多个配置文件来切换认证方式。在ScyllaDB,我们对自己简洁灵活的配置方式感到非常自豪。
如果你查看你的 docker 容器中的 /etc/scylla/scylla.yaml
(你可以通过点击这里 (文件: scylla.yaml#247)更详细地查看文件),你会发现配置标志位:
# 文件: /etc/scylla/scylla.yaml
# ...
# ...
# 用于识别用户的认证后端
# 出厂时,Scylla 提供 org.apache.cassandra.auth.{AllowAllAuthenticator, PasswordAuthenticator}。
#
# - AllowAllAuthenticator 不进行任何检查 - 设置它以禁用认证。
# - PasswordAuthenticator 依赖用户名/密码对来认证用户。它将用户名和哈希值存储在 system_auth.credentials 表中。
# 请增大 system_auth keyspace 的复制因子,如果使用此认证器。
# - Scylla 的 TransitionalAuthenticator 需要用户名/密码对来认证,与 PasswordAuthenticator 类似,但错误的凭据会导致自动登录为匿名用户。
# 用于升级集群认证。
# 注意: authenticator: AllowAllAuthenticator
# ...
切换到全屏模式 / 退出全屏模式
默认为 AllowAllAuthenticator
,它允许匿名连接并具有超级权限。接下来,我们将取消该行的注释,并将其改为 PasswordAuthenticator
:
# 文件: /etc/scylla/scylla.yaml
# ...
#-#authenticator: AllowAllAuthenticator # 大约在第247行
+#authenticator: PasswordAuthenticator
全屏模式 退出全屏
好的!现在需要告诉Scylla节点我们已经完成了更改。由于这是一个对我们系统环境来说“关键性”的变更,我们需要运行 drain
操作然后重启节点。下面是一步步的操作指南:
# 编辑前
docker exec -it some_scylla nodetool drain # 停止同步并准备关闭
docker exec -it some_scylla supervisorctl stop scylla # 停止 ScyllaDB
docker exec -it some_scylla cat /etc/scylla/scylla.yaml | grep authenticator: # 检查当前设置
# 编辑配置文件...
docker exec -it some_scylla sed -i 's/# authenticator:.*/authenticator: PasswordAuthenticator/' /etc/scylla/scylla.yaml
# 编辑完成
docker exec -it some_scylla cat /etc/scylla/scylla.yaml | grep authenticator: # 检查更新是否已应用
docker exec -it some_scylla supervisorctl start scylla # 启动 ScyllaDB
全屏模式,退出全屏
终于可以运行 cqlsh
了,但却收到了一个直接的“居然提示我要凭证,真是的”。
docker exec -it some_scylla cqlsh
连接错误信息:('无法连接到任何服务器', {'10.10.5.5:9042': 身份验证失败('远程端需要进行身份验证')})
点击进入全屏 点击退出全屏
默认,在 ScyllaDB 中,可以使用用户名/密码 "cassandra"(超级管理员)登录使用。
docker exec -it some_scylla cqlsh -u cassandra -p cassandra
# 连接到 10.10.5.5:9042 服务器
# [cqlsh 6.0.18 | Scylla 6.0.1-0.20240612.bc89aac9d017 | CQL spec 3.3.1 | Native protocol v4]
# 如有需要,输入 HELP 获取帮助。
# cassandra@cqlsh> select address, port, client_type, username from system.clients;
# 或者
# cassandra@cqlsh> 选择 地址, 端口, 客户端类型, 用户名 从 system.clients;
# 地址 | 端口 | 客户端类型 | 用户名
# -----------+-------+-------------+-----------
# 10.10.5.5 | 56998 | cql | cassandra
# 10.10.5.5 | 57014 | cql | cassandra
# -----------+-------+-------------+-----------
全屏模式 退出全屏
通过这些,我们已经知道了如何在 ScyllaDB 中配置身份验证的基础。如果你想知道为什么用户名/密码是 'cassandra',你可以阅读我的这篇系列文章的第一篇(https://dev.to/danielhe4rt/database-101-why-so-interesting-1344)。并且在部署之前务必更改默认凭据。
CQL协议默认运行在9042端口,这一点众所周知。同样地,让你的数据库在没有认证的情况下运行,它就会被黑掉。你也可以让默认凭证保持不变,你就会被黑掉。
目前,所有连接仍然是 未加密的
,但至少我们有了最基本的安全措施,别担心!我们很快就会搞定加密!在那之前,我们先在数据库里创建些用户和角色吧。
4.3 创建用户和角色
在创建此数据库的新用户之前,我们需要了解其工作原理。在 Scylla 中,我们每天使用 基于角色的身份验证
。每个用户都会被添加为角色到 system.roles
中。
这其实不是个问题,因为你可以为一个角色设置一个PASSWORD
。这看起来有点奇怪,对吧?我会告诉你怎么操作。看看这个:
scylladb@cqlsh> 描述 system.roles;
CREATE TABLE system.roles (
角色 text,
可以登录 boolean,
是否超级用户 boolean,
所属角色集 set<text>,
加盐哈希 text,
PRIMARY KEY (角色)
);
scylladb@cqlsh> 选择 * 从 system.roles;
角色 | 可以登录 | 是否超级用户 | 所属角色集 | 加盐哈希
-------------+-----------+--------------+---------------+--------------------
scylladb | True | True | 空 | $6$rAJ6FflUo8Chf...
employee | False | False | 空 | 空
danielhe4rt | True | False | {'employee'} | $6$AF4F6CflAA8Cw...
-------------+-----------+--------------+---------------+--------------------
全屏 退出全屏
以下是输出,为我们提供了一些关于认证过程的信息。
- 当
can_login
标志被设置为true
时,一个角色会成为一个authenticatable
; - 成为
authenticatable
后,该角色可以设定密码; - 一个角色可以属于另一个角色,从而继承它的所有权限。
这只是为了让您了解model和features是如何工作的示例环境。一定要阅读文档。
在DCL(数据控制语言)和DML(数据操控语言)的范畴内,我们将做一些基本的命令,如:
-- 创建我们的用户和角色
CREATE ROLE developer;
CREATE ROLE danielhe4rt WITH PASSWORD = 'some_cool_password' LOGIN = true;
-- 给用户分配角色
GRANT developer TO danielhe4rt;
全屏 开启 全屏 关闭
我们将在我们的 ScyllaDB Docker 实例上执行,按照文章开头创建的键。
# 创建一个名为 'employee' 的角色,如果该角色不存在的话
docker exec -it some-scylla cqlsh -u cassandra -p cassandra -e "CREATE ROLE IF NOT EXISTS 'employee' WITH LOGIN = true;";
# 创建一个名为 'server' 的角色,如果该角色不存在的话
docker exec -it some-scylla cqlsh -u cassandra -p cassandra -e "CREATE ROLE IF NOT EXISTS 'server' WITH LOGIN = true;";
切换到全屏模式 结束全屏模式
注意:您只能用已验证的账户创建角色或用户。
4.4 证书认证 / 角色证书认证
在本教程刚开始时,我们通过讲述一个有合法钥匙进入大楼的人的故事介绍了主题,现在我们要弄清楚这与普通的认证有什么区别。正如我之前提到的,如果没有TLS/SSL,您的数据在传输过程中是不加密的,这取决于您发送或接收的内容,如果内容敏感,那就不好。
使用证书意味着在发送数据之前,我们确保,如果有人截获了数据,如果没有解密密钥的人就无法读取数据,也就不会造成问题。
- 默认情况下,ScyllaDB 在端口 9042 上监听 CQL 协议;此端口的配置可以使用
native_transport_port
配置选项。 - Scylla 还支持支持通过 TLS/SSL 加密的 CQL 协议;此功能默认情况下是禁用的,可以通过设置
native_transport_port_ssl
配置选项来启用。
通常用于安全连接的端口是9142,但如果指定了client_encryption_options
而未指定native_transport_port_ssl
,那么native_transport_port
只会处理加密连接。同样的,如果native_transport_port
和native_transport_port_ssl
设置为相同的端口,也会发生同样的情况。
我知道,这看起来有点疯狂,有这么多选项,但我尽量简化一下。看看如下所示关于端口分配/加密的规则:
np := native_transport_port 已设置
nps := native_transport_port_ssl 已设置
ceo := client_encryption_options 已启用
eq := native_transport_port_ssl == native_transport_port
+-----+-----+-----+-----+
| np | nps | ceo | eq |
+-----+-----+-----+-----+
| 0 | 0 | 0 | * | => 在 native_transport_port 上监听未加密的数据
| 0 | 0 | 1 | * | => 在 native_transport_port 上监听加密的数据
| 0 | 1 | 0 | * | => 不监听
| 0 | 1 | 1 | * | => 在 native_transport_port_ssl 上监听加密的数据
| 1 | 0 | 0 | * | => 在 native_transport_port 上监听未加密的数据
| 1 | 0 | 1 | * | => 在 native_transport_port 上监听加密的数据
| 1 | 1 | 0 | * | => 在 native_transport_port 上监听未加密的数据
| 1 | 1 | 1 | 0 | => 在 native_transport_port 上监听未加密的数据,在 native_transport_port_ssl 上监听加密的数据
| 1 | 1 | 1 | 1 | => 在 native_transport_port(SSL同样)上监听加密的数据
+-----+-----+-----+-----+
// 更多信息请参见: https://github.com/scylladb/scylladb/blob/master/docs/dev/protocols.md#cql-client-protocol
全屏模式: 退出全屏
这表明如果我们想启用加密,需要在scylla.yaml
中更新一些设置,并从PasswordAuthenticator
切换到com.scylladb.auth.CertificateAuthenticator
。
在咱们调整之前,让我们先停掉并清空咱们的集群:
docker exec -it some_scylla nodetool drain # 停止通信并准备关闭(停止与其他节点的通信并准备关闭)
docker exec -it some_scylla supervisorctl stop scylla # 停止Scylla数据库
全屏模式,退出全屏
在上一步中,我们创建了一些启用了LOGIN的角色权限。然后我们在顶部的OpenSSL命令中添加了这些'角色',带有 CN=server/blabla ,对吧?现在是时候让这些设置变得有用,并不再使用凭据了。
私钥 + 证书可以包含更多的信息,比如原始字符串数据,这些数据可以在完成握手后使用。在这种情况下,我们已将用户/角色信息存入密钥,这些用户/角色将用于登录。通过对证书内容进行模式匹配,我们可以检查是否存在CN=某个特定值与我们的查询语句select * from system.roles where role = '某个特定值'
匹配。
我们先从进入我们的ScyllaDB实例开始操作
# 进入ScyllaDB实例环境
docker exec -it some_scylla shell
# root@c531i213hu:/#
# 安装你想要的文本编辑器
apt install nano
# 用nano打开scylla.yaml配置文件
nano -l /etc/scylla/scylla.yaml
全屏模式, 退出全屏
在你打开了配置文件后,让我们开始做一些必要的修改。
4.4.1 更改认证方式
我保证,这是我们最后一次打开这个文件。这里要的思路是将认证方式从 PasswordAuthenticator
更改为 com.scylladb.auth.CertificateAuthenticator
。我们还将设置一条规则,从每个证书中提取 CN=
标志,并用其内容进行认证。
# 文件: /etc/scylla/scylla.yaml
- authenticator: PasswordAuthenticator # 大约在第247行
+authenticator: com.scylladb.auth.CertificateAuthenticator
+auth_certificate_role_queries:
+ - source: SUBJECT # 根据主题
+ query: CN=([^,\s]+)
进入全屏 退出全屏
4.4.2 开启加密端口
我们甚至在设置了身份验证器之后还没有启用 TLS/SSL。还需要取消注释 native_transport_port_ssl
,这样端口 9142(用于传输加密数据)才能生效。所以,回到 scylla.yaml
文件,我们需要进行如下更改:
# 文件: /etc/scylla/scylla.yaml
# ...
-# native_transport_port_ssl: 9142 # <- 大约在第131行
+native_transport_port_ssl: 9142
进入全屏,退出全屏
4.4.3:启用客户端加密端口
一步一步来,我们一定能搞定!我们最后的改动是针对上表中定义的 client_encryption_options
(客户端加密选项)。我们需要取消所有内容的注释,并确保所有配置项都一致。以下是每个配置的简要介绍:
- enabled: 启用 TLS/SSL 加密。值设为 true (默认为 false)
- certificate:
绝对路径名
到你的服务器证书(security_cert.pem / server_cert.pem) - keyfile:
绝对路径名
到你的服务器密钥,该密钥需由根密钥签名(security_key.pem / server_key.pem) - truststore:
绝对路径名
到你的服务器信任存储,包含服务器和根证书。 - require_client_auth: 你的服务器必须要求客户端认证。
那么,咱们来搞定这些调整:
# 文件: /etc/scylla/scylla.yaml
# ...
# 启用或禁用客户端和服务器的加密。
-# client_encryption_options:
-# enabled: true
-# certificate: /etc/scylla/certs/cert.pem
-# keyfile: /etc/scylla/certs/key.pem
-# truststore: /etc/scylla/certs/truststore.pem
-# require_client_auth: true
+client_encryption_options:
+ enabled: true
+ certificate: /etc/scylla/certs/server_cert.pem
+ keyfile: /etc/scylla/certs/server_key.pem
+ truststore: /etc/scylla/certs/server_truststore.pem
+ require_client_auth: true
开启全屏 关闭全屏
行了!现在我们可以动手了。让我们启动一下我们的ScyllaDB集群,运行以下命令:
docker exec -it some_scylla supervisorctl start scylla # 注: 启动 ScyllaDB 服务
切换到全屏 退出全屏
我们来看看端口9142是否处于运行状态并监听TLS/SSL加密连接。
openssl s_client -connect localhost:9042
# 连接已建立(00000003)
# 40873B60D2750000:错误:0A00010B:SSL例程:ssl3_get_record:错误的版本号:../ssl/record/ssl3_record.c:354:
# 没有可用的对端证书
# 没有发送客户端证书的CA名称
openssl s_client -connect localhost:9142
# 连接已建立(00000003)
# 无法使用SSL_get_servername 函数
# 深度=0 CN=server
# 验证错误:num=20:无法找到本地证书颁发机构
# 验证返回:1
# 深度=0 CN=server
# 验证错误:num=21:无法验证证书
# 验证返回:1
# 深度=0 CN=server
# 验证返回:1
# ---
# 证书链
# 0 s:CN=server
# i:CN=administrator
# a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
# v:未开始生效: 2024年8月1日 20:09:38 GMT; 到期日期: 2025年8月1日 20:09:38 GMT
# ---
# 看来它需要证书了
全屏 退出全屏
在这个阶段,我们可以百分之百确定TLS已经开启,并且正在请求与我们之前生成的密钥相匹配的那些证书。
5. 测试加密连接:要配置的东西太多了,但我们该如何连接呢?为了避免使用CQLSH(因为它配置起来很麻烦,I LITERALLY PREFERRED TO MAKE IT WORK 在Node上也不愿意解释如何使用它),我们将使用NodeJS使操作简单。
首先,我们快速安装驱动器,可以通过运行命令来实现。
# 这里应该是具体的命令,但是原文本中没有提供命令,所以保持为空。
在命令行中输入以下命令:```npm install @lambda-group/scylladb```,运行此命令以安装 ScyllaDB 客户端库。ScyllaDB 是一个 NoSQL 数据库,此命令应在 Node.js 项目中运行。
全屏 退出全屏
之后,你可以创建一个指向你节点的演示脚本,别忘了在连接字符串里更改端口:
import { Cluster } from "@lambda-group/scylladb";
const cluster = new Cluster({
nodes: ["127.0.0.1:9142"],
ssl: {
enabled: true,
truststoreFilepath: "/your/path/to/certificates/developer_cert.pem",
privateKeyFilepath: "/your/path/to/certificates/developer_key.pem",
caFilepath: "/your/path/to/certificates/developer_truststore.pem",
verifyMode: VerifyMode.Peer,
}});
let result = await session.execute(
"SELECT address, port, username, driver_name, driver_version FROM system.clients"
);
console.log(result)
// [
// {
// address: '127.0.0.1',
// driver_name: 'scylla-js-driver',
// driver_version: '0.0.1',
// port: 58846,
// username: 'developer' // 这里我们是作为 'developer' 这个角色登录的
// }
// ]
进入全屏,退出全屏
只需发送我们的加密密钥和数字证书给服务器,我们就连接上了!
6. 结论部分这篇真的“文章/教程”我花了很长时间才写成,其中一个原因就是通过几次检查来确保内容无误。
我也制作了一个demo(gh: danielhe4rt/scylladb-role-tls-auth),你可以通过运行make
命令来完成所有这些步骤。所以如果你是通过某种方式来到这里的,请别忘了给它点个赞:D
安全是最近人们开始越来越重视的话题之一,学习这方面的知识非常令人兴奋。总之,请告诉我你感兴趣的话题!这个系列里你希望看到哪些话题!
注意安全,记得喝水哦!
共同學習,寫下你的評論
評論加載中...
作者其他優(yōu)質文章