简体   繁体   English

如何在一个进程中接受SSL连接,并在另一个进程中重用相同的SSL上下文

[英]How to accept SSL connection in one process and reuse the same SSL context in another process

I have spent quite some time doing my research on how to tackle this problem but could not find a working solution yet. 我花了很多时间研究如何解决这个问题,但还没找到合适的解决方案。

Problem: I am using OpenSSL library and linux. 问题:我使用的是OpenSSL库和linux。 I have a server process P1 accepting SSL connection from SSL client. 我有一个服务器进程P1接受来自SSL客户端的SSL连接。 P1 does tcp_accept() and then SSL_accept() and exchanges some protocol data with client with SSL_read/SSL_write(). P1执行tcp_accept(),然后执行SSL_accept(),并使用SSL_read / SSL_write()与客户端交换一些协议数据。 Everything is fine till this point. 到目前为止,一切都很好。 Now by design P1 needs to fork a child process C1 to serve the client from this point onwards. 现在通过设计P1需要分叉子进程C1以从此时起为客户端提供服务。 C1 uses execve call to re-image itself and spawn a different binary. C1使用execve调用重新映像自身并生成不同的二进制文件。 C1 still needs to talk to the SSL client over the same SSL connection that was used in P1. C1仍然需要通过P1中使用的相同SSL连接与SSL客户端通信。 The problem is since C1 is a completely different process now how it can re-use the existing SSL connection for that client? 问题是,由于C1现在如何重新使用该客户端的现有SSL连接,因此它是一个完全不同的过程? I am able to pass the underlying TCP socket descriptor from P1 to C1 as it is maintained in kernel but I can not pass the SSL context since it's maintained in the Openssl Library. 我可以将底层的TCP套接字描述符从P1传递给C1,因为它在内核中维护但我无法传递SSL上下文,因为它是在Openssl库中维护的。

I saw this tread on stackoverflow but unfortunately no solution is mentioned. 我在stackoverflow上看到了这一点,但遗憾的是没有提到解决方案。 OpenSSL: accept TLS connection and then transfer to another process OpenSSL:接受TLS连接,然后转移到另一个进程

