Невозможно получить HiRedis TLS example-ssl для подключения - PullRequest
0 голосов
/ 30 сентября 2019

Я пытаюсь использовать API HiRedis для выполнения соединения TLS с сервером Redis, подключенным к устройству, которое может выполнять завершение TLS. В моем проекте необходимо отправлять данные клиентов через Интернет на сервер Redis, размещенный в облаке. Мне нужно защитить данные с помощью TLS.

Я вижу, что HiRedis предлагает ограниченную поддержку для соединений TLS. Я создал прототип, чтобы опробовать код TLS.

  1. У меня есть сервер, расположенный в AWS eu-west-1. Я подтвердил различными способами, что я могу вставлять записи с помощью HiRedis 0.14.0 на порт 6379.

  2. У меня есть AWS Network Load Balancer в eu-west-1. У меня есть порт 443 с личным сертификатом, идущим в целевую группу к порту 6379 сервера Redis. У меня также открыт порт 6379, идущий к порту 6379 на сервер Redis. Я подтвердил, что последнее соединение работает, используя скомпилированную программу «Пример» hiredis.

  3. У меня есть экземпляр облака AWS в us-east-1 для работы в качестве моего клиентского компьютера. Я установил 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, но в основной ветке он переименован в ssl.c: https://github.com/redis/hiredis/blob/master/ssl.c

Как мне получить эту работу?

Когда я печатал, у меня возникла мысль, что я должен использовать клиентский сертификат и закрытый ключ (не используйте серверный сертификат и ключ). Я попробовал инструкции в https://gist.github.com/mtigas/952344 для генерации сертификата и ключа клиента, но я все еще не могу заставить работать пример-ssl.

1 Ответ

0 голосов
/ 03 октября 2019

Таким образом, проблема заключалась в том, что проверка сертификата не удалась.

  1. Посмотрел главную ветку hiRedis. Я нашел файл "ssl.c" (это sslio.c в моей версии 0.14.0) и нашел следующий код:
    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      <-------------

Затем я следовал инструкциям на следующей странице, чтобы проверить мой самоподписанный сертификат и установку: импортировать самоподписанный сертификат в redhat . Оказывается, сертификат, который я установил на своем клиентском компьютере hiRedis, не соответствовал сертификату, загруженному на моем AWS NLB. Это является результатом внутренних ошибок связи.

После обновления 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. Теперь пример-ssl работает правильно.

Просто примечание: AWS Network Load Balancer (NLB) не требует проверки сертификата клиента. Поэтому я мог бы установить и быть нулевым. Однако, если вы используете hiRedis (или любой другой API Redis в этом отношении) для подключения к лабораториям Redis Enterprise Cloud, они требуют client-AUTH в соответствии с их документацией.

...