JMXテクノロジを使用するモニタリングと管理
Java仮想マシン(Java VM)は組込みインストゥルメンテーションを備え、これによってJava Management Extensions (JMX)テクノロジを使用したモニターと管理を行うことができます。 これらの組込み管理ユーティリティは通常、Java VMのアウトオブボックスの管理ツールと呼ばれます。 適切に計測されたアプリケーションであれば、JMX APIを使用してモニターできます。
システム・プロパティの設定
アウトオブボックスのJMXエージェントを有効にして、Java VMのモニターと管理ができるように構成するには、Java VMの起動時に特定のシステム・プロパティを設定する必要があります。 システム・プロパティは、コマンド行で次のように設定します。
java -Dproperty=value ...
このようにシステム・プロパティはいくつでも設定できます。 管理プロパティは、値を指定しないとデフォルト値に設定されます。 アウトオブボックスの管理プロパティのフル・セットについては、この章の末尾の表 2-1を参照してください。 システム・プロパティは、「アウトオブボックスのモニタリングおよび管理のプロパティ」で説明しているように、構成ファイルのなかでも設定できます。
ノート -コマンド行からJava VMを実行するには、パスにJRE_HOME/binを追加する必要があります。JRE_HOMEはJava Runtime Environment (JRE)実装が入ったディレクトリです。 別の方法として、コマンド入力時にフル・パスをキー入力しても構いません。
Java HotSpot VMでサポートされる構文とコマンド行のフル・セット・オプションについては、次のドキュメントを参照してください。
アウトオブボックスの管理の有効化
JMX APIを使用してJavaプラットフォームをモニターするには、次の手順を実行する必要があります。
-
Java VMの起動時にJMXエージェント(プラットフォームMBeanサーバーの別名)を有効にします。 JMXエージェントの有効範囲は次のとおりです。
-
ローカル・モニタリング、ローカル・システムで実行されるクライアント管理アプリケーション。
-
リモート・モニタリング、リモート・システムで実行されるクライアント管理アプリケーション。
-
-
JMX仕様にコンパイルするツール(JConsoleなど)でJava VMをモニターします。 コンソールの詳細については、第 3章「JConsoleの使用」を参照してください。
それらのステップについて、次のセクションで説明します。
ローカル・モニタリングおよび管理
Java SEプラットフォームの以前のリリースでは、JMXクライアントでローカルのJava VMにアクセスするには、Java VMまたはJavaアプリケーションの起動時に、次のシステム・プロパティを設定する必要がありました。
com.sun.management.jmxremote
このプロパティを設定することでJava VMプラットフォームのMBeanを登録し、非公開インタフェースを介してRemote Method Invocation (RMI)コネクタを公開して、JMXクライアント・アプリケーションでローカルのJavaプラットフォーム(JMXクライアントと同じマシン上で動作するJava VM)をモニターできるようにしました。
Java SE 6プラットフォームでは、このシステム・プロパティの設定は必要ありません。 どのアプリケーションでも、Java SE 6プラットフォームで起動したものであればAttach APIがサポートされ、ローカル・モニタリングと管理が必要な場合は自動的に使用可能になります。
たとえば、以前ならJava SEのサンプル・アプリケーションNotepadでJMXエージェントを有効にするには、次のコマンドを実行する必要がありました。
% cd JDK_HOME/demo/jfc/Notepad % java -Dcom.sun.management.jmxremote -jar Notepad.jar
このコマンドのうちJDK_HOMEは、Java Development Kit (JDK)がインストールされるディレクトリです。 Java SE 6プラットフォームでは、次のコマンドを実行するだけでNotepadが起動します。
% java -jar Notepad.jar
Notepadが起動すると、Attach APIを使用するJMXクライアントがアウトオブボックスの管理エージェントを有効にし、Notepadアプリケーションのモニターと管理を行えるようになります。
ノート - Windowsプラットフォームではセキュリティ上の理由から、ローカル・モニタリングと管理がサポートされるのは、デフォルトの一時ディレクトリが、ファイルおよびディレクトリのアクセス権が設定可能なファイル・システム(たとえば、New Technology File System (NTFS)ファイル・システム)にある場合にかぎられます。 アクセス制御が不十分なFile Allocation Table (FAT)ファイル・システムではサポートされません。
JConsoleを使用したローカル・モニタリングおよび管理
JConsoleを使用したローカルのモニタリングは、開発とプロトタイプの作成に役立ちます。 JConsoleのローカルな使用は、本番環境ではお薦めしません。JConsole自体が相当のシステム・リソースを消費するためです。 JConsoleはリモート・システムで使用し、モニター対象のプラットフォームから分離した方がよいでしょう。
それでもローカルのモニタリングにJConsoleを使用する場合は、コマンド・シェルにjconsoleと入力してツールを起動します。 引数なしでjconsoleを起動すると、ローカルのJavaアプリケーションがすべて自動検出され、モニター対象とするアプリケーションを選択できるダイアログ・ボックスが表示されます。 JConsoleとアプリケーションはどちらも、同じユーザーが実行する必要があります。モニタリングおよび管理システムには、オペレーティング・システムのファイル・アクセス権を使用するためです。
ノート -コマンド行からJConsoleを実行するには、JDK_HOME/binをパスに追加する必要があります。 別の方法として、コマンド入力時にフル・パスをキー入力しても構いません。
詳細は、第 3章「JConsoleの使用」を参照してください。
リモート・モニタリングおよび管理
リモート・システムからモニタリングと管理を行うには、Java VM起動時に次のシステム・プロパティを設定する必要があります。
com.sun.management.jmxremote.port=portNum
このプロパティの中のportNumは、JMX RMI接続に使用するポート番号です。 必ず未使用のポート番号を指定してください。 ローカル・アクセスではRMIコネクタを公開するのに加えて、このプロパティを設定することにより、既知の名前「jmxrmi」を使用して、指定されたポートの非公開の読取り専用レジストリで追加のRMIコネクタを公開します。
ノート -セキュリティ用に設定するプロパティのほかに、上記のシステム・プロパティを設定する必要があります。
リモート・モニタリングと管理には、権限のない人がアプリケーションの制御やモニターができないように、セキュリティが必要です。 デフォルトで、SSL (secure sockets layer)経由のパスワード認証とTLS (Transport Layer Security)が有効になっています。 次のセクションに説明するように、パスワード認証とSSLは個別に無効にできます。
ノート - 実稼働システムの場合、クライアント・ホストを認証するSSLクライアント証明書とユーザー管理用のパスワード認証の両方を使用します。 詳細は、「SSLの使用」および「LDAP認証の使用」のトピックを参照してください。
Javaプラットフォームでは、認証にプラガブルなログイン・モジュールがサポートされます。 組織の認証インフラストラクチャに応じて、任意のログイン・モジュールをプラグインできます。 「LDAP認証の使用」というタイトルのセクションでは、Lightweight Directory Access Protocol (LDAP)ベースの認証にcom.sun.security.auth.module.LdapLoginModuleをプラグインする方法について説明します。
JMXエージェントをリモートで使用可能にすると、「JConsoleによるリモート・モニタリング」に説明するように、JConsoleでアプリケーションをモニタリングできます。 プログラムから管理エージェントに接続する方法については、「プログラムによるJMXエージェントへの接続」を参照してください。
パスワード認証の使用
LDAP認証の使用
JMXエージェントのJMXAuthenticator実装は、Java認証・承認サービス(JAAS)テクノロジに基づいています。 認証は、ユーザー資格をJAAS javax.security.auth.spi.LoginModuleオブジェクトに渡すことで実行されます。 com.sun.security.auth.module.LdapLoginModuleクラスでは、LDAPを使用した認証が可能です。 次に説明するように、デフォルトのLoginModule
クラスをLdapLoginModule
で置き換えることができます。
必要なビジネス組織で機能するJAAS構成ファイルを作成します。 次に、構成ファイル(ldap.config
)の例を示します。
ExampleCompanyConfig { com.sun.security.auth.module.LdapLoginModule REQUIRED userProvider="ldap://example-ds/ou=people,dc=examplecompany,dc=com" userFilter="(&(uid={USERNAME})(objectClass=inetOrgPerson))" authzIdentity=monitorRole; };
次に、構成ファイルのオプションについて簡単に説明します。 コード部分に示されている構成オプションの詳細は、com.sun.security.auth.module.LdapLoginModuleクラスのドキュメントを参照してください。
com.sun.security.auth.module.LdapLoginModule REQUIRED
オプションは、認証全体を正常に行うためにLdapLoginModule
を使用した認証が必要なことを意味します。userProvider
オプションは、LDAPサーバー、およびユーザー・エントリがあるディレクトリ・ツリー内の位置を特定します。userFilter
オプションは、LDAPディレクトリ内のユーザー・エントリの検索に使用する検索フィルタを指定します。 フィルタを使用してディレクトリを検索する前に、トークン{USERNAME}
はユーザー名と置き換えられます。authzIdentity
オプションは、認証されたユーザーのアクセス・ロールを指定します。 例では、認証されたユーザーはmonitorRole
を持ちます。 詳細は、「アクセス・ファイル」セクションを参照してください。
コマンド行で次のプロパティを設定して、アプリケーションを起動します。
com.sun.management.jmxremote.login.config
- このプロパティは、指定したJAAS構成エントリを使用するようJMXエージェントを構成します。java.security.auth.login.config
- JAAS構成ファイルへのパスを指定します。
次に、コマンド行の例を示します。
java -Dcom.sun.management.jmxremote.port=5000 -Dcom.sun.management.jmxremote.login.config=ExampleCompanyConfig -Djava.security.auth.login.config=ldap.config -jar MyApplication.jar
ファイルベースのパスワード認証の使用
JMXエージェントによってサポートされるファイルベースのパスワード認証メカニズムは、パスワードをクリアテキストで格納し、開発での使用のみを目的としています。 本番での使用の場合、認証にSSLクライアント証明書を使用するか、セキュアなログイン構成をプラグインすることを強くお薦めします。
警告 -クライアントがセキュアではないRMIレジストリ(デフォルト)からリモート・コネクタを取得すると、リモート・コネクタからのパスワード認証でセキュリティの問題が発生する可能性があります。 ターゲット・サーバー上で正当なRMIレジストリが起動する前に攻撃者が偽のRMIレジストリを起動すれば、クライアントのパスワードを盗むことができます。 このシナリオは、システム・プロパティcom.sun.management.jmxremote.port=portNumでリモート管理を有効にしてJava VMを起動する場合も当てはまります。SSLが有効になっていても同じです。 このような攻撃者は発見されることが多いものの、脆弱性があることは確かです。
デフォルトでは、リモート・モニタリングでJMXエージェントを有効にすると、JMXエージェントはパスワード認証を使用します。 ただし、パスワードを設定する方法は、シングル・ユーザー環境かマルチユーザー環境かによって異なります。
パスワードはパスワード・ファイルにクリアテキストで格納されるため、通常のユーザー名とパスワードをモニタリング用に使用することはお薦めできません。 代わりに、monitorRoleおよびcontrolRoleなどのパスワード・ファイルで指定したユーザー名を使用します。 詳細は、「パスワードとアクセス・ファイルの使用」を参照してください。
シングル・ユーザー環境を設定する方法
JRE_HOME/lib/managementディレクトリのパスワード・ファイルを、次のように設定します。
- パスワード・テンプレート・ファイルjmxremote.password.templateをjmxremote.passwordにコピーします。
- ファイル所有者だけがパスワード・ファイルを読書きできるように、ファイルのアクセス権を設定します。
- monitorRoleやcontrolRoleなどのロールのパスワードを追加します。
マルチユーザー環境を設定する方法
JRE_HOME/lib/managementディレクトリのパスワード・ファイルを、次のように設定します。
- パスワード・テンプレート・ファイルjmxremote.password.templateをホーム・ディレクトリにコピーし、そのファイル名をjmxremote.passwordに変更します。
- 自分だけがパスワード・ファイルを読書きできるように、ファイルのアクセス権を設定します。
- monitorRoleやcontrolRoleなどのロールのパスワードを追加します。
- Java VMの起動時に、次のシステム・プロパティを設定します。
com.sun.management.jmxremote.password.file=pwFilePath
上記のプロパティの中のpwFilePathは、パスワード・ファイルへのパスです。
パスワード認証の無効化
リモート・モニタリングのパスワード認証は、デフォルトで有効になっています。 パスワード認証を無効にするには、Java VMの起動時に次のシステム・プロパティを設定します。
com.sun.management.jmxremote.authenticate=false
警告 -この構成はセキュアではありません。 JMXポート番号およびホスト名を知っている(または推測する)リモート・ユーザーならだれでも、Javaアプリケーションおよびプラットフォームのモニターと制御ができます。 開発用には許容される場合があっても、実稼動システムにはお薦めしません。
パスワード認証を無効にする場合、「セキュリティの無効化」で説明しているようにSSLを無効にすることもできます。 「SSLクライアント認証の有効化」で説明しているように、パスワードを無効にしてSSLクライアント認証を使用する場合もあります。
SSLの使用
リモート・モニタリングおよび管理を有効にすると、SSLはデフォルトで有効になっています。 SSLを使用するには、JMXエージェント(MBeanサーバー)が稼動するシステム上でデジタル証明書を設定して、次にSSLを正しく構成する必要があります。 コマンド行ユーティリティkeytoolを使用して、証明書を操作します。 一般的な手順は次のとおりです。
SSLを設定する方法
- サーバー上でまだキー・ペアと証明書を設定していない場合、次の手順に従います。
-
keytool -genkeyコマンドでキー・ペアを生成します。
-
keytool -certreqコマンドで認証局(CA)に署名付き証明書を要求します。
-
keytool -importコマンドで、証明書をキーストアにインポートします。 keytoolドキュメントの「証明書のインポート」を参照してください。
詳細および例については、「keytool - キーおよび証明書管理ツール(Solaris、LinuxまたはMac OS X)」または「keytool - キーおよび証明書管理ツール(Windowsプラットフォーム)」を参照してください。
-
- サーバー・システム上でSSLを構成します。
このドキュメントでは、SSLの構成とカスタマイズについて詳細には説明しませんが、通常は次のリストに記載されているシステム・プロパティを設定する必要があります。
- システム・プロパティ
-
説明
- javax.net.ssl.keyStore
-
キーストアの場所。
- javax.net.ssl.keyStoreType
-
デフォルトのキーストア型。
- javax.net.ssl.keyStorePassword
-
デフォルトのキーストア・パスワード。
- javax.net.ssl.trustStore
-
トラスト・ストアの場所。
- javax.net.ssl.trustStoreType
-
デフォルトのトラスト・ストア型。
- javax.net.ssl.trustStorePassword
-
デフォルトのトラストストア・パスワード。
システム・プロパティの設定の詳細は、上記の「システム・プロパティの設定」または次のドキュメントを参照してください。
RMIレジストリ認証の有効化
リモート・アプリケーションのモニタリングで接続を設定するとき、SSLで保護されているRMIレジストリにRMIコネクタ・スタブをオプションでバインドできます。 これにより、適切なSSL証明書を持つクライアントは、RMIレジストリに登録されたコネクタ・スタブを取得できます。 RMIレジストリをSSLで保護するには、次のシステム・プロパティを設定する必要があります。
com.sun.management.jmxremote.registry.ssl=true
このプロパティがtrueに設定されている場合、Java VMの起動時に、アウトオブボックスの管理エージェントによって、SSLで保護されたRMIレジストリの生成および構成が行われます。 このプロパティのデフォルト値はfalseです。 ただし、このプロパティはtrueに設定することをお薦めします。 このプロパティがtrueに設定されている場合は、全面的なセキュリティを確保するために、次のセクションで説明されているようにSSLクライアント認証を有効にする必要もあります。
SSLクライアント認証の有効化
SSLクライアント認証を有効にするには、Java VMの起動時に次のシステム・プロパティを設定します。
com.sun.management.jmxremote.ssl.need.client.auth=true
クライアントSSL認証を使用するには、SSLを有効(デフォルトはfalseに設定されます)にしておく必要があります。 このプロパティはtrueに設定することをお薦めします。 この構成では、クライアント・システムが有効なデジタル証明書を持つ必要があります。 「SSLの使用」の説明に従って、クライアント・システムに証明書をインストールし、SSLを構成する必要があります。 前のセクションで述べたように、RMIレジストリのSSL保護を有効にした場合は、クライアントSSL認証をtrueに設定する必要があります。
SSLの無効化
リモート・モニタリングでSSLを無効にするには、Java VMの起動時に次のシステム・プロパティを設定する必要があります。
com.sun.management.jmxremote.ssl=false
パスワード認証は、「パスワード認証の無効化」の手順に従って無効にしないかぎり、必要になります。
セキュリティの無効化
パスワード認証とSSLの両方を無効(つまりすべてのセキュリティを無効)にするには、Java VMの起動時に次のシステム・プロパティを設定するべきです。
com.sun.management.jmxremote.authenticate=false com.sun.management.jmxremote.ssl=false
警告 - この構成はセキュアではありません。ポート番号およびホスト名を知っている(または推測する)リモート・ユーザーならだれでも、Javaアプリケーションおよびプラットフォームのモニターと制御ができます。 さらに、危害の可能性はMBeanで定義する操作に限定されません。 最低限のセキュリティ・マネージャもない場合、リモート・クライアントはjavax.management.loading.MLet MBeanを作成し、それを使用して任意のURLから新しいMBeanを作成できます。 つまり、悪意のあるリモート・クライアントから、Javaアプリケーションに任意のコードを実行させることができるということです。
このような理由から、セキュリティの無効化は、開発時には許容される場合があっても、実稼動システムのセキュリティでは行わないことを強くお薦めします。
JConsoleによるリモート・モニタリング
セキュリティが有効でも無効でも、JConsoleを使用してアプリケーションをリモートでモニターできます。
JConsoleによるリモート・モニタリング(SSLが無効な場合)
SSLが無効な状態でリモート・アプリケーションをモニターするには、次のコマンドでJConsoleを起動します。
% jconsole hostName:portNum
ホスト名とポート番号を省略して、JConsoleが提供するダイアログ・ボックスに入力することもできます。
JConsoleによるリモート・モニタリング(SSLが有効な場合)
SSLが有効な状態でリモート・アプリケーションをモニターするには、JConsoleが稼動しているシステムでトラスト・ストアを設定し、SSLを正しく構成する必要があります。 たとえば、「JSSEガイド」の手順に従ってキーストアを作成し、次のコマンドでアプリケーション(この例ではServer)を起動します。
% java -Djavax.net.ssl.keyStore=keystore \ -Djavax.net.ssl.keyStorePassword=password Server
キーストアを作成して、上記のServerが起動したら、次のようにJConsoleを起動する必要があります。
% jconsole -J-Djavax.net.ssl.trustStore=truststore \ -J-Djavax.net.ssl.trustStorePassword=trustword
上記の構成により認証されるのは、サーバーだけです。 クライアントSSL認証が設定されている場合、同様のキーストアをJConsoleのキーに渡し、該当するトラスト・ストアをアプリケーションに渡す必要があります。
詳細は、「JSSEガイド」の「デフォルトのキーとトラスト・ストア、ストア型、およびストア・パスワードのカスタマイズ」を参照してください。
JConsoleの使用の詳細は、第 3章「JConsoleの使用」を参照してください。
パスワードとアクセス・ファイルの使用
パスワードおよびアクセス・ファイルは、リモート・モニタリングおよび管理のセキュリティを制御します。 これらのファイルは、デフォルトではJRE_HOME/lib/managementにあり、標準のJavaプロパティ・ファイル・フォーマットです。 フォーマットに関する詳細は、java.util.Propertiesパッケージの「APIリファレンス」を参照してください。
パスワード・ファイル
パスワード・ファイルは、各種ロールとそのパスワードを定義します。 アクセス制御ファイル(デフォルトでは、jmxremote.access)は、ロールごとに許可するアクセス権を定義します。 ロールを機能させるには、パスワードとアクセス・ファイルの両方にエントリを持つ必要があります。
JRE実装には、jmxremote.password.templateというパスワード・ファイル・テンプレートがあります。 このファイルをJRE_HOME/lib/management/jmxremote.passwordまたはホーム・ディレクトリにコピーして、アクセス・ファイルで定義したロールのパスワードを追加します。
パスワード・ファイルにはパスワードがクリアテキストで含まれるため、必ず所有者だけがこのファイルへの読み取りおよび書込みアクセス権を持つようにしてください。 セキュリティ上の理由から、システムは所有者だけがファイルを読取り可能であるか確認し、そうでない場合はエラーとして終了します。 このため、マルチユーザー環境では、パスワード・ファイルをホーム・ディレクトリなどの非公開の場所に保存する必要があります。
プロパティ名はロールで、関連付けられた値はロールのパスワードです。 たとえば、パスワード・ファイルのエントリの例は次のようになります。
例 2-1パスワード・ファイルの例# specify actual password instead of the text password monitorRole password controlRole password
Solaris、LinuxまたはMac OS Xオペレーティング・システムで、パスワード・ファイルのファイル・アクセス権を設定するには、次のコマンドを実行します。
chmod 600 jmxremote.password
Windowsプラットフォームでファイル・アクセス権を設定する手順については、付録A 「Microsoft Windows用のセキュリティ情報の詳細」を参照してください。
アクセス・ファイル
デフォルトでは、アクセス・ファイルはjmxremote.accessという名前です。 プロパティ名はパスワード・ファイルと同じ領域のIDです。 関連する値はreadonlyまたはreadwriteのいずれかにする必要があります。
アクセス・ファイルはロールとそのアクセス・レベルを定義します。 デフォルトでは、アクセス・ファイルは次の2つの主要なロールを定義します。
-
monitorRole、モニタリングのための読取り専用アクセスを許可します。
-
controlRole、モニタリングおよび管理のために読み取りおよび書込みアクセスを許可します。
アクセス制御エントリは、ロール名と関連するアクセス・レベルで構成されています。 ロール名には、スペースやタブを含めることはできず、パスワード・ファイル内のエントリに対応している必要があります。 アクセス・レベルは次のいずれかです。
-
readonly、MBeanの属性の読取りアクセスを許可します。 これは、モニタリングの場合、このロールのリモート・クライアントから測定値を読み取ることはできるが、実行中のプログラムの環境を変更するアクションは実行できないという意味です。 リモート・クライアントはMBeanの通知を待機することもできます。
-
readwrite、MBeanの属性の読み取りおよび書込みアクセス、MBeanの属性への操作の呼び出し、MBeanの属性の作成または削除を許可します。 アプリケーションの操作を妨げる可能性があるため、このアクセス権は信頼できるクライアントのみに許可する必要があります。
ロールは、アクセス・ファイル内で1つのエントリだけを持つ必要があります。 ロールにエントリがない場合、アクセス権はありません。 ロールに複数のエントリがある場合、最後のエントリが優先されます。 アクセス・ファイルの事前定義された一般的なロールには、次のようなものがあります。
例 2-2アクセス・ファイルの例# The "monitorRole" role has readonly access. # The "controlRole" role has readwrite access. monitorRole readonly controlRole readwrite
アウトオブボックスのモニタリングおよび管理のプロパティ
アウトオブボックスのモニタリングおよび管理のプロパティは、構成ファイルまたはコマンド行で設定できます。 コマンド行で指定したプロパティにより、構成ファイル内のプロパティをオーバーライドします。 構成ファイルのデフォルトの場所は、JRE_HOME/lib/management/management.propertiesです。 com.sun.management.jmxremoteまたはcom.sun.management.jmxremote.portのいずれかのコマンド行プロパティが設定されている場合、Java VMはこのファイルを読み取ります。 SNMP (Simple Network Management Protocol)による管理では、同じ構成ファイルを使用します。 SNMPのモニタリングに関する詳細は、第 5章「SNMPモニタリングと管理」を参照してください。
次のコマンド行オプションで、構成ファイルの別の位置を指定できます。
com.sun.management.config.file=ConfigFilePath
上のプロパティでは、ConfigFilePathが構成ファイルへのパスです。
表 2-1は、すべてのアウトオブボックスのモニタリングおよび管理プロパティを示しています。
プロパティ | 説明 | 値 |
---|---|---|
com.sun.management.jmxremote |
JConsoleで使用される非公開インタフェース上に公開されたJMXコネクタと、Attach APIを使用するほかのローカルのJMXクライアントから、JMXリモート・エージェントおよびローカル・モニタリングを有効にします。 JConsoleでこのコネクタを使用できるのは、エージェントを起動したときと同じユーザーがJConsoleを起動した場合です。 このコネクタ経由の要求については、パスワードやアクセス・ファイルはチェックされません。 |
true/false。 デフォルトはtrueです。 |
com.sun.management.jmxremote. port |
JMXリモート・エージェントを有効にして、リモートJMXコネクタを作成し、指定したポートで待機します。 デフォルトでは、SSL、パスワード、およびアクセス・ファイル・プロパティがこのコネクタに使用されます。 また、com.sun.management.jmxremoteプロパティで説明したローカル・モニタリングも有効にします。 |
ポート番号。 デフォルトは存在しない。 |
com.sun.management.jmxremote. registry.ssl |
SSLで保護されたRMIレジストリにRMIコネクタ・スタブをバインドします。 |
true/false。 デフォルトはfalseです。 |
com.sun.management.jmxremote. ssl |
SSL経由でセキュアなモニタリングを可能にします。 falseの場合、SSLは使用されません。 |
true/false。 デフォルトはtrueです。 |
com.sun.management.jmxremote. ssl.enabled.protocols |
有効にするSSL/TLSプロトコル・バージョンのカンマ区切りのリスト。 com.sun.management.jmxremote.sslと組み合わせて使用します。 |
デフォルトのSSL/TLSプロトコル・バージョン。 |
com.sun.management.jmxremote. ssl.enabled.cipher.suites |
有効にするSSL/TLS暗号化方式群のカンマ区切りのリスト。 com.sun.management.jmxremote.sslと組み合わせて使用します。 |
デフォルトのSSL/TLS暗号化方式。 |
com.sun.management.jmxremote. ssl.need.client.auth |
このプロパティがtrueでプロパティcom.sun.management.jmxremote.sslもtrueの場合、クライアント認証が実行されます。 このプロパティはtrueに設定することをお薦めします。 |
true/false。 デフォルトはfalseです。 |
com.sun.management.jmxremote. authenticate |
このプロパティがfalseの場合、JMXではパスワードもアクセス・ファイルも使用しません。すべてのユーザーがすべてのアクセスを許可されます。 |
true/false。 デフォルトはtrueです。 |
com.sun.management.jmxremote. password.file |
パスワード・ファイルの場所を指定します。 com.sun.management.jmxremote.authenticateがfalseの場合、このプロパティとパスワードおよびアクセス・ファイルは無視されます。 それ以外の場合は、パスワード・ファイルが存在し、有効な形式である必要があります。 パスワード・ファイルが空であるか存在しない場合、アクセスは許可されません。 |
JRE_HOME/lib/management/ jmxremote.password |
com.sun.management.jmxremote. access.file |
アクセス・ファイルの場所を指定します。 com.sun.management.jmxremote.authenticateがfalseの場合、このプロパティとパスワードおよびアクセス・ファイルは無視されます。 それ以外の場合は、アクセス・ファイルが存在し、有効な形式である必要があります。 アクセス・ファイルが空であるか存在しない場合、アクセスは許可されません。 |
JRE_HOME/lib/management/ jmxremote.access |
JMXエージェントがユーザーを認証する場合に使用するJAAS (Java認証・承認サービス)ログイン構成エントリの名前を指定します。 このプロパティを使用してデフォルトのログイン構成をオーバーライドする場合は、指定された構成エントリがJAASでロードされたファイルに存在する必要があります。 また、構成で指定されたログイン・モジュールは、名前とパスワードのコールバックを使用してユーザーの資格を取得する必要があります。 詳細は、javax.security.auth.callback.NameCallbackおよびjavax.security.auth.callback.PasswordCallbackのAPIドキュメントを参照してください。 |
デフォルトのログイン構成は、ファイルベースのパスワード認証です。 |
構成エラー
MBeanサーバー、RMIレジストリ、またはコネクタの起動中にエラーが発生した場合、Java VMは例外をスローして終了します。 構成エラーには、次のようなものがあります。
-
ポート番号に対するバインドの失敗。
-
無効なパスワード・ファイル。
-
無効なアクセス・ファイル。
-
パスワード・ファイルが所有者以外のユーザーから読取り可能になっている。
アプリケーションでセキュリティ・マネージャを実行する場合、セキュリティ・アクセス権ファイルに追加のアクセス権を登録する必要があります。
プログラムによるJMXエージェントへの接続
JMXエージェントを有効にしたら、クライアントから次のURLを使用してモニタリング・サービスにアクセスできます。
service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi
クライアントがエージェントのコネクタを作成するには、例 2-3のように、URLを使用してjavax.management.remote.JMXServiceURLオブジェクトをインスタンス化したあと、JMXConnectorFactory.connectメソッドを使用して接続を作成します。
例 2-3 JMXConnectorFactory.connectを使用した接続の作成JMXServiceURL u = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://" + hostName + ":" + portNum + "/jmxrmi"); JMXConnector c = JMXConnectorFactory.connect(u);
プログラムによるモニタリングおよび管理の設定
前述のように、Java SEプラットフォームのバージョン6では、Attach APIを使用するJMXクライアントを作成できます。これによってJava SE 6プラットフォームで起動する任意のアプリケーションから、起動時にモニター用にアプリケーションを構成しなくても、アウトオブボックスのモニタリングおよび管理ができるようになります。 Attach APIは、ツールによってターゲット・アプリケーションのエージェントに接続し、それらのエージェントを起動します。 エージェントが起動すれば、JMXクライアント(や他のツール)は、そのエージェントに代わってJava VMが保持するプロパティ・リストから、そのエージェントのJMXコネクタ・アドレスを取得できます。 このリストに含まれるプロパティは、Attach APIを使用するツールからアクセスできます。 したがって、アプリケーションから起動したエージェントが構成情報を示すプロパティを生成した場合、その構成情報はアプリケーションに接続するツールから利用できます。
JMXエージェントは、ローカルのJMXコネクタ・サーバーのアドレスからプロパティを生成します。 これによって、JMXツールは、起動中のエージェントのコネクタ・アドレスを取得し、これに接続できます。
例 2-4に示すコードをJMXツールで使用すれば、ターゲットVMに接続し、JMXエージェントのコネクタ・アドレスを取得し、これに接続することができます。
例 2-4 JMXツールのコネクタへの接続とエージェントのアドレスの取得static final String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress"; // attach to the target application VirtualMachine vm = VirtualMachine.attach(id); // get the connector address String connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); // no connector address, so we start the JMX agent if (connectorAddress == null) { String agent = vm.getSystemProperties().getProperty("java.home") + File.separator + "lib" + File.separator + "management-agent.jar"; vm.loadAgent(agent); // agent is started, get the connector address connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); } // establish connection to connector server JMXServiceURL url = new JMXServiceURL(connectorAddress); JMXConnector = JMXConnectorFactory.connect(url);
例 2-4は、com.sun.tools.attach.VirtualMachineクラスのattach()メソッドを使用して、指定されたJava VMに接続することにより、ターゲットJava VMが稼動中のエージェントに代わって保持するプロパティを、指定されたJava VMで読み取ることができるようになっています。 エージェントがすでに実行中の場合は、VirtualMachineクラスのgetAgentProperties()メソッドを呼び出し、そのエージェントのアドレスを取得します。 ローカルのコネクタ・アドレスcom.sun.management.jmxremote.localConnectorAddressの場合、getAgentProperties()メソッドは文字列プロパティを返します。これを使用すれば、ローカルのJMXエージェントに接続できます。
実行中のエージェントがない場合、JRE_HOME/lib/management-agent.jarからいずれかのエージェントがVirtualMachineによってロードされます。そのコネクタ・アドレスはgetAgentProperties()によって取得されます。
次に、エージェントへの接続を確立するには、このコネクタ・アドレスから構築されたJMXサービスURLのJMXConnectorFactory.connectを呼び出します。
JMXリモートAPIを使用したアウトオブボックスの管理の模倣
前述のように、アウトオブボックスの管理エージェントへのリモート・アクセスは、認証と承認、およびSSL暗号化によって保護されており、あらゆる構成は、システム・プロパティの設定またはmanagement.propertiesファイルの定義によって行われます。 ほとんどの場合、アウトオブボックスの管理エージェントを使用し、これをmanagement.propertiesファイルで構成すれば、リモートJava VMの管理は十分にセキュアです。 ただし、さらに高いレベルのセキュリティが必要な場合もあれば、システム構成によってはmanagement.propertiesファイルを使用できない場合もあります。 このような場合には、ファイアウォールを通過できるようにRMIサーバーのリモート・オブジェクトを特定のポートにエクスポートすること、あるいはマルチホーム・システムで特定のネットワーク・インタフェースを使用してRMIサーバーのリモート・オブジェクトをエクスポートすることもあります。 このような場合、JMXリモートAPIを使用して直接プログラムから管理エージェントの作成、構成、配備を行うことで、アウトオブボックスの管理エージェントの動作を模倣できます。
アウトオブボックスの管理の模倣の例
このセクションでは、アウトオブボックスの管理エージェントをまったく同じものとして模倣するJMXエージェントの実装方法を例示します。 アウトオブボックスの管理エージェントとまったく同様に、例 2-5で作成されたエージェントはポート3000で動作し、password.propertiesというパスワード・ファイルとaccess.propertiesというアクセス・ファイルを持ち、SSL/TLSベースのRMIソケット・ファクトリのデフォルトの構成を実装し、サーバー認証だけを必要とします。 この例は、「SSLの使用」で説明しているように、keystoreがすでに作成されていることが前提です。 SSL構成の設定方法に関する情報は、「JSSEリファレンス・ガイド」に記載されています。
前記のように構成されたアウトオブボックスのJMXエージェントを使用してcom.example.MyAppというアプリケーションのモニタリングと管理を有効にするには、次のコマンドでcom.example.MyAppを実行します。
% java -Dcom.sun.management.jmxremote.port=3000 \ -Dcom.sun.management.jmxremote.password.file=password.properties \ -Dcom.sun.management.jmxremote.access.file=access.properties \ -Djavax.net.ssl.keyStore=keystore \ -Djavax.net.ssl.keyStorePassword=password \ com.example.MyApp
ノート - com.sun.management.jmxremote.*プロパティは、コマンド行で渡す代わりにmanagement.propertiesファイルで指定することもできます。 その場合は、システム・プロパティ-Dcom.sun.management.config.file=management.propertiesで、management.propertiesファイルの場所を指定する必要があります。
例 2-5は、com.example.MyAppで前記のコマンドを使用した場合とまったく同じモニタリングおよび管理ができるJMXエージェントをプログラムによって作成する場合に、記述が必要なコードを示しています。
例 2-5プログラムによるアウトオブボックスのJMXエージェントの模倣package com.example; import java.lang.management.*; import java.rmi.registry.*; import java.util.*; import javax.management.*; import javax.management.remote.*; import javax.management.remote.rmi.*; import javax.rmi.ssl.*; public class MyApp { public static void main(String[] args) throws Exception { // Ensure cryptographically strong random number generator used // to choose the object number - see java.rmi.server.ObjID // System.setProperty("java.rmi.server.randomIDs", "true"); // Start an RMI registry on port 3000. // System.out.println("Create RMI registry on port 3000"); LocateRegistry.createRegistry(3000); // Retrieve the PlatformMBeanServer. // System.out.println("Get the platform's MBean server"); MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // Environment map. // System.out.println("Initialize the environment map"); HashMap<String,Object> env = new HashMap<String,Object>(); // Provide SSL-based RMI socket factories. // // The protocol and cipher suites to be enabled will be the ones // defined by the default JSSE implementation and only server // authentication will be required. // SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory(); SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory(); env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf); env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf); // Provide the password file used by the connector server to // perform user authentication. The password file is a properties // based text file specifying username/password pairs. // env.put("jmx.remote.x.password.file", "password.properties"); // Provide the access level file used by the connector server to // perform user authorization. The access level file is a properties // based text file specifying username/access level pairs where // access level is either "readonly" or "readwrite" access to the // MBeanServer operations. // env.put("jmx.remote.x.access.file", "access.properties"); // Create an RMI connector server. // // As specified in the JMXServiceURL the RMIServer stub will be // registered in the RMI registry running in the local host on // port 3000 with the name "jmxrmi". This is the same name the // out-of-the-box management agent uses to register the RMIServer // stub too. // System.out.println("Create an RMI connector server"); JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:3000/jmxrmi"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); // Start the RMI connector server. // System.out.println("Start the RMI connector server"); cs.start(); } }
次のコマンドでこのアプリケーションを起動します。
java -Djavax.net.ssl.keyStore=keystore \ -Djavax.net.ssl.keyStorePassword=password \ com.example.MyApp
com.example.MyAppアプリケーションにより、JMXエージェントが有効になり、Javaプラットフォームのアウトオブボックスの管理エージェントを使用した場合とまったく同様にモニタリングと管理ができるようになります。 ただし、アウトオブボックスの管理エージェントで使用するRMIレジストリとそれを模倣した管理エージェントで使用するRMIレジストリとでは、わずかながら重要な違いが1つあります。 アウトオブボックスの管理エージェントで使用するRMIレジストリは読取り専用です。つまり、これにバインドできるのは単一のエントリであり、一度バインドされたエントリはもうアンバインドできません。 これは例 2-5で作成されたRMIレジストリには当てはまりません。
そのほか、どちらのRMIレジストリも、SSL/TLSを使用しないため、セキュアではありません。 RMIレジストリは、クライアント認証を必要とするSSL/TLSベースのRMIソケット・ファクトリを使用して作成するべきです。 そうすれば、クライアントの資格が悪意のあるRMIサーバーに送信されることはなく、RMIレジストリが信頼できないクライアントにRMIサーバー・スタブへのアクセスを許すこともありません。
SSL/TLS RMIソケット・ファクトリを実装するRMIレジストリは、management.propertiesファイルに次のプロパティを追加することで作成できます。
com.sun.management.jmxremote.registry.ssl=true com.sun.management.jmxremote.ssl.need.client.auth=true
例 2-5では、アウトオブボックスのJMXエージェントの主な動作を模倣していますが、management.propertiesファイルにある既存のプロパティのすべてを複製しているわけではありません。 ただし、com.example.MyAppを適切に変更すれば、ほかのプロパティを追加できます。
ファイアウォールを介したアプリケーションのモニタリング
前述のように、例 2-5のコードを使用すればファイアウォールを介してアプリケーションのモニターができますが、アウトオブボックスのモニタリング・ソリューションではこれができない場合もあります。 com.sun.management.jmxremote.port管理プロパティによりRMI Registryが接続可能なポートが指定されますが、RMIServerおよびRMIConnectionリモート・オブジェクトがエクスポートされるポートは、RMIスタックにより選択されます。 リモート・オブジェクト(RMIServerとRMIConnection)を指定されたポートにエクスポートするには、例 2-5のように、プログラムによってRMIコネクタ・サーバーを作成する必要があります。 ただし、JMXServiceURLは次のように指定する必要があります。
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://localhost:" + port1 + "/jndi/rmi://localhost:" + port2 + "/jmxrmi");
上記のURLの中のport1はRMIServerおよびRMIConnectionリモート・オブジェクトがエクスポートされるポート番号、port2はRMIレジストリのポート番号です。
エージェント・クラスを使用するアプリケーションの計測
Java SEプラットフォームは、Javaプログラミング言語エージェントによりJava VMで実行中のプログラムを計測するサービスを提供します。 インストゥルメンテーション・エージェントを作成すれば、アプリケーションをモニターする場合、そのアプリケーションに新しいコードを追加する必要がなくなります。 モニタリングと管理は、アプリケーションのstatic mainメソッドに実装するのではなく別のエージェント・クラスに実装し、-javaagentオプションを指定することでアプリケーションを起動します。 エージェント・クラスを作成してアプリケーションを計測する方法の詳細は、java.lang.instrumentパッケージのAPIリファレンス・ドキュメントを参照してください。
次の手順は、com.example.MyAppのコードを改変して、エージェントにモニタリングおよび管理用のほかのアプリケーションを計測させる方法を示しています。
アプリケーションを計測するエージェント・クラスの作成
- com.example.MyAgentクラスを作成します。
com.example.MyAgentというクラスを作成し、mainメソッドではなくpremainメソッドを宣言します。
package com.example; [...] public class MyAgent { public static void premain(String args) throws Exception { [...]
com.example.MyAgentクラスの残りのコードは、例 2-5に示したcom.example.MyAppクラスとまったく同じでも構いません。
- com.example.MyAgentクラスをコンパイルします。
- Premain-Classエントリを使用して、マニフェスト・ファイルMANIFEST.MFを作成します。
エージェントはJavaアーカイブ(JAR)ファイルとして配備されます。 JARファイルに含まれるマニフェストの属性は、エージェントを起動するためにロードされるエージェント・クラスを指定します。 MANIFEST.MFというファイルを作成し、次の行を挿入します。
Premain-Class: com.example.MyAgent
- JARファイルMyAgent.jarを作成します。
JARファイルには必ず次のファイルを入れます。
-
META-INF/MANIFEST.MF
-
com/example/MyAgent.class
-
- アプリケーションを起動し、モニタリングおよび管理サービスを提供するエージェントを指定します。
com.example.MyAgentを使用すれば、モニタリングおよび管理用のアプリケーションを計測できます。 次の例では、アプリケーションとしてNotepadを使用します。
% java -javaagent:MyAgent.jar -Djavax.net.ssl.keyStore=keystore \ -Djavax.net.ssl.keyStorePassword=password -jar Notepad.jar
Notepadを起動するとき、-javaagentオプションを使用して、com.example.MyAgentエージェントを指定します。 また、com.example.MyAgentアプリケーションが例 2-5のcom.example.MyAppアプリケーションと同じコードを複製する場合、RMIコネクタ・サーバーはSSLで保護されているため、keystoreとpasswordが必要になります。