Possible Solution: I am not sure if anybody has already solved this kind of problem but I tried following. 可能的解决方案:我不确定是否有人已经解决了这类问题,但我尝试了以下。

  1. I thought I can just create a new SSL conctext and do SSL renegotiation in the new child process. 我想我可以创建一个新的SSL conctext并在新的子进程中进行SSL重新协商。 So in C1 I created a new SSL context over the same underlying tcp socket fd and tried to do SSL renegotiation. 所以在C1中我在相同的底层tcp套接字fd上创建了一个新的SSL上下文,并尝试进行SSL重新协商。 Here is what I did (Omiting the SSL_ctx initialization part) 这是我做的(省略SSL_ctx初始化部分)

    ssl = SSL_new(ctx) // ctx is initialized the same as it was done in P1 server ssl = SSL_new(ctx)// ctx的初始化与P1服务器中的初始化相同
    SSL_set_fd(ssl, fd); SSL_set_fd(ssl,fd); // fd is the underlying tcp socket fd passed from P1 to C1 // fd是从P1传递给C1的底层tcp套接字fd
    SSL_set_accept_state(ssl); SSL_set_accept_state(SSL);
    SSL_set_verify(ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0); SSL_set_verify(ssl,SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
    SSL_renegotiate(ssl); SSL_renegotiate(SSL);
    SSL_do_handshake(ssl); SSL_do_handshake(SSL);
    ssl->state=SSL_ST_ACCEPT; SSL->状态= SSL_ST_ACCEPT;
    SSL_do_handshake(ssl); SSL_do_handshake(SSL);

But the renegotiation does not succeed and returns me an Openssl Internal error from first SSL_do_handshake() call. 但重新协商没有成功,并从第一次SSL_do_handshake()调用返回一个Openssl内部错误。 I am not even sure if this can really be done. 我甚至不确定这是否真的可以做到。 The other solution that I can think of is following. 我能想到的其他解决方案如下。

  1. Somehow transfer the whole SSL context for that client from P1 to C1. 以某种方式将该客户端的整个SSL上下文从P1转移到C1。 How efficiently this can be done? 这样做有多高效? I can think of shared memory for this but not really sure about what all internal state OpenSSL maintains that needs to copied into the shared memory. 我可以为此考虑共享内存,但不能确定所有内部状态OpenSSL维护需要复制到共享内存中的内容。 This seems to be the most logical solution but I don't have much insight into OpenSSL code to do this. 这似乎是最合理的解决方案,但我对OpenSSL代码没有太多了解。

Has anybody faced similar problem and solved it? 有没有人遇到类似问题并解决了? I will really appreciate any help regarding this. 我真的很感激任何有关这方面的帮助。

Thanks a lot 非常感谢

A search online finds this discussion: 在线搜索找到了这个讨论:

Passing TLS sessions between programs 在程序之间传递TLS会话

Once you have the SSL_SESSION, convert it to ASN1 (via i2d_SSL_SESSION) and dump it to a file. 获得SSL_SESSION后,将其转换为ASN1(通过i2d_SSL_SESSION)并将其转储到文件中。 Read that file in with your second program and convert it back from ASN1 to SSL_SESSION(via d2i_SSL_SESSION) and add it to the SSL_SESSION cache of the SSL_CTX (via SSL_CTX_add_session). 使用第二个程序读取该文件,并将其从ASN1转换回SSL_SESSION(通过d2i_SSL_SESSION),并将其添加到SSL_CTX的SSL_SESSION缓存中(通过SSL_CTX_add_session)。

I found in doc/ssleay.txt : 我在doc / ssleay.txt中找到了:
[...] [...]
The PEM_write_SSL_SESSION(fp,x) and PEM_read_SSL_SESSION(fp,x,cb) will write to a file pointer in base64 encoding. PEM_write_SSL_SESSION(fp,x)和PEM_read_SSL_SESSION(fp,x,cb)将以base64编码写入文件指针。 What you can do with this, is pass session information between separate processes. 您可以做的是在不同进程之间传递会话信息。
[...] [...]

So you need to serialize the SSL session data from P1 and pass it to C1 to deserialize, along with the socket descriptor. 因此,您需要从P1序列化SSL会话数据并将其传递给C1以进行反序列化以及套接字描述符。 You can then create new SSL and SSL_CTX objects in C1 and associate them with the socket and deserialized session data so C1 can take over the conversation. 然后,您可以在C1中创建新的SSLSSL_CTX对象,并将它们与套接字和反序列化的会话数据相关联,以便C1可以接管对话。

I did a search for "tls kernel mode" and found a kernel patch to give a normal fd for a TLS connection. 我搜索了“tls内核模式”并找到了一个内核补丁,为TLS连接提供了正常的fd。 Thus the fd can be passed to other processes as a normal socket. 因此,fd可以作为普通套接字传递给其他进程。

The page is titled " TLS in the kernel " on lwn.net. 该页面在lwn.net上标题为“ 内核中的TLS ”。 Towards the bottom there are interesting discussions about it. 在底部有一些有趣的讨论。 Hope it may get its way into the kernel mainline. 希望它可以进入内核主线。 Or else wish someone may come up with a production quality patch set so people can make real use of it. 或者希望有人可以提出一个生产质量的补丁集,以便人们可以真正使用它。

If you know some real products are using it, probably it's a good idea to share it here. 如果你知道一些真正的产品正在使用它,那么在这里分享它可能是一个好主意。

Update: This open source project "TLSe" as a replacement to openssh is specially designed for exporting context to another process. 更新: 这个开源项目“TLSe”作为openssh的替代品专门用于将上下文导出到另一个进程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM