如何在一个过程中接受SSL连接并在另一个过程中重用相同的SSL上下文 [英] How to accept SSL connection in one process and reuse the same SSL context in another process

查看:108
本文介绍了如何在一个过程中接受SSL连接并在另一个过程中重用相同的SSL上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了很多时间研究如何解决这个问题,但还没有找到可行的解决方案.

I have spent quite some time doing my research on how to tackle this problem but could not find a working solution yet.

问题: 我正在使用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,因为它在内核中维护,但是由于在Openssl库中维护,因此我无法传递SSL上下文.

Problem: I am using OpenSSL library and linux. I have a server process P1 accepting SSL connection from SSL client. P1 does tcp_accept() and then SSL_accept() and exchanges some protocol data with client with 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. C1 uses execve call to re-image itself and spawn a different binary. C1 still needs to talk to the SSL client over the same SSL connection that was used in P1. The problem is since C1 is a completely different process now how it can re-use the existing SSL connection for that client? 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.

我看到了堆栈溢出的问题,但是不幸的是没有提到解决方案. OpenSSL:接受TLS连接,然后转移到另一个进程

I saw this tread on stackoverflow but unfortunately no solution is mentioned. OpenSSL: accept TLS connection and then transfer to another process

可能的解决方案: 我不确定是否有人已经解决了此类问题,但我尝试了以下方法.

Possible Solution: I am not sure if anybody has already solved this kind of problem but I tried following.

  1. 我想我可以创建一个新的SSL上下文,并在新的子进程中进行SSL重新协商.因此,在C1中,我在相同的基础tcp套接字fd上创建了一个新的SSL上下文,并尝试进行SSL重新协商.这就是我所做的(省略SSL_ctx初始化部分)

  1. I thought I can just create a new SSL conctext and do SSL renegotiation in the new child process. So in C1 I created a new SSL context over the same underlying tcp socket fd and tried to do SSL renegotiation. Here is what I did (Omiting the SSL_ctx initialization part)

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-> state = SSL_ST_ACCEPT;
SSL_do_handshake(ssl);

ssl = SSL_new(ctx) // ctx is initialized the same as it was done in P1 server
SSL_set_fd(ssl, fd); // fd is the underlying tcp socket fd passed from P1 to C1
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->state=SSL_ST_ACCEPT;
SSL_do_handshake(ssl);

但是重新协商未成功,并从第一个SSL_do_handshake()调用返回了Openssl内部错误.我什至不确定这是否真的可以做到.我能想到的另一种解决方案如下.

But the renegotiation does not succeed and returns me an Openssl Internal error from first SSL_do_handshake() call. I am not even sure if this can really be done. The other solution that I can think of is following.

  1. 以某种方式将该客户端的整个SSL上下文从P1传输到C1.这样做的效率如何?我可以为此考虑共享内存,但不能完全确定OpenSSL维护的所有内部状态需要复制到共享内存中的内容. 这似乎是最合乎逻辑的解决方案,但我对OpenSSL代码没有太多了解.
  1. Somehow transfer the whole SSL context for that client from P1 to 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. This seems to be the most logical solution but I don't have much insight into OpenSSL code to do this.

有人遇到过类似的问题并解决了吗? 我将非常感谢您对此提供的任何帮助.

Has anybody faced similar problem and solved it? I will really appreciate any help regarding this.

非常感谢

推荐答案

在线搜索发现了以下讨论:

A search online finds this discussion:

在程序之间传递TLS会话

拥有SSL_SESSION后,将其转换为ASN1(通过i2d_SSL_SESSION)并将其转储到文件中.使用第二个程序读取该文件,然后将其从ASN1转换回SSL_SESSION(通过d2i_SSL_SESSION),然后将其添加到SSL_CTX的SSL_SESSION高速缓存中(通过SSL_CTX_add_session).

Once you have the SSL_SESSION, convert it to ASN1 (via i2d_SSL_SESSION) and dump it to a file. 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).

我在doc/ssleay.txt中找到了:
[...]
PEM_write_SSL_SESSION(fp,x)和PEM_read_SSL_SESSION(fp,x,cb)将 以base64编码写入文件指针. 您可以执行的操作是在单独的会话之间传递会话信息 流程.
[...]

I found in 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. What you can do with this, is pass session information between separate processes.
[...]

因此,您需要序列化来自P1的SSL会话数据,并将其与套接字描述符一起传递给C1进行反序列化.然后,您可以在C1中创建新的SSLSSL_CTX对象,并将它们与套接字和反序列化的会话数据相关联,以便C1可以接管对话.

So you need to serialize the SSL session data from P1 and pass it to C1 to deserialize, along with the socket descriptor. 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.

这篇关于如何在一个过程中接受SSL连接并在另一个过程中重用相同的SSL上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