目次 | 前の項目 | 次の項目 Java Management Extensions (JMX) テクノロジのチュートリアル

第 5 章

セキュリティ

この章では、JMX テクノロジのセキュリティ機能の設定方法の例を、次のセクション内で説明します。

5.1 簡単なセキュリティ

JMX テクノロジを使用して実装できる最も簡単なセキュリティは、暗号化、ユーザ名とユーザパスワードの認証、およびファイルアクセス制御に基づくものです。

5.1.1 簡単なセキュリティを使用した RMI コネクタ

簡単なセキュリティを使用した RMI コネクタの例は、ディレクトリ work_dir/jmx_examples/Security/simple 内にあります。

  1. work_dir/jmx_examples/Security/simple ディレクトリを開きます。
  2. このディレクトリ内に、次のディレクトリがあります。

  3. テキストエディタで、*.java*.properties のすべてのファイルを開きます。
  4. これらのファイルについて、以降のセクションで分析します。

5.1.1.1 Server.java

Server.java クラスをコード 例 5-1 に示します。

コード 例 5-1 RMI コネクタの例題 (簡単なセキュリティ) クラス Server.java
 
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.propertiesaccess.properties を渡します。

プロパティファイル password.properties には、ユーザ名とパスワードが含まれ、JMX リモート API インタフェース JMXAuthenticator を使用してアクセスします。プロパティ jmx.remote.x.password.file を使用することは、パスワードベースの JMXAuthenticator を作成し、これを jmx.remote.authenticator プロパティを通じて環境マップに渡すのと同じ意味を持ちます。

プロパティファイル access.properties には、ユーザ名と一定レベルのアクセス権、readwritereadonly のいずれかが含まれます。これはアクティブなユーザが、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 が新規に作成されます。

5.1.1.2 SimpleStandardMBean.java

SimpleStandardMBean クラスは、「第 3 章 JMX コネクタ」で使用されたのと同じ簡単な MBean インタフェースを定義します。

5.1.1.3 SimpleStandard.java

SimpleStandard クラスは、「第 3 章 JMX コネクタ」で使用されたのと同じ簡単な MBean を定義します。

5.1.1.4 ClientListener.java

ClientListener クラスは、「第 3 章 JMX コネクタ」で使用されたのと同じ簡単な通知リスナを定義します。

5.1.1.5 Client.java

Client.java クラスをコード 例 5-2 に示します。

コード 例 5-2 RMI コネクタの例題 (簡単なセキュリティ) クラス Client.java
 
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-2 に示す Client クラスは、環境マップ envServer が求める一連の資格、usernamepassword などを渡します。これらの資格は、コネクタスタブのサービス URL と環境マップが JMXConnectorFactory.connect() に渡されるときに、JMXConnector のインスタンス jmxc に付与されます。Clientjmxc を通じて、Server 側で起動された MBean に接続し、MBean の操作を実行します。

接続が確立すると、環境マップ env で付与された資格はサーバに送信されます。サーバは次に、JMXAuthenticator インタフェースの authenticate() メソッドを呼び出し、クライアント資格をパラメータとして渡します。authenticate() メソッドは、クライアントを認証し、アクセス制御の確認に使用される主体セットを含む被認証者を返します。

5.1.2 簡単なセキュリティを使用した RMI コネクタの例題の実行

簡単なセキュリティを使用した RMI コネクタの例題を実行するには、次の手順を実行します。

  1. 例題のクラスをコンパイルします。
  2.  
    $ javac  mbeans/SimpleStandard.java \ 
      mbeans/SimpleStandardMBean.java \ 
      server/Server.java \ 
      client/Client.java \ 
      client/ClientListener.java 
     
    
  3. ローカルホストのポート 9999 で RMI レジストリを起動します。
  4.  
    $ export CLASSPATH=server ; rmiregistry 9999 & 
     
    
  5. Server を起動します。
  6.  
    $ java -classpath server:mbeans \ 
    -Djavax.net.ssl.keyStore=config/keystore \ 
    -Djavax.net.ssl.keyStorePassword=password \ 
    Server & 
    

    Mbean サーバと RMI コネクタの作成の確認が表示されます。

  7. Client を起動します。
  8.  
    $ 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 が表示され、接続に失敗します。

5.2 主体委譲

実装において接続のクライアント側が、「5.1 簡単なセキュリティ」で示したセキュリティ機構を使用して、複数のユーザまたはアプリケーションに代わって異なる操作を実行する必要がある場合、各ユーザはユーザが実行する操作ごとに安全な接続を確立する必要があります。コネクタクライアントが多くのユーザと対話することが予測される場合、「主体委譲」を実装してシステムの負荷を減らすことができます。主体委譲を実装すると、ユーザごとに 1 つの安全な接続が確立され、この接続を使用すると、任意の数のユーザに代わって関連する操作を実行できます。接続自体は「認証された」ユーザによって設定されます。別のユーザに代わって動作することを許可する SubjectDelegationPermission が認証ユーザに付与されている場合、そのユーザに代わって、接続を使った操作を実行できます。

