У нас есть сервер (Linux), на котором выполняются два процесса, A и B. В настоящее время клиенты устанавливают соединение с процессом A, который затем передает дескриптор файла полученного сокета в процесс B, позволяя процессу B использовать существующий fd / socket для беспрепятственной связи. с клиентом. Затем клиент и процесс B выполняют квитирование TLS и продолжают разговор по полученному соединению TLS.
(Я опускаю много деталей здесь, но да, там является веские причины для того, чтобы процесс А выступал в качестве посредника, а не просто подключался к процессу Б напрямую)
Теперь из-за <long complicated story involving new client applications and websockets>
похоже, что нам, возможно, придется выполнить квитирование TLS в процессе A, а затем перенести установленное соединение TLS в процесс B.
Это возможно? Файловый дескриптор нижележащего сокета может быть скопирован (мы уже это делаем), и, по крайней мере, теоретически, внутренние данные состояния TLS также могут быть скопированы и использованы для восстановления соединения TLS в процессе B, эффективно захватывая соединение.
Но предоставляет ли OpenSSL какое-либо средство подобного рода?
Я нашел функцию d2i_SSL_SESSION
который, кажется, делает нечто подобное для объекта сеанса OpenSSL, но, будучи совершенно новым для OpenSSL, я не уверен, достаточно ли этого. Есть сессии, контекст, BIO и куча других сложных терминов. Сколько нужно было бы сериализовать и перенести в процесс B, чтобы это работало? И как это будет сделано на практике?
Переключение должно быть на 100% прозрачным для клиента: он должен просто выполнить SSL-квитирование с указанным IP / портом, а затем продолжить разговор по полученному сокету, не зная, что один процесс принимает соединение и выполняет рукопожатие TLS, а другой затем обрабатывает все последующие сообщения.
Я не пробовал это на практике, но, насколько я помню, после создания соединения на уровне сокета оно инициализируется openssl, а затем вы читаете / пишете с помощью SSL_read и SSL_write. Они принимают сокет fd в качестве параметра. Само соединение (со стороны SSL) представлено структурами SSL_CTX SSL.
Так что в теории это звучит возможно, но, как я уже сказал, я никогда не пробовал это в реальном мире.
Совместное использование контекста SSL между процессами действительно возможно. Однако тогда контекст SSL-сеанса должен находиться в общей памяти, доступной обоим процессам (поскольку по конкретным причинам неизвестны), мы хотим, чтобы фактическое рукопожатие было выполнено в процессе А, и выполнялся ввод / вывод данных. в процессе Б.
Первый шаг — зарегистрировать обратные вызовы для
SSL_CTX_sess_set_new_cb (ctx, shared_ctx_new_cb);
SSL_CTX_sess_set_get_cb (ctx, shared_ctx_get_cb);
SSL_CTX_sess_set_remove_cb (ctx, shared_ctx_remove_cb);
Убедитесь, что соответствующий SSL-сеанс-контекст всегда создается в разделяемой памяти (или, по крайней мере, возвращает сериализованные и готовые к использованию адресуемые указатели на SSL_SESSION
Чтобы (де) сериализовать структуру C ‘SSL_SESSION, используйте доступные API d2i_SSL_SESSION (…) и i2d_SSL_SESSION (…)
Рабочий проект, использующий этот подход, пример кода на https://github.com/varnish/hitch/blob/master/src/shctx.c
Я не думаю, что это возможно, так как часть первоначального рукопожатия — это обмен ключами, а ключи необходимы для постоянного общения. Процесс B должен знать ключ, используемый удаленным концом и процессом A.
Звучит так, как будто много проблем, которые стоит … рассмотреть другие проекты, например, прокси-соединение через A от имени B, используя, например, петлевой интерфейс.
Недавнее исправление ядра может сделать это возможным, предоставив нормальный fd для соединения TLS. Смотрите страницу «TLS в ядре Джейк Эдж
2 декабря 2015 г.«Я тоже кросс-пост отправил другому ТАК вопрос.