![](/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.