无法获取HiRedis TLS example-ssl进行连接

时间:2019-09-30 19:46:56

标签: c redis hiredis

我正在尝试使用HiRedis API与到可以执行TLS终止的设备所面向的Redis服务器执行TLS连接。我的项目需要通过互联网将客户数据发送到托管在Cloud中的Redis服务器。我需要使用TLS保护数据。

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

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

  2. 我在eu-west-1中拥有一个AWS Network Load Balancer。我有端口443,带有专用证书,该证书将目标组转到Redis服务器的端口6379。我还打开了端口6379,将端口6379连接到Redis服务器。我已经确认,使用hiredis“示例”编译程序可以实现后一种连接。

  3. 我在us-east-1中有一个AWS云实例,可以用作我的客户端计算机。我已经安装了hiredis 0.14.0,并使用OpenSSL库编译了示例。我已经在这台机器上安装/复制了私有证书和私有密钥。如上所述,我可以在端口6379上使用“示例”程序,并在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 个答案:

答案 0 :(得分:0)

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

  1. 查看了hiRedis的主分支。我找到文件“ 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. 然后我按照下一页上的说明来验证我的自签名证书和安装: interesting article。原来,我在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";

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

请注意:AWS Network Load Balancer(NLB)不需要客户端证书验证。因此,我可以将和设置为null。但是,如果您使用hiRedis(或其他任何Redis API)连接到Redis Enterprise Cloud实验室,则它们确实需要其文档中的client-AUTH。