![](/img/trans.png)
[英]How to do TLS handshake in one process and handle the rest of connection in another process?
[英]How to accept SSL connection in one process and reuse the same SSL context in another process
我花了很多时间研究如何解决这个问题,但还没找到合适的解决方案。
问题:我使用的是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:接受TLS连接,然后转移到另一个进程
可能的解决方案:我不确定是否有人已经解决了这类问题,但我尝试了以下。
我想我可以创建一个新的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内部错误。 我甚至不确定这是否真的可以做到。 我能想到的其他解决方案如下。
有没有人遇到类似问题并解决了? 我真的很感激任何有关这方面的帮助。
非常感谢
在线搜索找到了这个讨论:
获得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可以接管对话。
我搜索了“tls内核模式”并找到了一个内核补丁,为TLS连接提供了正常的fd。 因此,fd可以作为普通套接字传递给其他进程。
该页面在lwn.net上标题为“ 内核中的TLS ”。 在底部有一些有趣的讨论。 希望它可以进入内核主线。 或者希望有人可以提出一个生产质量的补丁集,以便人们可以真正使用它。
如果你知道一些真正的产品正在使用它,那么在这里分享它可能是一个好主意。
更新: 这个开源项目“TLSe”作为openssh的替代品专门用于将上下文导出到另一个进程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.