OpenSSL:接受TLS连接,然后转移到另一个进程

时间:2012-09-14 14:09:13

标签: c++ linux sockets openssl posix

我们有一个(Linux)服务器运行两个进程,A和B.目前,客户端建立与进程A的连接,进程A然后将生成的套接字的文件描述符传递给进程B,允许进程B使用现有的fd / socket与客户无缝沟通。然后,客户端和进程B执行TLS握手并继续讨论生成的TLS连接。

(我在这里省略了很多细节,但是, 是让进程A充当中介而不是直接连接到进程B的充分理由)

现在,由于 <long complicated story involving new client applications and websockets> ,我们可能不得不在进程A中执行TLS握手,然后将已建立的TLS连接传输到进程B.

这可能吗?可以复制底层套接字的文件描述符(我们已经这样做了),至少在理论上,内部TLS状态数据也可以被复制并用于重建进程B中的TLS连接,从而有效地接管连接。

但OpenSSL是否会公开这样的设施? 我发现函数d2i_SSL_SESSION似乎对OpenSSL会话对象做了类似的事情,但对于OpenSSL来说还不太新,我不确定这是否足够。会议,背景,BIO和其他一些复杂的术语涉及到。需要多少序列化并转移到流程B才能使其正常工作?如何在实践中完成?

切换需要对客户端100%透明:它必须简单地对给定的IP /端口执行SSL握手,然后继续讨论生成的套接字,而不知道一个进程接受了连接并执行TLS握手,然后另一个处理所有后续通信。

5 个答案:

答案 0 :(得分:2)

确实可以跨进程共享SSL上下文。但是,SSL会话上下文需要驻留在两个进程都可访问的共享内存位置(由于特定原因未知),我们希望在进程A中完成实际的握手并执行数据I / O在过程B中。

第一步是注册回拨     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指针

要(de)序列化SSL_SESSION&#39; C&#39; struct使用可用的API d2i_SSL_SESSION(...)和i2d_SSL_SESSION(...)

使用此方法的工作项目是https://github.com/varnish/hitch/blob/master/src/shctx.c

的示例代码

答案 1 :(得分:1)

我没有在练习上尝试这个,但据我记得在套接字级别创建连接后,它由openssl初始化,然后使用SSL_read和SSL_write进行读/写。它们接受socket fd作为参数。连接本身(来自SSL端)用SSL_CTX SSL结构表示。

所以在理论上听起来有可能,但正如我所说,我从来没有在现实世界中尝试过它。

答案 2 :(得分:1)

最新的内核补丁可以通过为TLS连接提供正常的fd来实现。请参阅“TLS in the kernel By Jake Edge December 2, 2015”页面。我也发布了另一个SO question

答案 3 :(得分:0)

我认为这是不可能的,因为初始握手的一部分是密钥交换,并且正在进行的通信需要密钥。进程B需要知道远程端和进程A使用的密钥。

答案 4 :(得分:0)

听起来更麻烦,值得...考虑其他设计,例如例如,使用loopback接口代表B通过A代理连接。