无法让 HiRedis TLS example-ssl 连接

Unable to get HiRedis TLS example-ssl to connect

我正在尝试使用 HiRedis API 执行到 Redis 服务器的 TLS 连接,该服务器前面的设备可以执行 TLS 终止。我的项目需要通过 Internet 将客户数据发送到云中托管的 Redis 服务器。我需要使用 TLS 保护数据。

我看到 HiRedis 对 TLS 连接提供了一些有限的支持。我创建了一个原型来试用 TLS 代码。

  1. 我有一台位于 AWS eu-west-1 中的服务器机器。我已经通过各种方式确认我可以在端口 6379 上使用 HiRedis 0.14.0 插入记录。

  2. 我在 eu-west-1 中有一个 AWS 网络负载均衡器。我有一个带有私有证书的端口 443 到目标组到 Redis 服务器的端口 6379。我还打开了端口 6379,将端口 6379 连接到 Redis 服务器。我已经确认后一个连接使用 hiredis "example" 编译程序确实有效。

  3. 我在 us-east-1 有一个 AWS 云实例作为我的客户端机器。我已经安装了 hiredis 0.14.0 并使用 OpenSSL 库编译了示例。我有 installed/copied 私人证书和私钥到这台机器上。如上所述,我可以在端口6379上使用"example"程序,并在Redis服务器上创建示例数据。

但是,在尝试 TLS 连接时,我得到以下信息:

[machine]# example-ssl <to-redis-host> 443 <cert_file> <private_key_file>

ST(0x10). before/connect initialization. R(0x1)U
ST(0x1001). before/connect initialization. R(0x1)U
ST(0x1001). SSLv2/v3 write client hello A. R(0x1)U
ST(0x1001). SSLv3 read server hello A. R(0x1)U
ST(0x4008). error. R(0x230)F
ST(0x1002). error. R(0xffffffff)U
ST(0x1002). error. R(0xffffffff)U
Couldn't initialize SSL!
Error: SSL_connect() failed

example-ssl 文件可以在这里找到: https://github.com/redis/hiredis/blob/master/examples/example-ssl.c

我的HiRedis版本有sslio.c,但是在master分支里好像改名了ssl.c: https://github.com/redis/hiredis/blob/master/ssl.c

我如何获得这项工作?

在我打字的时候,我想到我应该使用客户端证书和私钥(不要使用服务器证书和密钥)。我尝试了 https://gist.github.com/mtigas/952344 中的说明来生成客户端证书和密钥,但我仍然无法让 example-ssl 工作。

所以问题是证书验证失败。

  1. 查看了hiRedis的master分支。找到文件"ssl.c"(我的0.14.0版本是sslio.c),找到如下代码:
    if (c->err == 0) {
        char err[512];
        if (rv == SSL_ERROR_SYSCALL)
            snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",strerror(errno));
        else {
            unsigned long e = ERR_peek_last_error();
            snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",
                    ERR_reason_error_string(e));
        }
        __redisSetError(c, REDIS_ERR_IO, err);
    }
    return REDIS_ERR;

我将代码合并到我的程序中,然后收到以下有用的错误消息:

ST(0x10). before/connect initialization. R(0x1)U
ST(0x1001). before/connect initialization. R(0x1)U
ST(0x1001). SSLv2/v3 write client hello A. R(0x1)U
ST(0x1001). SSLv3 read server hello A. R(0x1)U
ST(0x4008). error. R(0x230)F
ST(0x1002). error. R(0xffffffff)U
ST(0x1002). error. R(0xffffffff)U
Couldn't initialize SSL!
Error: SSL_connect() failed: certificate verify failed      <-------------
  1. 然后我按照下一页的说明验证我的自签名证书和安装: import self signed certificate in redhat。原来我在 hiRedis 客户端机器上安装的证书与我的 AWS NLB 上加载的证书不匹配。这是内部通信错误的结果。

  2. 更新ca-trust后,我修改了example-ssl.c文件如下:

    const char *cert = NULL;
    const char *key = NULL;
    const char *ca = NULL;
    ca = "/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt";

无论出于何种原因,"default" CA 信任不正确或未加载。我指定了找到自签名证书的 CA 路径。我更改了 sslio.c 代码以重新插入 VERIFY_PEER 功能。现在 example-ssl 可以正常工作了。

请注意:AWS 网络负载均衡器 (NLB) 不需要客户端证书验证。因此,我可以将 和 设置为空。但是,如果您使用 hiRedis(或任何其他 Redis API)连接到 Redis Enterprise Cloud 实验室,根据他们的文档,他们确实需要 client-AUTH。