2009-05-28 5 views
16

時々悪い状態に陥るアプリケーションがいくつかありますが、これは実際には生産中だけです(もちろん!)。ヒープダンプを取ると状態情報を収集するのに役立ちますが、リモートデバッガを使用するほうが簡単です。これを設定することは簡単です - 1は彼のコマンドラインに以下を追加する必要が:プロダクションJVMのセキュアなデバッグ

-Xdebug -Xrunjdwp:輸送= dt_socketという、サーバー= Y、一時停止= N、アドレス= NOとPORT

あるようですプロダクションでのデバッグを有効にすると、ホットスワップを使用して任意のコードを実行することができます。

Solaris 9およびLinux(Redhat Enterprise 4)で動作するSun JVM 1.4.2および1.5が混在しています。安全なデバッグを可能にするにはどうすればよいですか?生産サーバー検査の目標を達成するための他の方法はありますか?

アップデート: JDK 1.5+ JVMの場合、デバッガがバインドする必要があるインタフェースとポートを指定できます。だから、KarlPのループバックへのバインディングとローカルの開発者ボックスへのSSHトンネルの使用は、SSHがサーバ上で適切に設定されていればうまくいくはずです。

しかし、JDK1.4xでは、デバッグポートにインターフェイスを指定できないようです。だから、私たちはネットワークのどこかでデバッグポートへのアクセスをブロックするか、OS自体(Jaredが提案するIPChainsなど)でシステム特有のブロックを行うことができますか?

更新#2:デバッガをオンにする

-Xdebug 
-Xrunjdwp: 
    transport=dt_socket, 
    server=y, 
    suspend=n, 
    address=9001, 
    onthrow=com.whatever.TurnOnDebuggerException, 
    launch=nothing 

Javaコード:

コマンドラインのparams:これは、私たちも1.4.2のJVM上で、私たちのリスクを制限できるようになるハックです

TurnOnDebuggerExceptionは、他のどこにもスローされないことが保証されています。

(1)デバッガポートが最初に接続を受け取らないこと、(2)上記のようにTurnOnDebugger例外をスローすることでデバッガが動作することを証明するために、これをWindowsのボックスでテストしました。起動パラメータは(少なくともJDK1.4.2では)必要でしたが、ガベージ値はJVMによって正常に処理されました。

適切なセキュリティの背後にある小さなサーブレットを作成して、デバッガをオンにできるようにする予定です。もちろん、後でそれをオフにすることはできませんし、デバッガはいまだ一度も無差別に聴いています。しかし、これは、本番システムのデバッグが後で再起動されるため、受け入れることができる制限です。

更新#3:(1)TurnOnDebuggerException、プレーンな「オールJavaの例外、(2)DebuggerPoller、背景がファイルシステム上の指定したファイルの存在をチェックスレッド:私は三つのクラスを書いてしまいました(3)DebuggerMainWrapper:ポーリングスレッドを起動し、指定された別のクラスのmainメソッドを反映して呼び出すクラスです。

