6

我们有一个(Linux)服务器运行两个进程,A 和 B。目前,客户端与进程 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 握手,然后另一个处理所有后续通信。

4

5 回答 5

2

跨进程共享 SSL 上下文确实是可能的。但是,SSL-session-context 需要驻留在两个进程都可以访问的共享内存位置中(因为未知的具体原因)我们希望在进程 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 的可寻址指针

要(反)序列化 SSL_SESSION 'C' 结构,请使用可用的 API d2i_SSL_SESSION(...) 和 i2d_SSL_SESSION(...)

使用这种方法的工作项目示例代码位于https://github.com/varnish/hitch/blob/master/src/shctx.c

于 2016-06-21T10:33:13.950 回答
1

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

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

于 2012-09-14T14:25:49.510 回答
1

最近的内核补丁可能通过为 TLS 连接提供正常的 fd 来实现。请参阅页面“内核中的 TLS,作者:Jake Edge,2015 年 12 月 2 日”。我还交叉发布到另一个SO question

于 2016-06-18T18:08:08.860 回答
0

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

于 2012-09-14T16:26:54.617 回答
0

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

于 2012-09-14T14:23:06.290 回答