| 目次|前|次 | Java Management Extensions (JMX)テクノロジのチュートリアル |
この章では、JMXテクノロジのセキュリティ機能の設定方法の例を、次のセクション内で説明します。
注意:
JMXテクノロジを使用して実装できるもっとも簡単なセキュリティは、暗号化、ユーザー名とユーザー・パスワードの認証、およびファイル・アクセス制御に基づくものです。
簡単なセキュリティを使用したRMIコネクタの例は、ディレクトリwork_dir/jmx_examples/Security/simple内にあります。
/jmx_examples/Security/simpleディレクトリを開きます。
このディレクトリ内に、次のディレクトリがあります。
/server、ファイルServer.javaを格納しています/config、セキュリティ構成ファイルを格納しています。access.propertieskeystorepassword.propertiestruststore/mbeans、次のファイルを格納しています。SimpleStandardMBean.javaSimpleStandard.java/client、次のファイルを格納しています。Client.javaClientListener.java*.javaと*.propertiesのすべてのファイルを開きます
これらのファイルについて、以降セクションで分析します。
Server.javaクラスをコード例5-1に示します。
public class Server { public static void main(String[] args) { try { MBeanServer mbs = MBeanServerFactory.createMBeanServer(); HashMap env = new HashMap(); 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); env.put("jmx.remote.x.password.file", "config" + File.separator + "password.properties"); env.put("jmx.remote.x.access.file", "config" + File.separator + "access.properties"); JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); cs.start(); } catch (Exception e) { e.printStackTrace(); } } }
コード例5-1に示すServerクラスは、MBeanサーバーmbsを作成し、環境マップenvにセキュリティ保護されたRMIクライアント・ソケット・ファクトリcsf、セキュリティ保護されたRMIサーバー・ソケット・ファクトリssf、およびプロパティ・ファイルpassword.propertiesとaccess.propertiesを渡します。
プロパティ・ファイルpassword.propertiesには、ユーザー名とパスワードが含まれ、JMXリモートAPIインタフェースJMXAuthenticatorを使用してアクセスします。 プロパティjmx.remote.x.password.fileを使用することは、パスワードベースのJMXAuthenticatorを作成し、これをjmx.remote.authenticatorプロパティを通じて環境マップに渡すのと同じ意味を持ちます。
プロパティ・ファイルaccess.propertiesには、ユーザー名と一定レベルのアクセス権、readwriteとreadonlyのいずれかが含まれます。 これはアクティブなユーザーが、MBeanサーバー操作にどのレベルでアクセスできるかを表します。 このファイルベースのアクセス制御は、アクセス・コントローラMBeanサーバー内に実際のMBeanサーバーをラップする、JMXテクノロジのインタフェースMBeanServerForwarderを使用して実装されます。 アクセス・コントローラMBeanサーバーは、適切なチェックを実行したあとに、実際のMBeanサーバーに要求を転送します。
ServerはRMIコネクタ用にJMXサービスURL、urlを作成します。このRMIコネクタはデフォルトのJRMPトランスポート上で動作し、ローカル・ホストのポート9999のRMIレジストリにRMIコネクタ・スタブを登録します。
MBeanサーバーmbs、環境マップenv、およびサービスURL urlはすべてJMXConnectorServerに渡され、セキュアなJMXコネクタ・サーバーcsが新規に作成されます。
SimpleStandardMBeanクラスは、第3章「JMXコネクタ」で使用されたものと同じ簡単なMBeanインタフェースを定義します。
SimpleStandardクラスは、第3章「JMXコネクタ」で使用されたものと同じ簡単なMBeanを定義します。
ClientListenerクラスは、第3章「JMXコネクタ」で使用されたものと同じ簡単な通知リスナーを定義します。
Client.javaクラスをコード例5-1に示します。
public class Client { public static void main(String[] args) { try { HashMap env = new HashMap(); String[] credentials = new String[] { "username" , "password" }; env.put("jmx.remote.credentials", credentials); JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnector jmxc = JMXConnectorFactory.connect(url, env); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); String domains[] = mbsc.getDomains(); for (int i = 0; i < domains.length; i++) { System.out.println("Domain[" + i + "] = " + domains[i]); } ObjectName mbeanName = new ObjectName("MBeans:type=SimpleStandard"); mbsc.createMBean("SimpleStandard", mbeanName, null, null); // Perform MBean operations [...] mbsc.removeNotificationListener(mbeanName, listener); mbsc.unregisterMBean(mbeanName); jmxc.close(); } catch (Exception e) { e.printStackTrace(); } } }
コード例5-1に示すClientクラスは、環境マップenvにServerが求める資格セット、つまりusernameやpasswordを渡します。 これらの資格は、コネクタ・スタブのサービスURLと環境マップがJMXConnectorFactory.connect()に渡されるときに、JMXConnectorのインスタンスjmxcに付与されます。 Clientはjmxcを通じて、Server側で起動されたMBeanに接続し、MBeanの操作を実行します。
接続が確立すると、環境マップenvで付与された資格はサーバーに送信されます。 サーバーは次に、JMXAuthenticatorインタフェースのauthenticate()メソッドを呼び出し、クライアント資格をパラメータとして渡します。 authenticate()メソッドは、クライアントを認証し、アクセス制御の確認に使用されるプリンシパルのセットを含む被認証者を返します。
簡単なセキュリティを使用したRMIコネクタの例題を実行するには、次のステップを実行します。
RMIコネクタの例題を実行します:
$ javac mbeans/SimpleStandard.java \ mbeans/SimpleStandardMBean.java \ server/Server.java \ client/Client.java \ client/ClientListener.java
$ export CLASSPATH=server ; rmiregistry 9999 &
Serverを起動します。
$ java -classpath server:mbeans \
-Djavax.net.ssl.keyStore=config/keystore \
-Djavax.net.ssl.keyStorePassword=password \
Server &
MBeanサーバーとRMIコネクタの作成の確認が表示されます。
Clientを起動します。
$java -classpath client:server:mbeans \
-Djavax.net.ssl.trustStore=config/truststore \
-Djavax.net.ssl.trustStorePassword=trustword \
Client
コネクタ・クライアントと各種のMBean操作の作成、および作成後の接続の終了の確認が表示されます。
この例からわかるように、すべての処理が、第3章「JMXコネクタ」で示す基本的なRMIコネクタの例とまったく同じ方法で進められているように見えます。 ただし、password.propertiesを開きパスワードを変更する場合、Clientを起動するとjava.lang.SecurityExceptionが表示され、接続に失敗します。
実装において接続のクライアント側が、セクション「簡単なセキュリティ」で示したセキュリティ・メカニズムを使用して、複数のユーザーまたはアプリケーションに代わって異なる操作を実行する場合、各ユーザーが操作を実行するたびにセキュアな接続を確立しなければなりません。 コネクタ・クライアントが多くのユーザーと対話することが予測される場合、主体委譲を実装してシステムの負荷を減らすことができます。 主体委譲を実装すると、ユーザーごとに1つのセキュアな接続が確立され、この接続を使用すると、任意の数のユーザーに代わって関連する操作を実行できます。 接続自体は認証されたユーザーによって設定されます。 別のユーザーに代わって動作することを許可するSubjectDelegationPermissionが認証ユーザーに付与されている場合、そのユーザーに代わって、接続を使った操作を実行できます。
主体委譲を実装するセキュアなRMIコネクタの例は、ディレクトリwork_dir/jmx_examples/Security/subject_delegation内にあります。
/jmx_examples/Security/subject_delegationディレクトリを開きます。
このディレクトリ内に、次のディレクトリがあります。
/server、次のファイルを格納しています: Server.java:/config、セキュリティ構成ファイルを格納しています。access.propertiesjava.policypassword.properties/mbeans、次のファイルを格納しています。SimpleStandardMBean.javaSimpleStandard.java/client、次のファイルを格納しています。Client.javaClientListener.java*.javaと*.propertiesのすべてのファイルを開きます
これらのファイルについて、以降セクションで分析します。
Server.javaクラスをコード例5-1に示します。
public class Server { public static void main(String[] args) { try { MBeanServer mbs = MBeanServerFactory.createMBeanServer(); HashMap env = new HashMap(); env.put("jmx.remote.x.password.file", "config" + File.separator + "password.properties"); env.put("jmx.remote.x.access.file", "config" + File.separator + "access.properties"); JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); cs.start(); } catch (Exception e) { e.printStackTrace(); } } }
コード例5-1は、MBeanサーバーmbsの作成から始まります。環境マップenvには、password.propertiesというパスワード・ファイルとaccess.propertiesというアクセス・ファイルが格納されます。
次にServerはコネクタ・サーバーcsを作成し、前述のRMIコネクタの例題とまったく同じ方法でコネクタ・サーバーを起動します。
java.policyファイルはusernameにSubjectDelegationPermissionを付与し、このユーザーがClientで作成されたJMXPrincipalのインスタンスである、ユーザーdelegateの代わりに操作を実行することを許可します。 java.policyファイルが要求されるのは、Serverクラスの起動時です。
SimpleStandardMBeanクラスは、前出の例で使用されたのと同じ簡単なMBeanインタフェースを定義します。
SimpleStandardクラスは、前出の例で使用されたのと同じ簡単なMBeanを定義します。
ClientListenerクラスは、前出の例題で使用されたのと同じ簡単な通知リスナーを定義します。
Client.javaクラスをコード例5-1に示します。
public class Client { public static void main(String[] args) { try { HashMap env = new HashMap(); String[] credentials = new String[] { "username" , "password" }; env.put("jmx.remote.credentials", credentials); JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnector jmxc = JMXConnectorFactory.connect(url, env); Subject delegationSubject = new Subject(true, Collections.singleton(new JMXPrincipal("delegate")), Collections.EMPTY_SET, Collections.EMPTY_SET); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(delegationSubject); String domains[] = mbsc.getDomains(); ObjectName mbeanName = new ObjectName("MBeans:type=SimpleStandard"); mbsc.createMBean("SimpleStandard", mbeanName, null, null); // Perform MBean operations // [...] mbsc.removeNotificationListener(mbeanName, listener); mbsc.unregisterMBean(mbeanName); jmxc.close(); } catch (Exception e) { e.printStackTrace(); } } }
コード例5-1は、ユーザー名usernameとパスワードpasswordが格納された環境マップenvの作成から始まります。 これらの文字列は、Serverがコネクタ・サーバーにアクセスするユーザーを認証するために保持するpassword.propertiesファイルに保存されたユーザー名とパスワードに一致します。
JMXテクノロジのコネクタ・クライアントjmxcは、前述のRMIコネクタの例題と同じ方法で作成され、ユーザー名とパスワードは環境マップenvに渡されます。
次に、Clientは、JMXPrincipalのインスタンスであるdelegateという名前のPrincipalを使用して、SubjectのインスタンスdelegationSubjectを作成します。
MBeanサーバー接続mbscは、JMXConnectorのgetMBeanServerConnection()メソッドを呼び出し、パラメータとしてdelegationSubjectを渡して作成されます。 したがって、このMBeanサーバー接続を使用すると、delegationSubjectに保存されたプリンシパル、この例ではdelegateという名前のJMXPrincipalに代わって、リモートMBeanサーバー上で操作を実行できます。
この例題ではさらに、これまでの例とまったく同じ方法で、MBeanサーバーでSimpleStandard MBeanが作成および登録され、このMBean上で操作が実行されます。
主体委譲を使用したセキュアなRMIコネクタの例題を実行するには、次のステップを実行します。
$ javac mbeans/SimpleStandard.java \ mbeans/SimpleStandardMBean.java \ server/Server.java \ client/Client.java \ client/ClientListener.java
$ export CLASSPATH=server ; rmiregistry 9999 &
Serverを起動します。
$ java -classpath server:mbeans \ -Djava.security.policy=config/java.policy Server &
MBeanサーバーの作成、環境マップの初期化、RMIコネクタの作成、およびコネクタのMBeanサーバーへの登録の確認が表示されます。
Clientを起動します。
$java -classpath client:server:mbeans Client
コネクタ・クライアントの作成、主体委譲の作成、MBeanサーバーへの接続、およびさまざまなMBean操作、その後の接続の終了の確認が表示されます。
Java Authentication and Authorization Service (JAAS)とJava platform Standard Edition (Java SE)セキュリティ・アーキテクチャによってユーザー・アクセスを管理することで、より詳細なレベルのセキュリティをコネクタに実装できます。 JAASとJava SEセキュリティの基本は、セキュリティ・マネージャとポリシー・ファイルを使用して、ユーザーごとに異なるアクセス・レベルを指定することです。 最終的に、どのユーザーにどの操作の実行を許可するかをより正確に決定することができます。
このセクションの2つの例題は、セクション「簡単なセキュリティ」に示す例題と非常に似ていますが、異なる点として、簡単なファイルベースのアクセス制御が、ポリシー・ベースのアクセス制御に置き換えられています。
詳細なセキュリティを使用したRMIコネクタの例は、ディレクトリwork_dir/jmx_examples/Security/fine_grained内にあります。
/jmx_examples/Security/fine_grainedを開きます。
このディレクトリ内に、次のディレクトリがあります。
/server、ファイルServer.javaを格納しています/config、セキュリティ構成ファイルを格納しています。java.policykeystorepassword.propertiestruststore/mbeans、次のファイルを格納しています。SimpleStandard.javaSimpleStandardMBean.java/client、次のファイルを格納しています。ClientListener.javaClient.java*.javaと*.propertiesのすべてのファイルを開きます。 これらのファイルについて、以降のセクションで分析します。
この例題で使用されるServer.javaクラスは、簡単なセキュリティを使用したRMIコネクタで使用されるクラスに非常に似ています。 ただし、詳細なセキュリティの例題では、環境マップにマップされるaccess.propertiesファイルがありません。 それ以外は、両クラスは同一です。
java.policyファイルは、次の権限を付与します。
serverコード・ベースのすべての権限。これがあることで、コネクタ・サーバーはコネクタを作成し、リモート・ユーザーの呼出しで要求される操作を実行できるmbeansコード・ベースに対するMBeanTrustPermission。これによって、信頼されたMBeanをMBeanサーバーに登録できるJMXPrincipalで表されるユーザー、username.に対する、各種のMBean操作およびMBeanサーバー操作を実行する権限SimpleStandardMBeanクラスは、前出の例で使用されたのと同じ簡単なMBeanインタフェースを定義します。
SimpleStandardクラスは、前出の例で使用されたのと同じ簡単なMBeanを定義します。
ClientListenerクラスは、前出の例題で使用されたのと同じ簡単な通知リスナーを定義します。
Client.javaクラスは、簡単なセキュリティを使用したRMIコネクタの例題で使用されるクラスとまったく同じです。
詳細なセキュリティを使用したRMIコネクタの例題を実行するには、次のステップを実行します。
$ javac mbeans/SimpleStandard.java \ mbeans/SimpleStandardMBean.java \ server/Server.java \ client/Client.java \ client/ClientListener.java
$ export CLASSPATH=server ; rmiregistry 9999 &
Serverを起動します。
$ java -classpath server:mbeans \
-Djavax.net.ssl.keyStore=config/keystore \
-Djavax.net.ssl.keyStorePassword=password \
-Djava.security.manager \
-Djava.security.policy=config/java.policy \
Server &
環境マップの初期化、MBeanサーバーとRMIコネクタの作成の確認が表示されます。
Clientを起動します。
$ java -classpath client:server:mbeans \ -Djavax.net.ssl.trustStore=config/truststore \ -Djavax.net.ssl.trustStorePassword=trustword \ Client
コネクタ・クライアントの作成、RMIサーバーへの接続、各種のMBean操作、および接続の終了の確認が表示されます。