これは、その使用方法である:2つのシステム(-D)のparams、本当のメインクラスを指定する1を追加するには、起動スクリプトで

  • をDebuggerMainWrapperであなたの「メイン」クラスを交換し

    1. 、およびもう1つはファイルシステム上のファイルを指定します。
    2. onthrow = com.whatever.TurnOnDebuggerExceptionの部分を追加してデバッガを構成します。
    3. 上記の3つのクラスを持つjarをクラスパスに追加します。

    ここで、JVMを起動すると、バックグラウンドポーラースレッドが開始される以外はすべて同じです。ファイル(私たちがTurnOnDebuggerと呼ばれる)が最初に存在しないと仮定すると、ポーラーはN秒ごとにそれをチェックします。ポーラーが最初にそれに気付くと、それは投げられ、すぐにTurnOnDebuggerExceptionをキャッチします。その後、エージェントはキックオフされます。

    これをオフに戻すことはできません。オンになっているとマシンのセキュリティは非常に悪くはありません。逆に、私はデバッガが複数の同時接続を許可しているとは思わないので、デバッグ接続を維持するのが最善の防御です。私たちはファイルの通知方法を選択しました。これは、適切な用途のみが権利を持つディレクトリにトリガファイルを指定することで、既存のUnixのauthen/authorにピギーバックできたからです。ソケット接続を介して同じ目的を達成した小さな戦争ファイルを簡単に作成することができます。もちろん、デバッガをオフにすることはできませんので、アプリケーションを強制終了する前にデータを収集するためにのみ使用します。もし誰かがこのコードを望むなら、私に知らせてください。しかし、あなた自身でそれを一緒に投げるのに数分しかかかりません。

  • 答えて

    8

    SSHを使用する場合は、トンネリングを許可し、ポートをローカルホストにトンネルできます。開発は必要ありません。すべてsshd、ssh、および/またはputtyを使って行います。

    javaサーバーのデバッグソケットは、ローカルインターフェイス127.0.0.1で設定できます。

    +0

    これが動作する(今テスト中)場合は、私たちのために最適なオプションのようです。私たちは定期的にデバッグするのとは異なりますが、正しく動作していない状態でJVMをキャッチする必要があります。 – ShabbyDoo

    +1

    これはJDK 1.5以降でのみ動作すると思います: http://java.sun.com/j2se/1.5.0/docs/guide/jpda/enhancements.html 「dt_socketトランスポートが改訂されました。上記のリンクの「サーバーモードで実行するときにローカルアドレスを取得する」を参照してください。 – ShabbyDoo

    +0

    @Shabby - yep - これは1.5+を動作させるように見え、すばらしい解決策です。別の方法は、ファイアウォール(ソフトウェアまたはハードウェア)を介してデバッグポートをロックダウンすることです。あなたのLinuxホスト用にチェックインするipchainsですか? (http://tldp.org/HOWTO/IPCHAINS-HOWTO.html) – Jared

    0

    情報/サービスをJMXにエクスポートし、RMI + SSLを使用してリモートからアクセスします。あなたの状況はJMXが設計したものです(MはManagementの略です)。

    +0

    一般的なメトリックはJMXを介して公開する必要があることに同意します。私たちは実際に軽量プロダクションプロファイラ(Wily)を使用していますが、状態情報をキャプチャするのはあまり良くありません。粗いトレースに限定した場合にのみうまく実行できます。もう1つの問題は、これらのアプリの一部が(部分的に)サードパーティ製なので、逆コンパイルされたソースを使ってデバッグすることです。 – ShabbyDoo

    +1

    私はまだ、実稼働アプリケーションにデバッガーを接続することは悪い考えです。ユーザーは、ブレークポイントに達したときに何が起きているのか分からず、メモリを使いながら数分間過ごします。 問題が発生しているコード内でJMX経由で現在の状態を公開し、何が起きているのか詳細な監査ログを保持しようとします。 – Kevin

    +1

    デバッグする前に、ロードバランスされたクラスタから悪い動作をするインスタンスを実際に外しています。私は、アクティブなユーザーとのアプリケーションのデバッグは本当に悪い考えであることに同意します。 – ShabbyDoo

    2

    あなたは絶対に正しいです.JavaデバッグAPIは本質的に安全ではありません。ただし、これをUNIXドメインソケットに限定し、SSL/SSHを使用してプロキシを作成することで、認証され暗号化された外部接続をUNIXドメインソケットにプロキシすることができます。少なくとも、サーバーにプロセスを取得できる人や、SSLをクラックさせる可能性のある人へのエクスポージャーを減らすことができます。

    +0

    デフォルトインターフェイスのポートをドメインソケットにマップできますか?私が抱えている問題は、1.4.xのSun JVMがデフォルト(?)インタフェースにしかバインドできないということです。したがって、このポートがVMの外部に公開されないように、いくつかのマジカルマッピングが必要になります。 – ShabbyDoo

    0

    良い質問です。

    私は、デバッグポートへの接続を暗号化する組み込みの機能について認識していません。

    は、はるかに良い/簡単に解決策があるかもしれませんが、私は次のようにします:

    1. はブロックがデバッグポート(複数可)へのアクセスをファイアウォールの背後生産機械を置きます。
    2. ポートに接続するホスト自体でプロキシ処理を実行し、ソケットからの入出力を暗号化します。
    3. 入力を暗号化/復号化するデバッグワークステーションでプロキシクライアントを実行します。これをサーバープロキシに接続します。それらの間の通信は暗号化される。
    4. デバッガをプロキシクライアントに接続します。
    +0

    補足として、当社のプロダクションサーバーはファイアウォールの背後にありますが、一部の内部ネットワークセグメントにさらされています。 – ShabbyDoo

    関連する問題