1

そのため、私は独自の Java ベースのアプリケーション サーバーを開発しています(Glassfish などは Web ベース以外のアプリケーション向けではないため)。もちろん、暗号化は絶対に必要です。SslRMIClientSocketFactoryそこで、標準の とを使用して基本的な SSL ソリューションをコーディングしましたSSLRMIServerSocketFactory。ここまでは順調ですね。ただし、クライアント側の証明書の使用を許可するが必要としないなど、他にもいくつかの問題があります (システムに SSH で接続する場合など)。

しかし、途中で「Java 5.0」が登場した 2005 年以降、xinetd「nix ベースのソリューションを使用するための助けが明らかになった」ことに気付きました。これを行う際の「新しい」ヘルプは、 xinetd - via のように、下位レベルから「継承」されたソケット情報を取得する機能であるように思われSystem.inheritedChannelます。

RMI ソリューションで暗号化と xinetd を一緒に使用する例が必要だと考えたところ、 The New RMIという優れた記事を見つけました。記事がありませんでした。少し腐っていると思います。(誰もコピーを持っていますか?!) 記事に表示されている例は不完全すぎて、テキストはサンプル コードがあるという事実に依存しています。しかたがない。簡単に言えば、よくわかりません-使用するSystem.inheritedChannelことは、既存のRMIレジストリ関連のコードにプラグインするだけでは明らかに簡単ではありません-明らかにソケットファクトリを作成する必要があります。 、例を探しています。

だから狩りに行った。Apache 関係者も同様のことを行っていることがわかりました。ここでRMI Service Exporterについて説明していますが、それは私がむしろ避けたい技術である SpringBeans を使用しています。そして、これは重要な例であるため、率直に言って、自分の仕事でこの種のソリューションをどのように使用すればよいか、少し迷っています。

探し続けたところ、一見したところInitializeRegistryという名前の優れたソリューションのように見えましたが、SSL への参照がまったくなく、すぐに迷子になりました。たとえば、次のように説明しています。

レジストリを作成してエクスポートし (継承されたチャネルがある場合はそれを使用して)、そのレジストリ内の指定されたプロキシに指定された名前をバインドします。

ここでの私の問題は言語です。特に、私はプロキシを使用していません。使用していたとしても、なぜそれが問題になるのかわかりません。また、名前だけでなく、オブジェクトを RMI レジストリにバインドしていると思いました。おそらく、誰かが自分のしていることを明確にすることができれば、これは良い例です...

最後に、ここ StackOverflow で、 Java RMI、SSL、および圧縮について話しているすばらしい回答を偶然見つけました。これまでで最も素晴らしいものの 1 つです。圧縮は私のニーズには関係ありませんが、それは興味深い議論です。それでも、RMIをSSLとxinetdの両方で同時に使用する方法を理解するのにどのように役立つかわかりません...

ありがとうございました。

アップデート:

EJP の提案された回答 (感謝しています) に応えて、InitializeRegistry.java上記の例から始めました。accept() メソッドを次のように更新しました。

      .
      .
      .
      /* Here we wrapper our socket with SSLSocketFactory.createSocket()

         Some open questions I have are whether the arguments to createSocket()
         are all _inbound_ in nature. Here's the basic call:

            SSLSocketFactory.createSocket(socket, host, port, auto-close);

         I PRESUME args are for the REMOTE host, not "us?"

            REMOTE: serverSocket.getInetAddress()
            LOCAL:  serverSocket.getLocalAddress()

            REMOTE: serverSocket.getPort()
            LOCAL:  serverSocket.getLocalPort()

         Who Knows about auto-close?! I'll try it and see if it works OK.
      */

      boolean autoClose = true;

      return (Socket)SSLSocketFactory.createSocket(serverSocket.accept(),
       serverSocket.getInetAddress().getHostAddress(),
       serverSocket.getLocalPort(),
       autoClose).accept();

      //return serverSocket.accept();
   }

ただし、このコードはコンパイルに失敗し、次のように不平を言っています。

  • createSocket()静的コンテキストから呼び出すことはできません - そして私はそれに対する解決策を見つけることができませんでした
  • .accept()2 番目の「記号」「 」が見つかりませんでした。

final を削除すると、このコードの静的コンテキストから.accept()「非静的メソッド」を使用できなくなるだけで、エラー カウントが減少します。createSocket()しかし、クラスから「静的」を削除しようとすると、いたるところに落ちて、どこにでもある「this」参照を使用できなくなります。OTOH、静的にする方法がわかりませんSSLSocketFactory.createSocket()!

accept()...渡されたソケット (!!) へのアクセスを取得するために使用されたもので十分であり、次に含めようとしたものは必要ないと推測しても安全ですか? うーん...

私はそれを試して、私だけがこれを構築できるかどうかを確認したいと思います.

ところで、後で使用する必要があると思いますsetUseClientMode(false)...はい?

さらに考えて....

私はそれがおそらく悪い出発点であることに気づき、InitializeRegistry.java「最初のプリンシパル」に戻りました。おそらく、最初にchannel経由して与えられた を受け取り、それをSystem.inheritedChannelに変換するときに道に迷ったことがわかったServerSocketので、オーバーライドのアイデアServerSocketFactoryは、まあ、"多くの作業"。そして、それは私を襲った:

ここでの要点は、要求されていない接続要求がリッスンしているターゲットに確実に到達するようにすることです。しかし、それ以上に、オブジェクトが有用であるためには、レジストリにオブジェクトが存在する必要があります。そのためには、それを作成するものも必要です。したがって、これを NETWORK SERVICE として解決することを心配するよりも、オブジェクトを作成するコードが SYSTEM SERVICE として実行されるようにする方が、同様に簡単です。

したがって、私はパントしています。...ただし、質問を削除するのは残念です。これは、他の誰かにガイダンスを提供する可能性があるためです。これは、この件に触れるすべての StackOverflow で唯一のクエリです。

再度、感謝します。

4

1 に答える 1

2

の要点がわかりませんDelayedAcceptServerSocketFactory。ちょっとやり過ぎですが、基本的なテクニックは次のとおりです。

  1. メソッドがオーバーライドされて、継承されたチャネルから来たに委譲するオーバーライドをRMIServerSocketFactory返す を記述します。ServerSocketaccept()ServerSocket

  2. accept()そのメソッドが戻る前に、そのソケットの、 via 、および callで受け入れられSocketたものをラップします。SSLSocketSSLSocketFactory.createSocket(Socket, ...)setUseClientMode(false)

出来上がり!RMI レジストリは xinetd によって開始され、レジストリ クライアントに対して SSL を使用します。それがあなたが望んでいたものであると仮定すると、クライアントは 経由でアクセスする限り、そのレジストリを検索できるようになりましたLocateRegistry.getRegistry(host, port, csf)

同様に、サーバーは同じ方法でアクセスする限り、それにバインドできます。

次に、SslRMI* ソケット ファクトリを使用してリモート オブジェクトを作成し、通常どおりレジストリにバインドします。

終わり。

于 2012-02-28T03:48:57.053 に答える