6

We have a (Linux) server running two processes, A and B. Currently, clients establish a connection to process A, which then passes the resulting socket's file descriptor to process B, allowing process B to use the existing fd/socket to communicate seamlessly with the client. The client and process B then perform a TLS handshake and continue talking on the resulting TLS connection.

(I'm leaving out a lot of details here, but yes, there is a good reasons for having process A act as an intermediary instead of just connecting to process B directly)

Now, because of <long complicated story involving new client applications and websockets> it looks like we may have to perform the TLS handshake in process A, and then transfer the established TLS connection to process B.

Is that possible? The underlying socket's file descriptor can be copied (we do that already), and at least in theory, the internal TLS state data could also be copied and used to reconstruct the TLS connection in process B, effectively taking over the connection.

But does OpenSSL expose any facility like that? I found the function d2i_SSL_SESSION which seems to do something similar for an OpenSSL session object, but being quite new to OpenSSL, I'm not sure if that is sufficient. There are sessions, context, BIO's and a bunch of other complicated-sounding terms involved. How much would have to be serialized and transferred to process B for this to work? And how would it be done in practice?

The switchover is required to be 100% transparent to the client: it must simply perform an SSL handshake against a given IP/port, and then continue talking on the resulting socket, with no knowledge of the fact that one process accepts the connection and performs the TLS handshake, and another then handles all subsequent communication.

4

5 に答える 5

2

プロセス間で SSL コンテキストを共有することは実際に可能です。ただし、SSL-session-context は、両方のプロセスからアクセスできる共有メモリの場所に存在する必要があります (具体的な理由は不明であるため)。実際のハンドシェイクをプロセス A で実行し、データ I/O を実行する必要があります。プロセスBで。

最初のステップは、SSL_CTX_sess_set_new_cb(ctx, shared_ctx_new_cb); のコールバックを登録することです。SSL_CTX_sess_set_get_cb(ctx, shared_ctx_get_cb); SSL_CTX_sess_set_remove_cb(ctx, shared_ctx_remove_cb);

適切な SSL-session-context が常に共有メモリに作成されるようにします (または、少なくともシリアル化され、すぐに使用できるアドレス指定可能なポインターを SSL_SESSION に返します)。

SSL_SESSION 'C' 構造体を (デ) シリアル化するには、利用可能な API d2i_SSL_SESSION(...) および i2d_SSL_SESSION(...) を使用します。

このアプローチを使用した作業プロジェクトhttps://github.com/varnish/hitch/blob/master/src/shctx.cのサンプル コード

于 2016-06-21T10:33:13.950 に答える
1

実際にこれを試したことはありませんが、接続がソケットレベルで作成された後、opensslによって初期化され、SSL_readとSSL_writeで読み書きできることを覚えている限りです。ソケット fd をパラメーターとして受け入れます。接続自体 (SSL 側から) は SSL_CTX SSL 構造体で表されます。

理論的には可能に思えますが、私が言ったように、私は現実の世界でそれを試したことはありません.

于 2012-09-14T14:25:49.510 に答える
1

最近のカーネル パッチでは、TLS 接続に通常の fd を指定することで、これが可能になる場合があります。「カーネル内の TLS By Jake Edge 2015 年 12 月 2 日」のページを参照してください。また、別のSO questionにクロス投稿しました。

于 2016-06-18T18:08:08.860 に答える
0

価値があるよりもはるかに厄介なように聞こえます...他の設計を検討してください。たとえば、ループバックインターフェイスを使用してBに代わってAを介して接続をプロキシします。

于 2012-09-14T16:26:54.617 に答える
0

最初のハンドシェイクの一部は鍵交換であり、進行中の通信には鍵が必要であるため、それは不可能だと思います。プロセス B は、リモート エンドとプロセス A で使用されているキーを知る必要があります。

于 2012-09-14T14:23:06.290 に答える