在服务器上启用加密连接有点像编织魔法咒语:只有在您完全正确地念出咒语时,才能正常工作,但一旦您做到了,一切都将顺利进行,并且您已经建立了与服务器的安全连接。当您还使用密码术在连接时对客户端进行身份验证时,配置加密可能会变得更加玄妙。
启用与服务器的安全连接应该是每个开发人员的必备技能,因此,在本篇文章中,我们将引导您完成一个简单的三步过程,以打开、测试和配置 Redis 企业云与使用 SSL 的 Python 客户端之间的加密连接。
如果您想在家中尝试,您需要获取以下工具 - 我们将等待您安装它们
您的 Redis 企业云订阅必须启用 SSL 功能才能使用 SSL。如果您的帐户尚未启用 SSL,您需要联系 Redis 支持团队为您的订阅启用 SSL。您将在帐户仪表板的主菜单中找到联系支持团队的链接。
的文档 设置 SSL可以在 Redis 企业云操作和管理指南中找到,但在这篇文章中,我们将引导您完成使用 SSL 与 Python 客户端所需的所有步骤。第一步和第二步恰好适用于任何语言,我们将在以后关于 Java 的文章中再次提到它们。
SSL 或 安全套接字层,是一种用于保护客户端和服务器之间连接的标准协议。SSL 使用加密来确保在客户端和服务器之间传输的任何数据保持私密。SSL 还使用 公钥密码术来对客户端和服务器进行身份验证。密码身份验证是可选的,但几乎总是需要服务器。TLS(传输层安全)是 SSL 协议的后续版本,它们的功能相同。
缩写词“SSL”非正式地用于指代 SSL 或 TLS 安全连接。Redis 企业云的文档和管理界面遵循该约定。在这篇文章中,我们将遵循文档约定,使用“SSL”来指代 SSL 和 TLS。
截至 2018 年 6 月,Redis 企业云使用 TLS 版本 1.2 来保护数据库和服务器之间的连接。
当然,在 Redis 企业云中使用 SSL 的第一步是为我们的数据库启用 SSL。首先登录到您的 Redis 企业云帐户,并创建一个新的数据库供您进行试验。在您完成数据库创建过程时,您将进入 创建数据库页面。当您到达 创建数据库页面(您也可以从 编辑数据库页面打开 SSL),找到 访问控制和安全组,并启用 SSL 客户端身份验证。
客户端身份验证(有时缩写为 Client-AUTH)是 SSL 规范的可选部分,它要求客户端除了服务器之外,还需要通过公钥密码术进行身份验证。尽管它是 TLS 协议的可选部分,但 Redis 企业云要求 Client-AUTH 才能使用 SSL。启用 SSL 客户端身份验证后,您的客户端软件将需要使用密码和公钥进行身份验证。在 SSL 中,公钥信息通过数字证书进行交换。
作为启用 SSL 客户端身份验证的一部分,我们可以让 Redis 企业云为我们的客户端生成证书。按 生成客户端证书 按钮,系统将为您的客户端生成证书。按下该按钮还会导致您的浏览器下载一个包含凭据的 zip 文件 (redis_credentials.zip),并在“客户端证书”字段中填充客户端证书的 PEM 版本。
您可以将为您的客户端创建的证书视为一个数字 ID,它可以用来证明自己的身份。该证书由颁发证书的组织进行数字签名,以确保它没有被修改。
redis_credentials.zip 文件包含与客户端和服务器相互身份验证所需的所有文件副本。该存档包括为您的客户端生成的证书 (redis_user.crt)、相应的私钥 (redis_user_private.key) 以及 Redis 证书颁发机构的证书副本 (redis_ca.pem)。需要特别注意 redis_credentials.zip 文件和 redis_user_private.key,以确保密钥的安全。所有这三个文件都需要分发到连接到此特定 Redis 数据库实例的每个客户端,因此您需要将它们集成到您用于管理已部署软件的凭据的系统中。
为新软件设置 SSL 连接通常是一段令人沮丧的经历;只有在所有组件到位时,才能正常工作,但之后一切都会正常工作。SSL 问题很难调试,这并没有什么帮助。毕竟,该协议的设计是为了防止您知道哪些数据正在通过网络传输!因此,在使用 SSL 与我们的客户端代码之前,我们将测试是否可以使用 OpenSSL s_client 命令与数据库建立安全连接。
使用您在步骤一中下载的 redis_credentials.zip 中的凭据,在您放置解压缩文件的目录中运行以下命令
openssl s_client -host [endpoint name] -port [endpoint port number] -cert redislabs_user.crt -key redislabs_user_private.key -CAfile redislabs_ca.pem -crlf
从您在步骤 1 中使用的数据库中获取主机参数的端点名称和端口参数的端点端口。使用此命令,OpenSSL 将尝试与您的 Redis 实例建立安全的 TLS 连接,并打印服务器提供的证书。运行该命令将产生关于 TLS 连接各个方面的一长串输出,最后会显示一条类似于以下内容的消息
Verify return code: 0 (ok)
如果您看到任何其他返回码或消息,则表示连接无法安全建立。
如果您无法建立安全连接,请确保您在数据库实例上正确启用了 TLS 客户端身份验证,并且您已为要连接的实例下载了相应的凭据文件。一旦您可以成功使用 OpenSSL 连接到数据库, 然后为您的客户端启用 SSL。相信我 - 不要跳过这一步!
最后一步是修改您的客户端代码以建立 SSL 连接。我们将使用 Python 构建一个示例客户端,以与我们的 Redis 企业云实例建立安全连接。我们的示例客户端将连接到数据库并运行 Redis INFO 命令。以下是我们客户端的代码:
#!/usr/local/bin/python3
import redis
import pprint
try:
r = redis.StrictRedis(
decode_responses=True,
host='redis-16148.c15.us-east-1-2.ec2.cloud.redislabs.com',
port=16148,
password='sekret',
ssl=True,
ssl_keyfile='./redislabs_user_private.key',
ssl_certfile='./redislabs_user.crt',
ssl_cert_reqs='required',
ssl_ca_certs='./redislabs_ca.pem',
)
info = r.info()
pprint.pprint(info)
except Exception as err:
print("Error connecting to Redis: {}".format(err))
我们的客户端代码与不使用 SSL 的版本几乎相同,我们只需要在 StrictRedis 构造函数中添加五个额外的参数:ssl、ssl_keyfile、ssl_certfile、ssl_cert_reqs 和 ssl_ca_certs。第一个参数 ssl 只需在连接上启用 SSL。其余参数用于提供与客户端和服务器相互身份验证所需的凭据。请务必注意,您仍然必须为实例提供密码,您可以在“编辑数据库”屏幕上找到该密码。
的 redis-py 客户端使用 Python 3 ssl 包为与 Redis 的标准套接字连接提供 SSL 包装器。在幕后,以“ssl”为前缀的参数是关键字参数,它们映射到 ssl.wrap_socket 方法的参数。您可以在 ssl 包文档中找到这些参数的详细文档。
客户端需要进行身份验证的凭据(证书和私钥,我们在第一部分下载了)是使用 `ssl_keyfile` 和 `ssl_certfile` 参数提供给 SSL 库的。Python SSL 库直接使用 Redis Enterprise Cloud 生成的 PEM 文件格式。
`ssl_cert_reqs` 参数转化为 SSLContext.verify_mode 的值,并控制服务器必须如何进行身份验证。此参数可以取三个不同的值之一:`none`、`optional` 或 `required`。您应该始终将 `ssl_cert_reqs` 设置为 `required`,在使用 Redis Enterprise Cloud 时。SSL 库默认使用与操作系统捆绑在一起的证书(包括所有主要证书颁发机构)来验证服务器。由于 Redis 维护自己的证书颁发机构,因此您需要向 SSL 库提供 Redis 证书颁发机构的证书(`redis_ca.pem`),以便 SSL 库可以验证服务器身份。
一旦 `StrictRedis` 构造函数被修改为设置 SSL 并加载验证客户端和服务器所需的所有凭据,您就可以运行代码并查看它如何连接到数据库。作为实验,尝试删除 `ssl_keyfile` 和 `ssl_certfile` 参数,看看脚本如何无法进行身份验证。之后,添加回 `ssl_keyfile` 和 `ssl_certfile` 参数,并删除 `ssl_ca_cert` 参数,看看客户端这次如何响应。
配置 redis-py 以使用 SSL 并不特别困难,但第一次使用时可能会让人感到头疼。SSL 旨在确保您的通信安全,因此您可能会不断收到错误(看似没有进展),直到一切设置正确为止。
希望这篇文章能为您提供关于设置与 Redis Enterprise Cloud 的安全连接所需组件的简要介绍,并帮助您将 SSL 添加到您的项目中。在后续文章中,我们将介绍如何设置 Redis Enterprise Cloud 和 Java 客户端之间的安全连接。
最后提醒您:许多组织对安全和管理此类凭据有特定的政策,因此请务必与您的运营或安全团队合作,以确保您遵守所有适用的政策。