| 目次 | 前へ | 次へ | Java Management Extensions (JMX) テクノロジのチュートリアル |
この章では、JMX テクノロジのセキュリティー機能の設定方法の例を、次のセクション内で説明します。
注意:アプリケーションでは、ユーザーがパスワードをコマンド行に入力するのではなく、パスワードの入力をユーザーに求めるようにする必要があります。実稼動システムではセキュアな認証メカニズムを使用してください。
JMX テクノロジを使用して実装できるもっとも簡単なセキュリティーは、暗号化、ユーザー名とユーザーパスワードの認証、およびファイルアクセス制御に基づくものです。
簡単なセキュリティーを使用した RMI コネクタの例は、ディレクトリ work_dir/jmx_examples/Security/simple 内にあります。
/jmx_examples/Security/simple ディレクトリを開きます。
このディレクトリ内に、次のディレクトリがあります。
/server、次のファイルを格納しています:Server.java/config、セキュリティー構成ファイルを格納しています。/mbeans、次のファイルを格納しています。/client、次のファイルを格納しています。*.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 コネクタの例題を実行するには、次の手順を実行します。
$ javac mbeans/SimpleStandard.java \ mbeans/SimpleStandardMBean.java \ server/Server.java \ client/Client.java \ client/ClientListener.java
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、セキュリティー構成ファイルを格納しています。/mbeans、次のファイルを格納しています。/client、次のファイルを格納しています。*.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 を起動します。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、セキュリティー構成ファイルを格納しています。/mbeans、次のファイルを格納しています。/client、次のファイルを格納しています。*.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 操作、および接続の終了の確認が表示されます。