我花了很多时间研究如何解决这个问题,但还没找到合适的解决方案。
问题: 我正在使用OpenSSL库和linux。 我有一个服务器进程P1接受来自SSL客户端的SSL连接。 P1执行tcp_accept(),然后执行SSL_accept(),并使用SSL_read / SSL_write()与客户端交换一些协议数据。到目前为止,一切都很好。现在通过设计P1需要分叉子进程C1以从此时起为客户端提供服务。 C1使用execve调用重新映像自身并生成不同的二进制文件。 C1仍然需要通过P1中使用的相同SSL连接与SSL客户端通信。问题是,由于C1现在如何重新使用该客户端的现有SSL连接,因此它是一个完全不同的过程?我可以将底层TCP套接字描述符从P1传递到C1,因为它在内核中维护但我无法传递SSL上下文,因为它在Openssl库中维护。
我在stackoverflow上看到了这个问题,但遗憾的是没有提到解决方案。 OpenSSL: accept TLS connection and then transfer to another process
可能的解决方案: 我不确定是否有人已经解决了这类问题,但我试过了。
我想我可以创建一个新的SSL conctext并在新的子进程中进行SSL重新协商。所以在C1中我在相同的底层tcp套接字fd上创建了一个新的SSL上下文,并尝试进行SSL重新协商。这是我做的(省略SSL_ctx初始化部分)
ssl = SSL_new(ctx)// ctx初始化与P1服务器中的相同
SSL_set_fd(ssl,fd); // fd是从P1传递到C1的底层tcp套接字fd
SSL_set_accept_state(SSL);
SSL_set_verify(ssl,SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
SSL_renegotiate(SSL);
SSL_do_handshake(SSL);
SSL的>状态= SSL_ST_ACCEPT;
SSL_do_handshake(SSL);
但是重新协商没有成功,并从第一次SSL_do_handshake()调用返回一个Openssl Internal错误。我甚至不确定这是否真的可以做到。我能想到的另一个解决方案是:
有没有人遇到类似的问题并解决了? 我真的很感激任何有关这方面的帮助。
非常感谢
答案 0 :(得分:2)
在线搜索找到了这个讨论:
Passing TLS sessions between programs
获得SSL_SESSION后,将其转换为ASN1(通过i2d_SSL_SESSION)并将其转储到文件中。使用第二个程序读取该文件,并将其从ASN1转换回SSL_SESSION(通过d2i_SSL_SESSION),并将其添加到SSL_CTX的SSL_SESSION缓存中(通过SSL_CTX_add_session)。
我在doc / ssleay.txt中找到了:
[...]
PEM_write_SSL_SESSION(fp,x)和PEM_read_SSL_SESSION(fp,x,cb)将 以base64编码写入文件指针。 你可以做些什么,是在单独的之间传递会话信息 流程。
[...]
因此,您需要从P1序列化SSL会话数据并将其传递给C1以进行反序列化以及套接字描述符。然后,您可以在C1中创建新的SSL
和SSL_CTX
对象,并将它们与套接字和反序列化的会话数据相关联,以便C1可以接管对话。
答案 1 :(得分:1)
我搜索了" tls内核模式"并找到一个内核补丁,为TLS连接提供正常的fd。因此,fd可以作为普通套接字传递给其他进程。
该页面标题为" TLS in the kernel"在lwn.net上。在底部有一些有趣的讨论。希望它可以进入内核主线。或者希望有人可以提出一个生产质量的补丁集,以便人们可以真正使用它。
如果你知道一些真正的产品正在使用它,那么在这里分享它可能是一个好主意。
更新:This open source project "TLSe" as a replacement to openssh专门用于将上下文导出到另一个进程。