2

ネットワーク層に Netty を使用するサーバー アプリケーションとそれに対応するクライアントを作成しています。クライアントからサーバーにパスワードを送信する際によくある安全上の懸念に直面しているため、これを行うには SSL が最も安全な方法であると判断しました。

私はセキュアチャットの例を知っており、これを使用してパイプラインを適宜変更します。ただし、パスワードの送信後に SSL を無効にし、サーバー側の貴重な CPU サイクルを節約することを認めたいと思います。サーバー側は、他の多くのクライアントでビジー状態になる可能性があります。ChannelPipelineのドキュメントには、次のように記載されています。

「いったん接続されると、チャネルとパイプラインの間の結合は永続的です。チャネルは別のパイプラインをそれに接続したり、現在のパイプラインを切り離したりすることはできません。」

アイデアは、禁止されているオンザフライでパイプラインを変更するのではなく、パイプライン内のSslHandlerに、ある時点でメッセージの暗号化を停止する必要があることを何らかの方法で伝えることです。SslHandlerから継承するクラスを作成し、そのhandleDownstream関数をオーバーライドして、通信のある時点でcontext.sendDownstream(evt)を呼び出すことを考えていました。

質問 1 : これは悪い考えですか、つまり、ある時点で SSL を無効にしますか?

パイプライン内のブロック ( Decoderなど) が別のブロック ( SslHandler など) に今後の動作を変更する必要があることを伝えるには、ChannelPipelineFactorygetPipeline()で AtomicBoolean を作成して渡すことができると考えました。 DecoderSslHandlerの両方のコンストラクターに。

質問 2 : パイプライン ブロック間で状態を共有することは悪い考えですか? ここでNettyのマルチスレッドを台無しにするのではないかと心配しています.パイプラインのブロックは一度に1つのメッセージで動作していますか? つまり、次のメッセージをプルする前に、最初のブロックは最後のブロックの完了を待ちますか?

編集:

残念ながら、これは私が何度も訪れ、まさにこの質問で引用していたChannelPipelineページからのものです。

「ChannelPipeline はスレッド セーフであるため、ChannelHandler はいつでも追加または削除できます。たとえば、機密情報が交換されようとしているときに SslHandler を挿入し、交換後に削除できます。」

したがって、これは、パイプラインの参照自体ではなく、パイプラインのコンテンツをオンザフライで変更することに関する質問 2 に答えます。

4

3 に答える 3

3

SslHandlerパイプラインから削除するとChannelPipeline.remove(..)、接続がプレーンテキストに変わります。うまくいかない場合はバグを報告してください - 私たちは実際にそのシナリオを本番環境で試していません:-)

于 2012-12-03T06:02:16.173 に答える
3

一度確立された SSL をオフにすることの有効性についてはわかりませんが、パイプラインの可変性を誤解していると思います。特定のチャネルがパイプラインに関連付けられると、その関連付けは不変になります。ただし、パイプラインのハンドラーは安全に変更できます。つまり、プロトコルの必要に応じてハンドラーを追加および削除できます。したがって、SSL ハンドラーが目的を果たしたら、SSL ハンドラーを削除できるはずです。

于 2012-11-27T10:12:56.043 に答える
2

Netty についてはよくわかりませんが、原則として、実際には同じ TCP 接続でプレーン トラフィックを続行できます。いくつかの欠点があります。

  • 認証のみが保護されます。MITM は、ユーザーが意図した以外のアクションを実行する可能性があります。(これはある程度、HTTP ダイジェストを使用することに似ています。資格情報は保護されますが、要求/応答エンティティは保護されません。)

  • 実装の観点からすると、これを正しく行うのは難しいことです。TLS 仕様には次のように記載されています。

    TLS を使用するアプリケーション プロトコルが、TLS 接続が閉じられた後、基礎となるトランスポートを介してデータを運ぶことができることを提供する場合、TLS 実装は close_notify、TLS 接続が終了したことをアプリケーション層に示す前に、応答アラートを受信する必要があります。

    close_notifyこれは、通常のトラフィックを続行する前に、何らかの形でストリームを同期して応答を待つことを意味します。プログラミング モデルはかなり複雑であり、SSLEngineNetty API がこの状況を処理する必要がないことに気付くかもしれません。

いくつかの CPU サイクルを節約したいのは理にかなっているかもしれませんが、SSL/TLS オーバーヘッドのほとんどはハンドシェークにあります。データの実際の暗号化に使用される対称暗号操作は、はるかに安価です。(このオーバーヘッドを測定して、それが本当に問題であるかどうかを確認する必要があります。)

于 2012-11-27T10:38:41.183 に答える