5.2.1 主体委譲を使用した安全な RMI コネクタ

主体委譲を実装する安全な RMI コネクタの例は、ディレクトリ work_dir/jmx_examples/Security/subject_delegation 内にあります。

  1. work_dir/jmx_examples/Security/subject_delegation ディレクトリを開きます。
  2. このディレクトリ内に、次のディレクトリがあります。

    • /server。ファイル Server.java を収めています。
    • /config。セキュリティ設定ファイルを収めています。
      • access.properties
      • java.policy
      • password.properties
    • /mbeans。次のファイルを収めています。
      • SimpleStandardMBean.java
      • SimpleStandard.java
    • /client。次のファイルを収めています。
      • Client.java
      • ClientListener.java
  3. テキストエディタで、*.java*.properties のすべてのファイルを開きます。
  4. これらのファイルについて、以降の節で分析します。

5.2.1.1 Server.java

Server.java クラスをコード 例 5-3 に示します。

コード 例 5-3 安全な RMI コネクタ (主体委譲) 例題クラス Server.java
 
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-3 は MBean サーバ mbs の作成から始まり、次に環境マップ env にパスワードファイルとアクセスファイル、password.propertiesaccess.properties が格納されます。

  • パスワードファイルには、ユーザ名とパスワードの組み合わせが収められ、接続を試みるユーザの認証に使用される
  • アクセスファイルには、ユーザ名とアクセスレベルの組み合わせが含まれ、MBean サーバの MBean へのアクセスの認証に使用される。アクセスレベルは、読み書き可能か読み込み専用のいずれか

次に Server はコネクタサーバ cs を作成し、前述の RMI コネクタの例題とまったく同じ方法でコネクタサーバを起動します。

5.2.1.2 java.policy

java.policy ファイルは usernameSubjectDelegationPermission を付与し、このユーザが Client で作成された JMXPrincipal のインスタンスである、ユーザ delegate の代わりに操作を実行することを許可します。java.policy ファイルが要求されるのは、Server クラスの起動時です。

5.2.1.3 SimpleStandardMBean.java

SimpleStandardMBean クラスは、前出の例題で使用されたのと同じ簡単な MBean インタフェースを定義します。

5.2.1.4 SimpleStandard.java

SimpleStandard クラスは、前出の例題で使用されたのと同じ簡単な MBean を定義します。

5.2.1.5 ClientListener.java

ClientListener クラスは、前出の例題で使用されたのと同じ簡単な通知リスナを定義します。

5.2.1.6 Client.java

Client.java クラスをコード 例 5-4 に示します。

コード 例 5-4 安全な RMI コネクタ (主体委譲) 例題クラス Client.java
 
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-4 は環境マップ env の作成から始まり、このマップにはユーザ名 username とパスワード password が生成されます。これらの文字列は、Server がコネクタサーバにアクセスするユーザを認証するために保持する password.properties ファイルに保存されたユーザ名とパスワードに一致します。

JMX テクノロジのコネクタクライアント jmxc は、前述の RMI コネクタの例題と同じ方法で作成され、ユーザ名とパスワードは環境マップ env に渡されます。

次に、Client は、JMXPrincipal のインスタンスである delegate という名前の Principal を使用して、Subject のインスタンス delegationSubject を作成します。

MBean サーバ接続 mbsc は、JMXConnectorgetMBeanServerConnection() メソッドを呼び出し、パラメータとして delegationSubject を渡して作成されます。したがって、この MBean サーバ接続を使用すると、delegationSubject に保存された主体、この例では delegate という名前の JMXPrincipal に代わって、リモート MBean サーバ上で操作を実行できます。

この例題ではさらに、これまでの例とまったく同じ方法で、MBean サーバで SimpleStandard MBean が作成および登録され、この MBean 上で操作が実行されます。

5.2.2 主体委譲を使用した安全な RMI コネクタの例題の実行

主体委譲を使用した安全な RMI コネクタの例題を実行するには、次の手順を実行します。

  1. 例題のクラスをコンパイルします。
  2. $ javac  mbeans/SimpleStandard.java \ 
      mbeans/SimpleStandardMBean.java \ 
      server/Server.java \ 
      client/Client.java \ 
      client/ClientListener.java 
     
    
  3. ローカルホストのポート 9999 で RMI レジストリを起動します。
  4. $ export CLASSPATH=server ; rmiregistry 9999 &

  5. Server を起動します。
  6. $ java -classpath server:mbeans \ 
      -Djava.security.policy=config/java.policy Server & 
     
    

    MBean サーバの作成、環境マップの初期化、RMI コネクタの作成、およびコネクタの MBean サーバへの登録の確認が表示されます。

  7. Client を起動します。
  8. $ java -classpath client:server:mbeans Client

    コネクタクライアントの作成、主体委譲の作成、MBean サーバへの接続、およびさまざまな MBean 操作、その後の接続の終了の確認が表示されます。

5.3 詳細なセキュリティ

Java Authentication and Authorization Service (JAAS) と Java 2 platform Standard Edition (J2SE) セキュリティアーキテクチャを通じてユーザアクセスを管理することで、コネクタにより詳細なレベルのセキュリティを実装できます。JAAS と J2SE セキュリティの基本は、セキュリティマネージャとポリシーファイルを使用して、ユーザごとに異なるレベルのアクセスを割り振ることです。最終的に、どのユーザにどの操作の実行を許可するかをより正確に決定することができます。

この節の 2 つの例題は、「5.1 簡単なセキュリティ」に示す例題と非常に似ていますが、簡単なファイルベースのアクセス制御が、ポリシーベースのアクセス制御に置き換えられています。

5.3.1 詳細なセキュリティを使用した RMI コネクタ

詳細なセキュリティを使用した RMI コネクタの例は、ディレクトリ work_dir/jmx_examples/Security/fine_grained 内にあります。

  1. work_dir/jmx_examples/Security/fine_grained を開きます。
  2. このディレクトリ内に、次のディレクトリがあります。

    • /server。ファイル Server.java を収めています。
    • /config。セキュリティ設定ファイルを収めています。
      • java.policy
      • keystore
      • password.properties
      • truststore
    • /mbeans。次のファイルを収めています。
      • SimpleStandard.java
      • SimpleStandardMBean.java
    • /client。次のファイルを収めています。
      • ClientListener.java
      • Client.java
  3. テキストエディタで、*.java*.properties のすべてのファイルを開きます。
  4. これらのファイルについて、以降のセクションで分析します。

5.3.1.1 Server.java

この例題で使用される Server.java クラスは、簡単なセキュリティを使用した RMI コネクタで使用されるクラスに非常に似ています。ただし、詳細なセキュリティの例題では、環境マップにマップされる access.properties ファイルがありません。それ以外は、両クラスは同一です。

5.3.1.2 java.policy

java.policy ファイルは、次の権限を付与します。

  • server コードベースのすべての権限。コネクタサーバはコネクタを作成し、リモートユーザの呼び出しで要求される操作を実行できる
  • mbeans コードベースに対する MBeanTrustPermission。信頼された MBeans を MBean サーバに登録することができる
  • JMXPrincipal で表されるユーザ、username に対する、各種の MBean 操作および MBean サーバ操作を実行する権限

5.3.1.3 SimpleStandardMBean.java

SimpleStandardMBean クラスは、前出の例題で使用されたのと同じ簡単な MBean インタフェースを定義します。

5.3.1.4 SimpleStandard.java

SimpleStandard クラスは、前出の例題で使用されたのと同じ簡単な MBean を定義します。

5.3.1.5 ClientListener.java

ClientListener クラスは、前出の例題で使用されたのと同じ簡単な通知リスナを定義します。

5.3.1.6 Client.java

Client.java クラスは、簡単なセキュリティを使用した RMI コネクタの例題で使用されるクラスとまったく同じです。

5.3.2 詳細なセキュリティを使用した RMI コネクタの例題の実行

詳細なセキュリティを使用した RMI コネクタの例題を実行するには、次の手順を実行します。

  1. 例題のクラスをコンパイルします。
  2. $ javac  mbeans/SimpleStandard.java \ 
      mbeans/SimpleStandardMBean.java \ 
      server/Server.java \ 
      client/Client.java \ 
      client/ClientListener.java 
     
    
  3. ローカルホストのポート 9999 で RMI レジストリを起動します。
  4. $ export CLASSPATH=server ; rmiregistry 9999 &

  5. Server を起動します。
  6. $ 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 コネクタの作成の確認が表示されます。

  7. Client を起動します。
  8.  
    $ java -classpath client:server:mbeans \ 
         -Djavax.net.ssl.trustStore=config/truststore \ 
         -Djavax.net.ssl.trustStorePassword=trustword \ 
         Client 
     
    

    コネクタクライアントの作成、RMI サーバへの接続、各種の MBean 操作、および接続の終了の確認が表示されます。

 


目次 | 前の項目 | 次の項目 Java Management Extensions (JMX) テクノロジのチュートリアル
Java Management Extensions (JMX), Java 2 Platform Standard Edition 5.0